aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkDraw.cpp
diff options
context:
space:
mode:
authorGravatar Yuqian Li <liyuqian@google.com>2018-04-11 17:09:12 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-04-16 18:53:10 +0000
commit94bb0722b238ac24e45863462d943b7b3d82cdb0 (patch)
tree2432ba485b91aa4a3f80f5e9385e5e7b398c78f1 /src/core/SkDraw.cpp
parent6b7b1dcc863ae8877f33532df05c921e12c67675 (diff)
SkBlitter is not thread safe; make one for each thread.
Otherwise, GM fancy_gradients would be drawn incorrectly and TSAN will issue alerts as SkARGB32_Shader_Blitter has its own memory that may be written during blitting. As we make one blitter for each thread, we also don't need to send in a thread-alloc for blitCoverageDeltas Bug: skia: Change-Id: Ie4ee0886b88c797ab57c65674b0b7527501b164f Reviewed-on: https://skia-review.googlesource.com/120641 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Yuqian Li <liyuqian@google.com>
Diffstat (limited to 'src/core/SkDraw.cpp')
-rw-r--r--src/core/SkDraw.cpp22
1 files changed, 11 insertions, 11 deletions
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 5c5247c4cc..f205080c25 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -953,15 +953,8 @@ void SkDraw::drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawC
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) {
- blitterStoragePtr->choose(fDst, *fMatrix, paint, drawCoverage);
- blitter = blitterStoragePtr->get();
+ blitter = blitterStorage.choose(fDst, *fMatrix, paint, drawCoverage);
} else {
blitter = customBlitter;
}
@@ -1025,20 +1018,27 @@ void SkDraw::drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawC
// 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,
+ SkASSERT(customBlitter == nullptr);
+ iData->fElement->setDrawFn([proc, devPath, paint, drawCoverage](SkArenaAlloc* alloc,
const SkThreadedBMPDevice::DrawState& ds, const SkIRect& tileBounds) {
SkThreadedBMPDevice::TileDraw tileDraw(ds, tileBounds);
- proc(devPath, *tileDraw.fRC, blitter);
+ SkAutoBlitterChoose blitterStorage;
+ proc(devPath, *tileDraw.fRC, blitterStorage.choose(tileDraw.fDst, *tileDraw.fMatrix,
+ paint, drawCoverage));
});
} else {
// We can use DAA to do scan conversion in the init-once phase.
SkDAARecord* record = iData->fAlloc->make<SkDAARecord>(iData->fAlloc);
SkNullBlitter nullBlitter; // We don't want to blit anything during the init phase
SkScan::AntiFillPath(devPath, *fRC, &nullBlitter, record);
- iData->fElement->setDrawFn([record, devPath, blitter](SkArenaAlloc* alloc,
+ SkASSERT(customBlitter == nullptr);
+ iData->fElement->setDrawFn([record, devPath, paint, drawCoverage](SkArenaAlloc* alloc,
const SkThreadedBMPDevice::DrawState& ds, const SkIRect& tileBounds) {
SkASSERT(record->fType != SkDAARecord::Type::kToBeComputed);
SkThreadedBMPDevice::TileDraw tileDraw(ds, tileBounds);
+ SkAutoBlitterChoose blitterStorage;
+ SkBlitter* blitter = blitterStorage.choose(tileDraw.fDst, *tileDraw.fMatrix,
+ paint, drawCoverage);
SkScan::AntiFillPath(devPath, *tileDraw.fRC, blitter, record);
});
}