SkTCopyOnFirstWrite-based SkPaintFilterCanvas API
I find this version preferable because
1) it consolidates the in/out paint args without compromising
efficiency or flexibility
2) relieves overriders from having to set the SkTLazy explicitly
BUG=skia:4782
R=mtklein@google.com,reed@google.com
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1576183002
Review URL: https://codereview.chromium.org/1576183002
diff --git a/include/core/SkTLazy.h b/include/core/SkTLazy.h
index c8ae317..8032538 100644
--- a/include/core/SkTLazy.h
+++ b/include/core/SkTLazy.h
@@ -131,6 +131,8 @@
public:
SkTCopyOnFirstWrite(const T& initial) : fObj(&initial) {}
+ SkTCopyOnFirstWrite(const T* initial) : fObj(initial) {}
+
// Constructor for delayed initialization.
SkTCopyOnFirstWrite() : fObj(NULL) {}
diff --git a/include/utils/SkPaintFilterCanvas.h b/include/utils/SkPaintFilterCanvas.h
index 505f965..35e3221 100644
--- a/include/utils/SkPaintFilterCanvas.h
+++ b/include/utils/SkPaintFilterCanvas.h
@@ -49,22 +49,18 @@
protected:
/**
* Called with the paint that will be used to draw the specified type.
- *
- * Upon return, if filteredPaint is initialized it will replace the original paint
- * for the current draw. Note that that implementation is responsible for
- * initializing *filteredPaint (e.g. via set(*paint)).
+ * The implementation may modify the paint as they wish (using SkTCopyOnFirstWrite::writable).
*
* The result bool is used to determine whether the draw op is to be
- * executed (true) or skipped (false). When the draw is skipped, filteredPaint is
- * ignored.
+ * executed (true) or skipped (false).
*
* Note: The base implementation calls onFilter() for top-level/explicit paints only.
* To also filter encapsulated paints (e.g. SkPicture, SkTextBlob), clients may need to
* override the relevant methods (i.e. drawPicture, drawTextBlob).
*/
- virtual bool onFilter(const SkPaint* paint, Type type, SkTLazy<SkPaint>* filteredPaint) const {
- if (paint) {
- this->onFilterPaint(filteredPaint->set(*paint), type);
+ virtual bool onFilter(SkTCopyOnFirstWrite<SkPaint>* paint, Type type) const {
+ if (*paint) {
+ this->onFilterPaint(paint->writable(), type);
}
return true;
}
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index ce2cfb2..a3a81d8 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -475,27 +475,25 @@
}
protected:
- bool onFilter(const SkPaint* paint, Type t, SkTLazy<SkPaint>* filteredPaint) const override {
- if (!paint) {
+ bool onFilter(SkTCopyOnFirstWrite<SkPaint>* paint, Type t) const override {
+ if (!*paint) {
return true;
}
- filteredPaint->set(*paint);
if (kText_Type == t && SkOSMenu::kMixedState != fLCDState) {
- filteredPaint->get()->setLCDRenderText(SkOSMenu::kOnState == fLCDState);
+ paint->writable()->setLCDRenderText(SkOSMenu::kOnState == fLCDState);
}
if (SkOSMenu::kMixedState != fAAState) {
- filteredPaint->get()->setAntiAlias(SkOSMenu::kOnState == fAAState);
+ paint->writable()->setAntiAlias(SkOSMenu::kOnState == fAAState);
}
if (0 != fFilterQualityIndex) {
- filteredPaint->get()->setFilterQuality(
- gFilterQualityStates[fFilterQualityIndex].fQuality);
+ paint->writable()->setFilterQuality(gFilterQualityStates[fFilterQualityIndex].fQuality);
}
if (SkOSMenu::kMixedState != fSubpixelState) {
- filteredPaint->get()->setSubpixelText(SkOSMenu::kOnState == fSubpixelState);
+ paint->writable()->setSubpixelText(SkOSMenu::kOnState == fSubpixelState);
}
if (0 != fHintingState && fHintingState < (int)SK_ARRAY_COUNT(gHintingStates)) {
- filteredPaint->get()->setHinting(gHintingStates[fHintingState].hinting);
+ paint->writable()->setHinting(gHintingStates[fHintingState].hinting);
}
return true;
}
diff --git a/src/utils/SkPaintFilterCanvas.cpp b/src/utils/SkPaintFilterCanvas.cpp
index 0a5b7e6..ea94068 100644
--- a/src/utils/SkPaintFilterCanvas.cpp
+++ b/src/utils/SkPaintFilterCanvas.cpp
@@ -13,23 +13,20 @@
class SkPaintFilterCanvas::AutoPaintFilter {
public:
AutoPaintFilter(const SkPaintFilterCanvas* canvas, Type type, const SkPaint* paint)
- : fOrigPaint(paint) {
- fShouldDraw = canvas->onFilter(fOrigPaint, type, &fFilteredPaint);
+ : fPaint(paint) {
+ fShouldDraw = canvas->onFilter(&fPaint, type);
}
AutoPaintFilter(const SkPaintFilterCanvas* canvas, Type type, const SkPaint& paint)
: AutoPaintFilter(canvas, type, &paint) { }
- const SkPaint* paint() const {
- return fFilteredPaint.isValid() ? fFilteredPaint.get() : fOrigPaint;
- }
+ const SkPaint* paint() const { return fPaint; }
bool shouldDraw() const { return fShouldDraw; }
private:
- const SkPaint* fOrigPaint;
- SkTLazy<SkPaint> fFilteredPaint;
- bool fShouldDraw;
+ SkTCopyOnFirstWrite<SkPaint> fPaint;
+ bool fShouldDraw;
};
SkPaintFilterCanvas::SkPaintFilterCanvas(int width, int height) : INHERITED(width, height) { }
diff --git a/src/utils/debugger/SkDebugCanvas.cpp b/src/utils/debugger/SkDebugCanvas.cpp
index 9f11a9e..63739ae 100644
--- a/src/utils/debugger/SkDebugCanvas.cpp
+++ b/src/utils/debugger/SkDebugCanvas.cpp
@@ -69,16 +69,15 @@
, fFilterQuality(quality) {}
protected:
- bool onFilter(const SkPaint* paint, Type, SkTLazy<SkPaint>* filteredPaint) const override {
- if (paint) {
- filteredPaint->set(*paint);
+ bool onFilter(SkTCopyOnFirstWrite<SkPaint>* paint, Type) const override {
+ if (*paint) {
if (nullptr != fOverdrawXfermode.get()) {
- filteredPaint->get()->setAntiAlias(false);
- filteredPaint->get()->setXfermode(fOverdrawXfermode.get());
+ paint->writable()->setAntiAlias(false);
+ paint->writable()->setXfermode(fOverdrawXfermode.get());
}
if (fOverrideFilterQuality) {
- filteredPaint->get()->setFilterQuality(fFilterQuality);
+ paint->writable()->setFilterQuality(fFilterQuality);
}
}
return true;
diff --git a/tests/CanvasTest.cpp b/tests/CanvasTest.cpp
index 516dd05..774e85d 100644
--- a/tests/CanvasTest.cpp
+++ b/tests/CanvasTest.cpp
@@ -730,7 +730,7 @@
MockFilterCanvas(SkCanvas* canvas) : INHERITED(canvas) { }
protected:
- bool onFilter(const SkPaint*, Type, SkTLazy<SkPaint>*) const override { return true; }
+ bool onFilter(SkTCopyOnFirstWrite<SkPaint>*, Type) const override { return true; }
private:
typedef SkPaintFilterCanvas INHERITED;