Switch SkColorFilterImageFilter over to new onFilterImage interface (again)
authorrobertphillips <robertphillips@google.com>
Tue, 19 Apr 2016 17:21:02 +0000 (10:21 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 19 Apr 2016 17:21:03 +0000 (10:21 -0700)
Back when this was originally reverted I was able to easily repro the perf regression locally. At ToT Skia/Chrome I can no longer repro the perf regression with this CL (in fact there is a modest perf improvement).

I propose landing this and then watching the Chromium perf bots.

BUG=602300,598028
TBR=reed@google.com

GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1901513002

Review URL: https://codereview.chromium.org/1901513002

include/effects/SkColorFilterImageFilter.h
src/effects/SkColorFilterImageFilter.cpp

index 2aa04d1..5ed051c 100644 (file)
@@ -33,8 +33,8 @@ public:
 
 protected:
     void flatten(SkWriteBuffer&) const override;
-    bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result,
-                                 SkIPoint* loc) const override;
+    sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
+                                        SkIPoint* offset) const override;
     bool onIsColorFilterNode(SkColorFilter**) const override;
     bool affectsTransparentBlack() const override;
 
index 63dded6..8d412cc 100644 (file)
@@ -9,8 +9,9 @@
 
 #include "SkCanvas.h"
 #include "SkColorFilter.h"
-#include "SkDevice.h"
 #include "SkReadBuffer.h"
+#include "SkSpecialImage.h"
+#include "SkSpecialSurface.h"
 #include "SkWriteBuffer.h"
 
 sk_sp<SkImageFilter> SkColorFilterImageFilter::Make(sk_sp<SkColorFilter> cf,
@@ -56,55 +57,62 @@ void SkColorFilterImageFilter::flatten(SkWriteBuffer& buffer) const {
     buffer.writeFlattenable(fColorFilter.get());
 }
 
-bool SkColorFilterImageFilter::onFilterImageDeprecated(Proxy* proxy, const SkBitmap& source,
-                                                       const Context& ctx,
-                                                       SkBitmap* result,
-                                                       SkIPoint* offset) const {
-    SkBitmap src = source;
-    SkIPoint srcOffset = SkIPoint::Make(0, 0);
-    bool inputResult = this->filterInputDeprecated(0, proxy, source, ctx, &src, &srcOffset);
-
-    SkIRect srcBounds;
+sk_sp<SkSpecialImage> SkColorFilterImageFilter::onFilterImage(SkSpecialImage* source,
+                                                              const Context& ctx,
+                                                              SkIPoint* offset) const {
+    SkIPoint inputOffset = SkIPoint::Make(0, 0);
+    sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset));
 
+    SkIRect inputBounds;
     if (fColorFilter->affectsTransparentBlack()) {
         // If the color filter affects transparent black, the bounds are the entire clip.
-        srcBounds = ctx.clipBounds();
-    } else if (!inputResult) {
-        return false;
+        inputBounds = ctx.clipBounds();
+    } else if (!input) {
+        return nullptr;
     } else {
-        srcBounds = src.bounds();
-        srcBounds.offset(srcOffset);
+        inputBounds = SkIRect::MakeXYWH(inputOffset.x(), inputOffset.y(),
+                                        input->width(), input->height());
     }
 
     SkIRect bounds;
-    if (!this->applyCropRect(ctx, srcBounds, &bounds)) {
-        return false;
+    if (!this->applyCropRect(ctx, inputBounds, &bounds)) {
+        return nullptr;
     }
 
-    SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
-    if (nullptr == device.get()) {
-        return false;
+    SkImageInfo info = SkImageInfo::MakeN32(bounds.width(), bounds.height(), kPremul_SkAlphaType);
+    sk_sp<SkSpecialSurface> surf(source->makeSurface(info));
+    if (!surf) {
+        return nullptr;
     }
-    SkCanvas canvas(device.get());
+
+    SkCanvas* canvas = surf->getCanvas();
+    SkASSERT(canvas);
 
     SkPaint paint;
+
     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     paint.setColorFilter(fColorFilter);
 
     // TODO: it may not be necessary to clear or drawPaint inside the input bounds
     // (see skbug.com/5075)
     if (fColorFilter->affectsTransparentBlack()) {
-        // The subsequent drawBitmap call may not fill the entire canvas. For filters which
+        // The subsequent input->draw() call may not fill the entire canvas. For filters which
         // affect transparent black, ensure that the filter is applied everywhere.
-        canvas.drawPaint(paint);
+        canvas->drawPaint(paint);
+    } else {
+        canvas->clear(0x0);
+    }
+
+    if (input) {
+        input->draw(canvas,
+                    SkIntToScalar(inputOffset.fX - bounds.fLeft),
+                    SkIntToScalar(inputOffset.fY - bounds.fTop),
+                    &paint);
     }
 
-    canvas.drawBitmap(src, SkIntToScalar(srcOffset.fX - bounds.fLeft),
-                           SkIntToScalar(srcOffset.fY - bounds.fTop), &paint);
-    *result = device.get()->accessBitmap(false);
     offset->fX = bounds.fLeft;
     offset->fY = bounds.fTop;
-    return true;
+    return surf->makeImageSnapshot();
 }
 
 bool SkColorFilterImageFilter::onIsColorFilterNode(SkColorFilter** filter) const {