aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Yuqian Li <liyuqian@google.com>2018-04-13 14:11:30 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-04-16 19:01:20 +0000
commit575c21bf74767d89b54fefb4a6697cb295d4eb95 (patch)
tree168c2366a2bfc20c84a26dd6b474d8dceee2a173
parent94bb0722b238ac24e45863462d943b7b3d82cdb0 (diff)
Let SkCoverageDeltaList store width and use it during blitting
Otherwise, out/Debug/viewer -m complexclip_bw_invert may crash using the threaded backend because the clip in the initFn may be wider than the clip in the drawFn. Bug: skia: Change-Id: I3b3ddc9a912fcc155bd30a6bc1f87e24739d1ca6 Reviewed-on: https://skia-review.googlesource.com/121327 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Yuqian Li <liyuqian@google.com>
-rw-r--r--src/core/SkBlitter.cpp9
-rw-r--r--src/core/SkCoverageDelta.cpp8
-rw-r--r--src/core/SkCoverageDelta.h13
-rw-r--r--src/core/SkScan_DAAPath.cpp2
4 files changed, 22 insertions, 10 deletions
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index df67ffb63a..572150a173 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -108,7 +108,16 @@ void SkBlitter::blitCoverageDeltas(SkCoverageDeltaList* deltas, const SkIRect& c
// This is such an important optimization that will bring ~2x speedup for benches like
// path_fill_small_long_line and path_stroke_small_sawtooth.
if (canUseMask && !deltas->sorted(y) && deltas->count(y) << 3 >= clip.width()) {
+#ifdef SK_SUPPORT_LEGACY_THREADED_DAA_BUGS
SkIRect rowIR = SkIRect::MakeLTRB(clip.fLeft, y, clip.fRight, y + 1);
+#else
+ // Note that deltas->left()/right() may be different than clip.fLeft/fRight because in
+ // the threaded backend, deltas are generated in the initFn with full clip, while
+ // blitCoverageDeltas is called in drawFn with a subclip. For inverse fill, the clip
+ // might be wider than deltas' bounds (which is clippedIR).
+ SkIRect rowIR = SkIRect::MakeLTRB(SkTMin(clip.fLeft, deltas->left()), y,
+ SkTMax(clip.fRight, deltas->right()), y + 1);
+#endif
SkSTArenaAlloc<SkCoverageDeltaMask::MAX_SIZE> alloc;
SkCoverageDeltaMask mask(&alloc, rowIR);
for(int i = 0; i < deltas->count(y); ++i) {
diff --git a/src/core/SkCoverageDelta.cpp b/src/core/SkCoverageDelta.cpp
index defdcf2b7b..8ead98de09 100644
--- a/src/core/SkCoverageDelta.cpp
+++ b/src/core/SkCoverageDelta.cpp
@@ -7,12 +7,14 @@
#include "SkCoverageDelta.h"
-SkCoverageDeltaList::SkCoverageDeltaList(SkArenaAlloc* alloc, int top, int bottom, bool forceRLE) {
+SkCoverageDeltaList::SkCoverageDeltaList(SkArenaAlloc* alloc, const SkIRect& bounds, bool forceRLE) {
fAlloc = alloc;
- fTop = top;
- fBottom = bottom;
+ fBounds = bounds;
fForceRLE = forceRLE;
+ int top = bounds.fTop;
+ int bottom = bounds.fBottom;
+
// Init the anti-rect to be empty
fAntiRect.fY = bottom;
fAntiRect.fHeight = 0;
diff --git a/src/core/SkCoverageDelta.h b/src/core/SkCoverageDelta.h
index 62dee61043..9a7a41d5ac 100644
--- a/src/core/SkCoverageDelta.h
+++ b/src/core/SkCoverageDelta.h
@@ -48,10 +48,12 @@ public:
static constexpr int INIT_ROW_SIZE = 32;
#endif
- SkCoverageDeltaList(SkArenaAlloc* alloc, int top, int bottom, bool forceRLE);
+ SkCoverageDeltaList(SkArenaAlloc* alloc, const SkIRect& bounds, bool forceRLE);
- int top() const { return fTop; }
- int bottom() const { return fBottom; }
+ int top() const { return fBounds.fTop; }
+ int bottom() const { return fBounds.fBottom; }
+ int left() const { return fBounds.fLeft; }
+ int right() const { return fBounds.fRight; }
bool forceRLE() const { return fForceRLE; }
int count(int y) const { this->checkY(y); return fCounts[y]; }
bool sorted(int y) const { this->checkY(y); return fSorted[y]; }
@@ -84,12 +86,11 @@ private:
bool* fSorted;
int* fCounts;
int* fMaxCounts;
- int fTop;
- int fBottom;
+ SkIRect fBounds;
SkAntiRect fAntiRect;
bool fForceRLE;
- void checkY(int y) const { SkASSERT(y >= fTop && y < fBottom); }
+ void checkY(int y) const { SkASSERT(y >= fBounds.fTop && y < fBounds.fBottom); }
SK_ALWAYS_INLINE void push_back(int y, const SkCoverageDelta& delta) {
this->checkY(y);
diff --git a/src/core/SkScan_DAAPath.cpp b/src/core/SkScan_DAAPath.cpp
index a0d656f6b9..329e69e120 100644
--- a/src/core/SkScan_DAAPath.cpp
+++ b/src/core/SkScan_DAAPath.cpp
@@ -367,7 +367,7 @@ void SkScan::DAAFillPath(const SkPath& path, SkBlitter* blitter, const SkIRect&
} else {
record->fType = SkDAARecord::Type::kList;
SkCoverageDeltaList* deltaList = alloc->make<SkCoverageDeltaList>(
- alloc, clippedIR.fTop, clippedIR.fBottom, forceRLE);
+ alloc, clippedIR, forceRLE);
gen_alpha_deltas(path, clippedIR, clipBounds, *deltaList, blitter, skipRect,
containedInClip);
record->fList = deltaList;