aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkDraw.cpp
diff options
context:
space:
mode:
authorGravatar Yuqian Li <liyuqian@google.com>2018-02-12 14:47:34 +0800
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-02-12 07:42:08 +0000
commit56a4a099e707b2d556f4e39605b72fe8b8cde6f8 (patch)
tree6c635b0f786f1d96f2a0c132180f13368dfae7f6 /src/core/SkDraw.cpp
parenta76f6161f1c2640302bb5fb1371b2ac14cf5c6d7 (diff)
Add init-once to threaded backend
For the simplicity of this CL, I haven't enabled DAA for init-once yet. The current init-once is only enabled for draw path, and it simply generates the dev path in the init-once phase. Bug: skia: Change-Id: Ie9a9ef9fc453acbdeb48b06b93d578c626961e3f Reviewed-on: https://skia-review.googlesource.com/87784 Commit-Queue: Yuqian Li <liyuqian@google.com> Reviewed-by: Herb Derby <herb@google.com>
Diffstat (limited to 'src/core/SkDraw.cpp')
-rw-r--r--src/core/SkDraw.cpp54
1 files changed, 42 insertions, 12 deletions
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index d2d2307046..478617f828 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -34,6 +34,7 @@
#include "SkStrokeRec.h"
#include "SkTemplates.h"
#include "SkTextMapStateProc.h"
+#include "SkThreadedBMPDevice.h"
#include "SkTLazy.h"
#include "SkUtils.h"
@@ -951,12 +952,18 @@ SkScalar SkDraw::ComputeResScaleForStroking(const SkMatrix& matrix) {
}
void SkDraw::drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawCoverage,
- SkBlitter* customBlitter, bool doFill) const {
+ SkBlitter* customBlitter, bool doFill, SkInitOnceData* iData) const {
SkBlitter* blitter = nullptr;
SkAutoBlitterChoose blitterStorage;
+ SkAutoBlitterChoose* blitterStoragePtr = &blitterStorage;
+ if (iData) {
+ // we're in the threaded init-once phase; the blitter has to be allocated in the thread
+ // allocator so it will remain valid later during the draw phase.
+ blitterStoragePtr = iData->fAlloc->make<SkAutoBlitterChoose>();
+ }
if (nullptr == customBlitter) {
- blitterStorage.choose(fDst, *fMatrix, paint, drawCoverage);
- blitter = blitterStorage.get();
+ blitterStoragePtr->choose(fDst, *fMatrix, paint, drawCoverage);
+ blitter = blitterStoragePtr->get();
} else {
blitter = customBlitter;
}
@@ -1009,12 +1016,31 @@ void SkDraw::drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawC
}
}
}
- proc(devPath, *fRC, blitter);
+
+ if (iData == nullptr) {
+ proc(devPath, *fRC, blitter); // proceed directly if we're not in threaded init-once
+ } else if (true || !doFill || !paint.isAntiAlias()) {
+ // TODO remove true in the if statement above so we can proceed to DAA.
+
+ // We're in threaded init-once but we can't use DAA. Hence we'll stop here and hand all the
+ // remaining work to draw phase. This is a simple example of how to add init-once to
+ // existing drawXXX commands: simply send in SkInitOnceData, do as much init work as
+ // possible, and finally wrap the remaining work into iData->fElement->fDrawFn.
+ iData->fElement->setDrawFn([proc, devPath, blitter](SkArenaAlloc* alloc,
+ const SkThreadedBMPDevice::DrawState& ds, const SkIRect& tileBounds) {
+ SkThreadedBMPDevice::TileDraw tileDraw(ds, tileBounds);
+ proc(devPath, *tileDraw.fRC, blitter);
+ });
+ } else {
+ // We can use DAA to do scan conversion in the init-once phase.
+ // TODO To be implemented
+ }
}
void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
const SkMatrix* prePathMatrix, bool pathIsMutable,
- bool drawCoverage, SkBlitter* customBlitter) const {
+ bool drawCoverage, SkBlitter* customBlitter,
+ SkInitOnceData* iData) const {
SkDEBUGCODE(this->validate();)
// nothing to draw
@@ -1024,17 +1050,21 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
SkPath* pathPtr = (SkPath*)&origSrcPath;
bool doFill = true;
- SkPath tmpPath;
+ SkPath tmpPathStorage;
+ SkPath* tmpPath = &tmpPathStorage;
SkMatrix tmpMatrix;
const SkMatrix* matrix = fMatrix;
- tmpPath.setIsVolatile(true);
+ if (iData) {
+ tmpPath = iData->fAlloc->make<SkPath>();
+ }
+ tmpPath->setIsVolatile(true);
if (prePathMatrix) {
if (origPaint.getPathEffect() || origPaint.getStyle() != SkPaint::kFill_Style) {
SkPath* result = pathPtr;
if (!pathIsMutable) {
- result = &tmpPath;
+ result = tmpPath;
pathIsMutable = true;
}
pathPtr->transform(*prePathMatrix, result);
@@ -1079,18 +1109,18 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
if (this->computeConservativeLocalClipBounds(&cullRect)) {
cullRectPtr = &cullRect;
}
- doFill = paint->getFillPath(*pathPtr, &tmpPath, cullRectPtr,
+ doFill = paint->getFillPath(*pathPtr, tmpPath, cullRectPtr,
ComputeResScaleForStroking(*fMatrix));
- pathPtr = &tmpPath;
+ pathPtr = tmpPath;
}
// avoid possibly allocating a new path in transform if we can
- SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath;
+ SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath;
// transform the path into device space
pathPtr->transform(*matrix, devPathPtr);
- this->drawDevPath(*devPathPtr, *paint, drawCoverage, customBlitter, doFill);
+ this->drawDevPath(*devPathPtr, *paint, drawCoverage, customBlitter, doFill, iData);
}
void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, const SkPaint& paint) const {