diff options
author | Yuqian Li <liyuqian@google.com> | 2018-02-12 14:47:34 +0800 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-02-12 07:42:08 +0000 |
commit | 56a4a099e707b2d556f4e39605b72fe8b8cde6f8 (patch) | |
tree | 6c635b0f786f1d96f2a0c132180f13368dfae7f6 /src/core/SkDraw.cpp | |
parent | a76f6161f1c2640302bb5fb1371b2ac14cf5c6d7 (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.cpp | 54 |
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 { |