Return translate info from looper, rather than moding a canvas
Change-Id: Ibb4520030bc0ca455fa079d923fd4f5be86d72a1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/229837
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 bdb0e82..762af67 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -421,7 +421,8 @@
#ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
if (SkDrawLooper* looper = paint.getLooper()) {
- fLooperContext = looper->makeContext(canvas, &fAlloc);
+ fLooperContext = looper->makeContext(&fAlloc);
+ fCanvas->save();
fIsSimple = false;
} else
#endif
@@ -491,9 +492,15 @@
paint->setBlendMode(SkBlendMode::kSrcOver);
}
- if (fLooperContext && !fLooperContext->next(fCanvas, paint)) {
- fDone = true;
- return false;
+ if (fLooperContext) {
+ fCanvas->restore();
+ SkDrawLooper::Context::Info info;
+ if (!fLooperContext->next(&info, paint)) {
+ fDone = true;
+ return false;
+ }
+ fCanvas->save();
+ info.applyToCanvas(fCanvas);
}
fPaint = paint;
diff --git a/src/core/SkDrawLooper.cpp b/src/core/SkDrawLooper.cpp
index 6aa082a..11dee29 100644
--- a/src/core/SkDrawLooper.cpp
+++ b/src/core/SkDrawLooper.cpp
@@ -12,14 +12,32 @@
#include "include/core/SkRect.h"
#include "src/core/SkArenaAlloc.h"
+void SkDrawLooper::Context::Info::applyToCTM(SkMatrix* ctm) const {
+ if (fApplyPostCTM) {
+ ctm->postTranslate(fTranslate.fX, fTranslate.fY);
+ } else {
+ ctm->preTranslate(fTranslate.fX, fTranslate.fY);
+ }
+}
+
+void SkDrawLooper::Context::Info::applyToCanvas(SkCanvas* canvas) const {
+ if (fApplyPostCTM) {
+ SkMatrix ctm = canvas->getTotalMatrix();
+ ctm.postTranslate(fTranslate.fX, fTranslate.fY);
+ canvas->setMatrix(ctm);
+ } else {
+ canvas->translate(fTranslate.fX, fTranslate.fY);
+ }
+}
+
bool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) const {
- SkCanvas canvas;
SkSTArenaAlloc<48> alloc;
- SkDrawLooper::Context* context = this->makeContext(&canvas, &alloc);
+ SkDrawLooper::Context* context = this->makeContext(&alloc);
for (;;) {
SkPaint p(paint);
- if (context->next(&canvas, &p)) {
+ SkDrawLooper::Context::Info info;
+ if (context->next(&info, &p)) {
#ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
p.setLooper(nullptr);
#endif
@@ -38,22 +56,22 @@
// src and dst rects may alias and we need to keep the original src, so copy it.
const SkRect src = s;
- SkCanvas canvas;
SkSTArenaAlloc<48> alloc;
*dst = src; // catch case where there are no loops
- SkDrawLooper::Context* context = this->makeContext(&canvas, &alloc);
+ SkDrawLooper::Context* context = this->makeContext(&alloc);
for (bool firstTime = true;; firstTime = false) {
SkPaint p(paint);
- if (context->next(&canvas, &p)) {
+ SkDrawLooper::Context::Info info;
+ if (context->next(&info, &p)) {
SkRect r(src);
#ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
p.setLooper(nullptr);
#endif
p.computeFastBounds(r, &r);
- canvas.getTotalMatrix().mapRect(&r);
+ r.offset(info.fTranslate.fX, info.fTranslate.fY);
if (firstTime) {
*dst = r;
@@ -73,14 +91,24 @@
void SkDrawLooper::apply(SkCanvas* canvas, const SkPaint& paint,
std::function<void(SkCanvas*, const SkPaint&)> proc) {
SkSTArenaAlloc<256> alloc;
- Context* ctx = this->makeContext(canvas, &alloc);
+ Context* ctx = this->makeContext(&alloc);
if (ctx) {
+ Context::Info info;
for (;;) {
SkPaint p = paint;
- if (!ctx->next(canvas, &p)) {
+ if (!ctx->next(&info, &p)) {
break;
}
+ canvas->save();
+ if (info.fApplyPostCTM) {
+ SkMatrix ctm = canvas->getTotalMatrix();
+ ctm.postTranslate(info.fTranslate.fX, info.fTranslate.fY);
+ canvas->setMatrix(ctm);
+ } else {
+ canvas->translate(info.fTranslate.fX, info.fTranslate.fY);
+ }
proc(canvas, p);
+ canvas->restore();
}
}
}
diff --git a/src/effects/SkLayerDrawLooper.cpp b/src/effects/SkLayerDrawLooper.cpp
index 1dd5b29..4259221 100644
--- a/src/effects/SkLayerDrawLooper.cpp
+++ b/src/effects/SkLayerDrawLooper.cpp
@@ -42,8 +42,7 @@
}
SkLayerDrawLooper::Context*
-SkLayerDrawLooper::makeContext(SkCanvas* canvas, SkArenaAlloc* alloc) const {
- canvas->save();
+SkLayerDrawLooper::makeContext(SkArenaAlloc* alloc) const {
return alloc->make<LayerDrawLooperContext>(this);
}
@@ -130,35 +129,21 @@
#endif
}
-// Should we add this to canvas?
-static void postTranslate(SkCanvas* canvas, SkScalar dx, SkScalar dy) {
- SkMatrix m = canvas->getTotalMatrix();
- m.postTranslate(dx, dy);
- canvas->setMatrix(m);
-}
-
SkLayerDrawLooper::LayerDrawLooperContext::LayerDrawLooperContext(
const SkLayerDrawLooper* looper) : fCurrRec(looper->fRecs) {}
-bool SkLayerDrawLooper::LayerDrawLooperContext::next(SkCanvas* canvas,
- SkPaint* paint) {
- canvas->restore();
+bool SkLayerDrawLooper::LayerDrawLooperContext::next(Info* info, SkPaint* paint) {
if (nullptr == fCurrRec) {
return false;
}
ApplyInfo(paint, fCurrRec->fPaint, fCurrRec->fInfo);
- canvas->save();
- if (fCurrRec->fInfo.fPostTranslate) {
- postTranslate(canvas, fCurrRec->fInfo.fOffset.fX,
- fCurrRec->fInfo.fOffset.fY);
- } else {
- canvas->translate(fCurrRec->fInfo.fOffset.fX,
- fCurrRec->fInfo.fOffset.fY);
+ if (info) {
+ info->fTranslate = fCurrRec->fInfo.fOffset;
+ info->fApplyPostCTM = fCurrRec->fInfo.fPostTranslate;
}
fCurrRec = fCurrRec->fNext;
-
return true;
}