Simplify scan converter's args
All scan converters need an SkIRect clipBounds and a bool
containedInClip. However, we previously sent in an SkRegion
and a SkIRect*, and convert them into clipBounds and
containedInClip all over the places. This CL converts them
only once inside do_fill_path and change all args to SkIRect
and bool.
Bug: skia:
Change-Id: I05f1d76322942d8817860fd33991f7f7ce918e7c
Reviewed-on: https://skia-review.googlesource.com/52741
Reviewed-by: Cary Clark <caryclark@google.com>
Commit-Queue: Yuqian Li <liyuqian@google.com>
diff --git a/src/core/SkScanPriv.h b/src/core/SkScanPriv.h
index 8883be0..03b09ce 100644
--- a/src/core/SkScanPriv.h
+++ b/src/core/SkScanPriv.h
@@ -135,7 +135,7 @@
}
using FillPathFunc = std::function<void(const SkPath& path, SkBlitter* blitter, bool isInverse,
- const SkIRect& ir, const SkRegion* clipRgn, const SkIRect* clipRect, bool forceRLE)>;
+ const SkIRect& ir, const SkIRect& clipBounds, bool containedInClip, bool forceRLE)>;
static inline void do_fill_path(const SkPath& path, const SkRegion& origClip, SkBlitter* blitter,
bool forceRLE, const int SHIFT, FillPathFunc fillPathFunc) {
@@ -216,7 +216,7 @@
SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
- fillPathFunc(path, blitter, isInverse, ir, clipRgn, clipRect, forceRLE);
+ fillPathFunc(path, blitter, isInverse, ir, clipRgn->getBounds(), clipRect == nullptr, forceRLE);
if (isInverse) {
sk_blit_below(blitter, ir, *clipRgn);
diff --git a/src/core/SkScan_AAAPath.cpp b/src/core/SkScan_AAAPath.cpp
index b6377ed..d62b151 100644
--- a/src/core/SkScan_AAAPath.cpp
+++ b/src/core/SkScan_AAAPath.cpp
@@ -134,7 +134,7 @@
// We need this mask blitter because it significantly accelerates small path filling.
class MaskAdditiveBlitter : public AdditiveBlitter {
public:
- MaskAdditiveBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip,
+ MaskAdditiveBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkIRect& clipBounds,
bool isInverse);
~MaskAdditiveBlitter() override {
fRealBlitter->blitMask(fMask, fClipRect);
@@ -202,7 +202,7 @@
};
MaskAdditiveBlitter::MaskAdditiveBlitter(
- SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip, bool isInverse) {
+ SkBlitter* realBlitter, const SkIRect& ir, const SkIRect& clipBounds, bool isInverse) {
SkASSERT(canHandleRect(ir));
SkASSERT(!isInverse);
@@ -217,7 +217,7 @@
fRow = nullptr;
fClipRect = ir;
- if (!fClipRect.intersect(clip.getBounds())) {
+ if (!fClipRect.intersect(clipBounds)) {
SkASSERT(0);
fClipRect.setEmpty();
}
@@ -276,7 +276,7 @@
class RunBasedAdditiveBlitter : public AdditiveBlitter {
public:
- RunBasedAdditiveBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip,
+ RunBasedAdditiveBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkIRect& clipBounds,
bool isInverse);
~RunBasedAdditiveBlitter() override;
@@ -372,16 +372,16 @@
};
RunBasedAdditiveBlitter::RunBasedAdditiveBlitter(
- SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip, bool isInverse) {
+ SkBlitter* realBlitter, const SkIRect& ir, const SkIRect& clipBounds, bool isInverse) {
fRealBlitter = realBlitter;
SkIRect sectBounds;
if (isInverse) {
// We use the clip bounds instead of the ir, since we may be asked to
//draw outside of the rect when we're a inverse filltype
- sectBounds = clip.getBounds();
+ sectBounds = clipBounds;
} else {
- if (!sectBounds.intersect(ir, clip.getBounds())) {
+ if (!sectBounds.intersect(ir, clipBounds)) {
sectBounds.setEmpty();
}
}
@@ -471,8 +471,8 @@
// In those cases, we can easily accumulate alpha greater than 0xFF.
class SafeRLEAdditiveBlitter : public RunBasedAdditiveBlitter {
public:
- SafeRLEAdditiveBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip,
- bool isInverse) : RunBasedAdditiveBlitter(realBlitter, ir, clip, isInverse) {}
+ SafeRLEAdditiveBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkIRect& clipBounds,
+ bool isInverse) : RunBasedAdditiveBlitter(realBlitter, ir, clipBounds, isInverse) {}
void blitAntiH(int x, int y, const SkAlpha antialias[], int len) override;
void blitAntiH(int x, int y, const SkAlpha alpha) override;
@@ -1675,9 +1675,7 @@
void SkScan::AAAFillPath(const SkPath& path, const SkRegion& origClip, SkBlitter* blitter,
bool forceRLE) {
FillPathFunc fillPathFunc = [](const SkPath& path, SkBlitter* blitter, bool isInverse,
- const SkIRect& ir, const SkRegion* clipRgn, const SkIRect* clipRect, bool forceRLE){
- const SkIRect& clipBounds = clipRgn->getBounds();
-
+ const SkIRect& ir, const SkIRect& clipBounds, bool containedInClip, bool forceRLE){
// The mask blitter (where we store intermediate alpha values directly in a mask, and then
// call the real blitter once in the end to blit the whole mask) is faster than the RLE
// blitter when the blit region is small enough (i.e., canHandleRect(ir)).
@@ -1687,16 +1685,16 @@
// much overhead. Hence we'll use blitFatAntiRect to avoid the mask and its overhead.
if (MaskAdditiveBlitter::canHandleRect(ir) && !isInverse && !forceRLE) {
#ifdef SK_SUPPORT_LEGACY_SMALLRECT_AA
- MaskAdditiveBlitter additiveBlitter(blitter, ir, *clipRgn, isInverse);
+ MaskAdditiveBlitter additiveBlitter(blitter, ir, clipBounds, isInverse);
aaa_fill_path(path, clipBounds, &additiveBlitter, ir.fTop, ir.fBottom,
- clipRect == nullptr, true, forceRLE);
+ containedInClip, true, forceRLE);
#else
// blitFatAntiRect is slower than the normal AAA flow without MaskAdditiveBlitter.
// Hence only tryBlitFatAntiRect when MaskAdditiveBlitter would have been used.
if (!TryBlitFatAntiRect(blitter, path, clipBounds)) {
- MaskAdditiveBlitter additiveBlitter(blitter, ir, *clipRgn, isInverse);
+ MaskAdditiveBlitter additiveBlitter(blitter, ir, clipBounds, isInverse);
aaa_fill_path(path, clipBounds, &additiveBlitter, ir.fTop, ir.fBottom,
- clipRect == nullptr, true, forceRLE);
+ containedInClip, true, forceRLE);
}
#endif
} else if (!isInverse && path.isConvex()) {
@@ -1704,16 +1702,16 @@
// aaa_walk_convex_edges won't generate alphas above 255. Hence we don't need
// SafeRLEAdditiveBlitter (which is slow due to clamping). The basic RLE blitter
// RunBasedAdditiveBlitter would suffice.
- RunBasedAdditiveBlitter additiveBlitter(blitter, ir, *clipRgn, isInverse);
+ RunBasedAdditiveBlitter additiveBlitter(blitter, ir, clipBounds, isInverse);
aaa_fill_path(path, clipBounds, &additiveBlitter, ir.fTop, ir.fBottom,
- clipRect == nullptr, false, forceRLE);
+ containedInClip, false, forceRLE);
} else {
// If the filling area might not be convex, the more involved aaa_walk_edges would
// be called and we have to clamp the alpha downto 255. The SafeRLEAdditiveBlitter
// does that at a cost of performance.
- SafeRLEAdditiveBlitter additiveBlitter(blitter, ir, *clipRgn, isInverse);
+ SafeRLEAdditiveBlitter additiveBlitter(blitter, ir, clipBounds, isInverse);
aaa_fill_path(path, clipBounds, &additiveBlitter, ir.fTop, ir.fBottom,
- clipRect == nullptr, false, forceRLE);
+ containedInClip, false, forceRLE);
}
};
diff --git a/src/core/SkScan_AntiPath.cpp b/src/core/SkScan_AntiPath.cpp
index 10b8891..86b4355 100644
--- a/src/core/SkScan_AntiPath.cpp
+++ b/src/core/SkScan_AntiPath.cpp
@@ -39,7 +39,7 @@
class BaseSuperBlitter : public SkBlitter {
public:
BaseSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
- const SkRegion& clip, bool isInverse);
+ const SkIRect& clipBounds, bool isInverse);
/// Must be explicitly defined on subclasses.
virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
@@ -71,17 +71,17 @@
SkIRect fSectBounds;
};
-BaseSuperBlitter::BaseSuperBlitter(SkBlitter* realBlit, const SkIRect& ir, const SkRegion& clip,
- bool isInverse) {
+BaseSuperBlitter::BaseSuperBlitter(SkBlitter* realBlit, const SkIRect& ir,
+ const SkIRect& clipBounds, bool isInverse) {
fRealBlitter = realBlit;
SkIRect sectBounds;
if (isInverse) {
// We use the clip bounds instead of the ir, since we may be asked to
//draw outside of the rect when we're a inverse filltype
- sectBounds = clip.getBounds();
+ sectBounds = clipBounds;
} else {
- if (!sectBounds.intersect(ir, clip.getBounds())) {
+ if (!sectBounds.intersect(ir, clipBounds)) {
sectBounds.setEmpty();
}
}
@@ -102,7 +102,8 @@
/// Run-length-encoded supersampling antialiased blitter.
class SuperBlitter : public BaseSuperBlitter {
public:
- SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip, bool isInverse);
+ SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkIRect& clipBounds,
+ bool isInverse);
~SuperBlitter() override {
this->flush();
@@ -147,9 +148,9 @@
int fOffsetX;
};
-SuperBlitter::SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip,
+SuperBlitter::SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkIRect& clipBounds,
bool isInverse)
- : BaseSuperBlitter(realBlitter, ir, clip, isInverse)
+ : BaseSuperBlitter(realBlitter, ir, clipBounds, isInverse)
{
fRunsToBuffer = realBlitter->requestRowsPreserved();
fRunsBuffer = realBlitter->allocBlitMemory(fRunsToBuffer * this->getRunsSz());
@@ -393,7 +394,7 @@
/// Masked supersampling antialiased blitter.
class MaskSuperBlitter : public BaseSuperBlitter {
public:
- MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion&, bool isInverse);
+ MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkIRect&, bool isInverse);
~MaskSuperBlitter() override {
fRealBlitter->blitMask(fMask, fClipRect);
}
@@ -431,9 +432,9 @@
uint32_t fStorage[(kMAX_STORAGE >> 2) + 1];
};
-MaskSuperBlitter::MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip,
- bool isInverse)
- : BaseSuperBlitter(realBlitter, ir, clip, isInverse)
+MaskSuperBlitter::MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
+ const SkIRect& clipBounds, bool isInverse)
+ : BaseSuperBlitter(realBlitter, ir, clipBounds, isInverse)
{
SkASSERT(CanHandleRect(ir));
SkASSERT(!isInverse);
@@ -444,7 +445,7 @@
fMask.fFormat = SkMask::kA8_Format;
fClipRect = ir;
- if (!fClipRect.intersect(clip.getBounds())) {
+ if (!fClipRect.intersect(clipBounds)) {
SkASSERT(0);
fClipRect.setEmpty();
}
@@ -627,27 +628,16 @@
#endif
FillPathFunc fillPathFunc = [](const SkPath& path, SkBlitter* blitter, bool isInverse,
- const SkIRect& ir, const SkRegion* clipRgn, const SkIRect* clipRect, bool forceRLE){
- SkIRect superRect, *superClipRect = nullptr;
- if (clipRect) {
- superRect.set(SkLeftShift(clipRect->fLeft, SHIFT),
- SkLeftShift(clipRect->fTop, SHIFT),
- SkLeftShift(clipRect->fRight, SHIFT),
- SkLeftShift(clipRect->fBottom, SHIFT));
- superClipRect = &superRect;
- }
-
+ const SkIRect& ir, const SkIRect& clipBounds, bool containedInClip, bool forceRLE){
// MaskSuperBlitter can't handle drawing outside of ir, so we can't use it
// if we're an inverse filltype
if (!isInverse && MaskSuperBlitter::CanHandleRect(ir) && !forceRLE) {
- MaskSuperBlitter superBlit(blitter, ir, *clipRgn, isInverse);
+ MaskSuperBlitter superBlit(blitter, ir, clipBounds, isInverse);
SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
- sk_fill_path(path, clipRgn->getBounds(), &superBlit, ir.fTop, ir.fBottom, SHIFT,
- superClipRect == nullptr);
+ sk_fill_path(path, clipBounds, &superBlit, ir.fTop, ir.fBottom, SHIFT, containedInClip);
} else {
- SuperBlitter superBlit(blitter, ir, *clipRgn, isInverse);
- sk_fill_path(path, clipRgn->getBounds(), &superBlit, ir.fTop, ir.fBottom, SHIFT,
- superClipRect == nullptr);
+ SuperBlitter superBlit(blitter, ir, clipBounds, isInverse);
+ sk_fill_path(path, clipBounds, &superBlit, ir.fTop, ir.fBottom, SHIFT, containedInClip);
}
};
diff --git a/src/core/SkScan_DAAPath.cpp b/src/core/SkScan_DAAPath.cpp
index a9195eb..da4a640 100644
--- a/src/core/SkScan_DAAPath.cpp
+++ b/src/core/SkScan_DAAPath.cpp
@@ -150,13 +150,12 @@
};
template<class Deltas> static SK_ALWAYS_INLINE
-void gen_alpha_deltas(const SkPath& path, const SkRegion& clipRgn, Deltas& result,
+void gen_alpha_deltas(const SkPath& path, const SkIRect& clipBounds, Deltas& result,
SkBlitter* blitter, bool skipRect, bool pathContainedInClip) {
// 1. Build edges
SkEdgeBuilder builder;
SkIRect ir = path.getBounds().roundOut();
- const SkIRect& clipRect = clipRgn.getBounds();
- int count = builder.build_edges(path, &clipRect, 0, pathContainedInClip,
+ int count = builder.build_edges(path, &clipBounds, 0, pathContainedInClip,
SkEdgeBuilder::kBezier);
if (count == 0) {
return;
@@ -266,7 +265,7 @@
if (lowerCeil <= upperFloor + SK_Fixed1) { // only one row is affected by the currE
SkFixed rowHeight = currE->fLowerY - currE->fUpperY;
SkFixed nextX = currE->fX + SkFixedMul(currE->fDX, rowHeight);
- if (iy >= clipRect.fTop && iy < clipRect.fBottom) {
+ if (iy >= clipBounds.fTop && iy < clipBounds.fBottom) {
add_coverage_delta_segment<true>(iy, rowHeight, currE, nextX, &result);
}
continue;
@@ -305,7 +304,8 @@
}
// last partial row
- if (SkIntToFixed(iy) < currE->fLowerY && iy >= clipRect.fTop && iy < clipRect.fBottom) {
+ if (SkIntToFixed(iy) < currE->fLowerY &&
+ iy >= clipBounds.fTop && iy < clipBounds.fBottom) {
rowHeight = currE->fLowerY - SkIntToFixed(iy);
nextX = currE->fX + SkFixedMul(currE->fDX, rowHeight);
add_coverage_delta_segment<true>(iy, rowHeight, currE, nextX, &result);
@@ -319,12 +319,11 @@
bool forceRLE) {
FillPathFunc fillPathFunc = [](const SkPath& path, SkBlitter* blitter, bool isInverse,
- const SkIRect& ir, const SkRegion* clipRgn, const SkIRect* clipRect, bool forceRLE){
+ const SkIRect& ir, const SkIRect& clipBounds, bool containedInClip, bool forceRLE){
bool isEvenOdd = path.getFillType() & 1;
bool isConvex = path.isConvex();
bool skipRect = isConvex && !isInverse;
- const SkIRect& clipBounds = clipRgn->getBounds();
SkIRect clippedIR = ir;
clippedIR.intersect(clipBounds);
@@ -345,12 +344,12 @@
// Everything before can be done out of order in the threaded backend.
if (!forceRLE && !isInverse && SkCoverageDeltaMask::Suitable(clippedIR)) {
SkCoverageDeltaMask deltaMask(&alloc, clippedIR);
- gen_alpha_deltas(path, *clipRgn, deltaMask, blitter, skipRect, clipRect == nullptr);
+ gen_alpha_deltas(path, clipBounds, deltaMask, blitter, skipRect, containedInClip);
deltaMask.convertCoverageToAlpha(isEvenOdd, isInverse, isConvex);
blitter->blitMask(deltaMask.prepareSkMask(), clippedIR);
} else {
SkCoverageDeltaList deltaList(&alloc, clippedIR.fTop, clippedIR.fBottom, forceRLE);
- gen_alpha_deltas(path, *clipRgn, deltaList, blitter, skipRect, clipRect == nullptr);
+ gen_alpha_deltas(path, clipBounds, deltaList, blitter, skipRect, containedInClip);
blitter->blitCoverageDeltas(&deltaList, clipBounds, isEvenOdd, isInverse, isConvex);
}
};