SkTCopyOnFirstWrite-based SkPaintFilterCanvas API
authorfmalita <fmalita@chromium.org>
Tue, 12 Jan 2016 15:21:11 +0000 (07:21 -0800)
committerCommit bot <commit-bot@chromium.org>
Tue, 12 Jan 2016 15:21:11 +0000 (07:21 -0800)
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

include/core/SkTLazy.h
include/utils/SkPaintFilterCanvas.h
samplecode/SampleApp.cpp
src/utils/SkPaintFilterCanvas.cpp
src/utils/debugger/SkDebugCanvas.cpp
tests/CanvasTest.cpp

index c8ae317..8032538 100644 (file)
@@ -131,6 +131,8 @@ class SkTCopyOnFirstWrite {
 public:
     SkTCopyOnFirstWrite(const T& initial) : fObj(&initial) {}
 
+    SkTCopyOnFirstWrite(const T* initial) : fObj(initial) {}
+
     // Constructor for delayed initialization.
     SkTCopyOnFirstWrite() : fObj(NULL) {}
 
index 505f965..35e3221 100644 (file)
@@ -49,22 +49,18 @@ public:
 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;
     }
index ce2cfb2..a3a81d8 100644 (file)
@@ -475,27 +475,25 @@ public:
     }
 
 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;
     }
index 0a5b7e6..ea94068 100644 (file)
 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) { }
index 9f11a9e..63739ae 100644 (file)
@@ -69,16 +69,15 @@ public:
         , 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;
index 516dd05..774e85d 100644 (file)
@@ -730,7 +730,7 @@ public:
     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;