simplify canvas after looper's demise
Bug: skia:4783
Change-Id: Ib5bf3524033b0064f4248552b5946306dab18572
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/230744
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 4d0c716..02a29ba 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -310,10 +310,6 @@
/////////////////////////////////////////////////////////////////////////////
-static SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) {
- return lazy->isValid() ? lazy->get() : lazy->set(orig);
-}
-
/**
* If the paint has an imagefilter, but it can be simplified to just a colorfilter, return that
* colorfilter, else return nullptr.
@@ -363,22 +359,22 @@
}
}
-class AutoDrawLooper {
+class AutoLayerForImageFilter {
public:
// "rawBounds" is the original bounds of the primitive about to be drawn, unmodified by the
// paint. It's used to determine the size of the offscreen layer for filters.
// If null, the clip will be used instead.
- AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint, bool skipLayerForImageFilter = false,
- const SkRect* rawBounds = nullptr) : fOrigPaint(paint) {
+ AutoLayerForImageFilter(SkCanvas* canvas, const SkPaint& origPaint,
+ bool skipLayerForImageFilter = false,
+ const SkRect* rawBounds = nullptr) {
fCanvas = canvas;
- fPaint = &fOrigPaint;
+ fPaint = &origPaint;
fSaveCount = canvas->getSaveCount();
fTempLayerForImageFilter = false;
- fDone = false;
- auto simplifiedCF = image_to_color_filter(fOrigPaint);
- if (simplifiedCF) {
- SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint);
+ if (auto simplifiedCF = image_to_color_filter(origPaint)) {
+ SkASSERT(!fLazyPaint.isValid());
+ SkPaint* paint = fLazyPaint.set(origPaint);
paint->setColorFilter(std::move(simplifiedCF));
paint->setImageFilter(nullptr);
fPaint = paint;
@@ -400,26 +396,30 @@
* src pixels of the primitive). It returns a new "filtered" buffer, which we
* draw onto the previous layer using the xfermode from the original paint.
*/
- SkPaint tmp;
- tmp.setImageFilter(fPaint->refImageFilter());
- tmp.setBlendMode(fPaint->getBlendMode());
+
+ SkPaint restorePaint;
+ restorePaint.setImageFilter(fPaint->refImageFilter());
+ restorePaint.setBlendMode(fPaint->getBlendMode());
+
SkRect storage;
if (rawBounds) {
// Make rawBounds include all paint outsets except for those due to image filters.
rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *rawBounds, &storage);
}
- (void)canvas->internalSaveLayer(SkCanvas::SaveLayerRec(rawBounds, &tmp),
+ (void)canvas->internalSaveLayer(SkCanvas::SaveLayerRec(rawBounds, &restorePaint),
SkCanvas::kFullLayer_SaveLayerStrategy);
fTempLayerForImageFilter = true;
- // we remove the imagefilter/xfermode inside doNext()
- }
- {
- fIsSimple = !fTempLayerForImageFilter;
+ // Remove the restorePaint fields from our "working" paint
+ SkASSERT(!fLazyPaint.isValid());
+ SkPaint* paint = fLazyPaint.set(origPaint);
+ paint->setImageFilter(nullptr);
+ paint->setBlendMode(SkBlendMode::kSrcOver);
+ fPaint = paint;
}
}
- ~AutoDrawLooper() {
+ ~AutoLayerForImageFilter() {
if (fTempLayerForImageFilter) {
fCanvas->internalRestore();
}
@@ -431,79 +431,38 @@
return *fPaint;
}
- bool next() {
- if (fDone) {
- return false;
- } else if (fIsSimple) {
- fDone = true;
- return !fPaint->nothingToDraw();
- } else {
- return this->doNext();
- }
- }
-
private:
- SkLazyPaint fLazyPaintInit; // base paint storage in case we need to modify it
- SkLazyPaint fLazyPaintPerLooper; // per-draw-looper storage, so the looper can modify it
+ SkLazyPaint fLazyPaint; // base paint storage in case we need to modify it
SkCanvas* fCanvas;
- const SkPaint& fOrigPaint;
- const SkPaint* fPaint;
+ const SkPaint* fPaint; // points to either the original paint, or lazy (if we needed it)
int fSaveCount;
bool fTempLayerForImageFilter;
- bool fDone;
- bool fIsSimple;
-
- bool doNext();
};
-bool AutoDrawLooper::doNext() {
- fPaint = nullptr;
- SkASSERT(!fIsSimple);
- SkASSERT(fTempLayerForImageFilter);
-
- SkPaint* paint = fLazyPaintPerLooper.set(fLazyPaintInit.isValid() ?
- *fLazyPaintInit.get() : fOrigPaint);
-
- if (fTempLayerForImageFilter) {
- paint->setImageFilter(nullptr);
- paint->setBlendMode(SkBlendMode::kSrcOver);
- }
-
- fPaint = paint;
-
- // if we only came in here for the imagefilter, mark us as done
- fDone = true;
- return true;
-}
-
////////// macros to place around the internal draw calls //////////////////
-#define LOOPER_BEGIN_DRAWBITMAP(paint, skipLayerForFilter, bounds) \
+#define DRAW_BEGIN_DRAWBITMAP(paint, skipLayerForFilter, bounds) \
this->predrawNotify(); \
- AutoDrawLooper looper(this, paint, skipLayerForFilter, bounds); \
- while (looper.next()) { \
- SkDrawIter iter(this);
+ AutoLayerForImageFilter draw(this, paint, skipLayerForFilter, bounds); \
+ { SkDrawIter iter(this);
-#define LOOPER_BEGIN_DRAWDEVICE(paint) \
+#define DRAW_BEGIN_DRAWDEVICE(paint) \
this->predrawNotify(); \
- AutoDrawLooper looper(this, paint, true); \
- while (looper.next()) { \
- SkDrawIter iter(this);
+ AutoLayerForImageFilter draw(this, paint, true); \
+ { SkDrawIter iter(this);
-#define LOOPER_BEGIN(paint, bounds) \
+#define DRAW_BEGIN(paint, bounds) \
this->predrawNotify(); \
- AutoDrawLooper looper(this, paint, false, bounds); \
- while (looper.next()) { \
- SkDrawIter iter(this);
+ AutoLayerForImageFilter draw(this, paint, false, bounds); \
+ { SkDrawIter iter(this);
-#define LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, bounds, auxOpaque) \
+#define DRAW_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, bounds, auxOpaque) \
this->predrawNotify(bounds, &paint, auxOpaque); \
- AutoDrawLooper looper(this, paint, false, bounds); \
- while (looper.next()) { \
- SkDrawIter iter(this);
+ AutoLayerForImageFilter draw(this, paint, false, bounds); \
+ { SkDrawIter iter(this);
-#define LOOPER_END }
+#define DRAW_END }
////////////////////////////////////////////////////////////////////////////
@@ -1314,13 +1273,13 @@
paint = &tmp;
}
- LOOPER_BEGIN_DRAWDEVICE(*paint)
+ DRAW_BEGIN_DRAWDEVICE(*paint)
while (iter.next()) {
SkBaseDevice* dstDev = iter.fDevice;
check_drawdevice_colorspaces(dstDev->imageInfo().colorSpace(),
srcDev->imageInfo().colorSpace());
- paint = &looper.paint();
+ paint = &draw.paint();
SkImageFilter* filter = paint->getImageFilter();
SkIPoint pos = { x - iter.getX(), y - iter.getY() };
if (filter || clipImage) {
@@ -1336,7 +1295,7 @@
}
}
- LOOPER_END
+ DRAW_END
}
/////////////////////////////////////////////////////////////////////////////
@@ -2012,11 +1971,11 @@
SkPaint paint;
const SkRect& pathBounds = path.getBounds();
- LOOPER_BEGIN(paint, &pathBounds)
+ DRAW_BEGIN(paint, &pathBounds)
while (iter.next()) {
iter.fDevice->drawShadow(path, rec);
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::experimental_DrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4],
@@ -2050,13 +2009,13 @@
}
void SkCanvas::internalDrawPaint(const SkPaint& paint) {
- LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, nullptr, false)
+ DRAW_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, nullptr, false)
while (iter.next()) {
- iter.fDevice->drawPaint(looper.paint());
+ iter.fDevice->drawPaint(draw.paint());
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
@@ -2086,13 +2045,13 @@
SkASSERT(pts != nullptr);
- LOOPER_BEGIN(paint, bounds)
+ DRAW_BEGIN(paint, bounds)
while (iter.next()) {
- iter.fDevice->drawPoints(mode, count, pts, looper.paint());
+ iter.fDevice->drawPoints(mode, count, pts, draw.paint());
}
- LOOPER_END
+ DRAW_END
}
static bool needs_autodrawlooper(SkCanvas* canvas, const SkPaint& paint) {
@@ -2109,13 +2068,13 @@
}
if (needs_autodrawlooper(this, paint)) {
- LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, &r, false)
+ DRAW_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, &r, false)
while (iter.next()) {
- iter.fDevice->drawRect(r, looper.paint());
+ iter.fDevice->drawRect(r, draw.paint());
}
- LOOPER_END
+ DRAW_END
} else if (!paint.nothingToDraw()) {
this->predrawNotify(&r, &paint, false);
SkDrawIter iter(this);
@@ -2134,13 +2093,13 @@
}
}
- LOOPER_BEGIN(paint, ®ionRect)
+ DRAW_BEGIN(paint, ®ionRect)
while (iter.next()) {
- iter.fDevice->drawRegion(region, looper.paint());
+ iter.fDevice->drawRegion(region, draw.paint());
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::onDrawBehind(const SkPaint& paint) {
@@ -2159,7 +2118,7 @@
}
}
- LOOPER_BEGIN(paint, nullptr)
+ DRAW_BEGIN(paint, nullptr)
while (iter.next()) {
SkBaseDevice* dev = iter.fDevice;
@@ -2170,11 +2129,11 @@
// but we don't want that, so we undo that before calling in.
SkRegion rgn(bounds.makeOffset(dev->fOrigin.fX, dev->fOrigin.fY));
dev->clipRegion(rgn, SkClipOp::kIntersect);
- dev->drawPaint(looper.paint());
+ dev->drawPaint(draw.paint());
dev->restore(fMCRec->fMatrix);
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
@@ -2186,13 +2145,13 @@
}
}
- LOOPER_BEGIN(paint, &oval)
+ DRAW_BEGIN(paint, &oval)
while (iter.next()) {
- iter.fDevice->drawOval(oval, looper.paint());
+ iter.fDevice->drawOval(oval, draw.paint());
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::onDrawArc(const SkRect& oval, SkScalar startAngle,
@@ -2207,13 +2166,13 @@
}
}
- LOOPER_BEGIN(paint, &oval)
+ DRAW_BEGIN(paint, &oval)
while (iter.next()) {
- iter.fDevice->drawArc(oval, startAngle, sweepAngle, useCenter, looper.paint());
+ iter.fDevice->drawArc(oval, startAngle, sweepAngle, useCenter, draw.paint());
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
@@ -2234,13 +2193,13 @@
return;
}
- LOOPER_BEGIN(paint, &rrect.getBounds())
+ DRAW_BEGIN(paint, &rrect.getBounds())
while (iter.next()) {
- iter.fDevice->drawRRect(rrect, looper.paint());
+ iter.fDevice->drawRRect(rrect, draw.paint());
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
@@ -2251,13 +2210,13 @@
}
}
- LOOPER_BEGIN(paint, &outer.getBounds())
+ DRAW_BEGIN(paint, &outer.getBounds())
while (iter.next()) {
- iter.fDevice->drawDRRect(outer, inner, looper.paint());
+ iter.fDevice->drawDRRect(outer, inner, draw.paint());
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
@@ -2280,13 +2239,13 @@
}
}
- LOOPER_BEGIN(paint, &pathBounds)
+ DRAW_BEGIN(paint, &pathBounds)
while (iter.next()) {
- iter.fDevice->drawPath(path, looper.paint());
+ iter.fDevice->drawPath(path, draw.paint());
}
- LOOPER_END
+ DRAW_END
}
bool SkCanvas::canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint& paint) {
@@ -2353,10 +2312,10 @@
}
}
- LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds)
+ DRAW_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds)
while (iter.next()) {
- const SkPaint& pnt = looper.paint();
+ const SkPaint& pnt = draw.paint();
if (special) {
SkPoint pt;
iter.fDevice->ctm().mapXY(x, y, &pt);
@@ -2371,7 +2330,7 @@
}
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
@@ -2390,13 +2349,13 @@
}
paint = &realPaint;
- LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, &dst, image->isOpaque())
+ DRAW_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, &dst, image->isOpaque())
while (iter.next()) {
- iter.fDevice->drawImageRect(image, src, dst, looper.paint(), constraint);
+ iter.fDevice->drawImageRect(image, src, dst, draw.paint(), constraint);
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, const SkPaint* paint) {
@@ -2431,10 +2390,10 @@
}
}
- LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds)
+ DRAW_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds)
while (iter.next()) {
- const SkPaint& pnt = looper.paint();
+ const SkPaint& pnt = draw.paint();
if (special) {
SkPoint pt;
iter.fDevice->ctm().mapXY(x, y, &pt);
@@ -2449,7 +2408,7 @@
}
}
- LOOPER_END
+ DRAW_END
}
// this one is non-virtual, so it can be called safely by other canvas apis
@@ -2472,13 +2431,13 @@
paint = lazy.init();
}
- LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, &dst, bitmap.isOpaque())
+ DRAW_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, &dst, bitmap.isOpaque())
while (iter.next()) {
- iter.fDevice->drawBitmapRect(bitmap, src, dst, looper.paint(), constraint);
+ iter.fDevice->drawBitmapRect(bitmap, src, dst, draw.paint(), constraint);
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
@@ -2500,13 +2459,13 @@
}
paint = &realPaint;
- LOOPER_BEGIN(*paint, &dst)
+ DRAW_BEGIN(*paint, &dst)
while (iter.next()) {
- iter.fDevice->drawImageNine(image, center, dst, looper.paint());
+ iter.fDevice->drawImageNine(image, center, dst, draw.paint());
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
@@ -2523,13 +2482,13 @@
}
paint = &realPaint;
- LOOPER_BEGIN(*paint, &dst)
+ DRAW_BEGIN(*paint, &dst)
while (iter.next()) {
- iter.fDevice->drawBitmapNine(bitmap, center, dst, looper.paint());
+ iter.fDevice->drawBitmapNine(bitmap, center, dst, draw.paint());
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
@@ -2545,13 +2504,13 @@
}
paint = &realPaint;
- LOOPER_BEGIN(*paint, &dst)
+ DRAW_BEGIN(*paint, &dst)
while (iter.next()) {
- iter.fDevice->drawImageLattice(image, lattice, dst, looper.paint());
+ iter.fDevice->drawImageLattice(image, lattice, dst, draw.paint());
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice,
@@ -2567,13 +2526,13 @@
}
paint = &realPaint;
- LOOPER_BEGIN(*paint, &dst)
+ DRAW_BEGIN(*paint, &dst)
while (iter.next()) {
- iter.fDevice->drawBitmapLattice(bitmap, lattice, dst, looper.paint());
+ iter.fDevice->drawBitmapLattice(bitmap, lattice, dst, draw.paint());
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
@@ -2591,13 +2550,13 @@
// We cannot filter in the looper as we normally do, because the paint is
// incomplete at this point (text-related attributes are embedded within blob run paints).
- LOOPER_BEGIN(paint, bounds)
+ DRAW_BEGIN(paint, bounds)
while (iter.next()) {
- fScratchGlyphRunBuilder->drawTextBlob(looper.paint(), *blob, {x, y}, iter.fDevice);
+ fScratchGlyphRunBuilder->drawTextBlob(draw.paint(), *blob, {x, y}, iter.fDevice);
}
- LOOPER_END
+ DRAW_END
}
// These call the (virtual) onDraw... method
@@ -2620,14 +2579,14 @@
void SkCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkVertices::Bone bones[],
int boneCount, SkBlendMode bmode, const SkPaint& paint) {
- LOOPER_BEGIN(paint, nullptr)
+ DRAW_BEGIN(paint, nullptr)
while (iter.next()) {
// In the common case of one iteration we could std::move vertices here.
- iter.fDevice->drawVertices(vertices, bones, boneCount, bmode, looper.paint());
+ iter.fDevice->drawVertices(vertices, bones, boneCount, bmode, draw.paint());
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4],
@@ -2652,13 +2611,13 @@
return;
}
- LOOPER_BEGIN(paint, nullptr)
+ DRAW_BEGIN(paint, nullptr)
while (iter.next()) {
iter.fDevice->drawPatch(cubics, colors, texCoords, bmode, paint);
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::drawDrawable(SkDrawable* dr, SkScalar x, SkScalar y) {
@@ -2703,22 +2662,22 @@
pnt = *paint;
}
- LOOPER_BEGIN(pnt, nullptr)
+ DRAW_BEGIN(pnt, nullptr)
while (iter.next()) {
iter.fDevice->drawAtlas(atlas, xform, tex, colors, count, bmode, pnt);
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) {
SkASSERT(key);
SkPaint paint;
- LOOPER_BEGIN(paint, nullptr)
+ DRAW_BEGIN(paint, nullptr)
while (iter.next()) {
iter.fDevice->drawAnnotation(rect, key, value);
}
- LOOPER_END
+ DRAW_END
}
void SkCanvas::onDrawEdgeAAQuad(const SkRect& r, const SkPoint clip[4], QuadAAFlags edgeAA,
@@ -2746,12 +2705,12 @@
// Looper is used when there are image filters, which drawEdgeAAImageSet needs to support
// for Chromium's RenderPassDrawQuads' filters.
- LOOPER_BEGIN(realPaint, nullptr)
+ DRAW_BEGIN(realPaint, nullptr)
while (iter.next()) {
iter.fDevice->drawEdgeAAImageSet(
- imageSet, count, dstClips, preViewMatrices, looper.paint(), constraint);
+ imageSet, count, dstClips, preViewMatrices, draw.paint(), constraint);
}
- LOOPER_END
+ DRAW_END
}
//////////////////////////////////////////////////////////////////////////////