Revert of Switch SkBlurImageFilter over to new onFilterImage interface (patchset...
authorrobertphillips <robertphillips@google.com>
Wed, 23 Mar 2016 21:03:43 +0000 (14:03 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 23 Mar 2016 21:03:43 +0000 (14:03 -0700)
Reason for revert:
serialize-8888 broken for some reason

Original issue's description:
> Switch SkBlurImageFilter over to new onFilterImage interface
>
> This CL relies on:
> https://codereview.chromium.org/1787883002/ (Add SkSpecialImage::extractSubset & NewFromPixmap)
> https://codereview.chromium.org/1808743003/ (Allow SkGpuDevice::drawSprite to handle subset SkBitmaps)
> https://codereview.chromium.org/1813813002/ (Add SkSpecialImage::makeTextureImage entry point)
>
> GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1785643003
>
> Committed: https://skia.googlesource.com/skia/+/3c935bc87020bfd19a08922f7394db3a801d168b

TBR=senorblanco@google.com,senorblanco@chromium.org,bsalomon@google.com,reed@google.com
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

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

include/core/SkDevice.h
include/effects/SkBlurImageFilter.h
src/core/SkCanvas.cpp
src/core/SkDevice.cpp
src/effects/SkBlurImageFilter.cpp
src/gpu/SkGpuDevice.cpp
src/gpu/SkGpuDevice.h

index 126f1d2..cd13d54 100644 (file)
@@ -378,12 +378,6 @@ protected:
         return NULL;
     }
 
-    /**
-     *  Calls through to drawSprite, processing the imagefilter.
-     */
-    virtual void drawBitmapAsSpriteWithImageFilter(const SkDraw&, const SkBitmap&,
-                                                   int x, int y, const SkPaint&);
-
 private:
     friend class SkCanvas;
     friend struct DeviceCM; //for setMatrixClip
@@ -394,6 +388,11 @@ private:
     friend class SkNoPixelsBitmapDevice;
     friend class SkSurface_Raster;
 
+    /**
+     *  Calls through to drawSprite, processing imagefilter as needed.
+     */
+    void drawBitmapAsSprite(const SkDraw&, const SkBitmap&, int x, int y, const SkPaint&);
+
     // used to change the backend's pixels (and possibly config/rowbytes)
     // but cannot change the width/height, so there should be no change to
     // any clip information.
index 46d073e..8a2d211 100644 (file)
@@ -28,9 +28,12 @@ public:
 
 protected:
     void flatten(SkWriteBuffer&) const override;
-    SkSpecialImage* onFilterImage(SkSpecialImage* source, const Context&,
-                                  SkIPoint* offset) const override;
+    bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result,
+                                 SkIPoint* offset) const override;
     SkIRect onFilterNodeBounds(const SkIRect& src, const SkMatrix&, MapDirection) const override;
+    bool canFilterImageGPU() const override { return true; }
+    bool filterImageGPUDeprecated(Proxy* proxy, const SkBitmap& src, const Context& ctx,
+                                  SkBitmap* result, SkIPoint* offset) const override;
 
 private:
     SkBlurImageFilter(SkScalar sigmaX,
index fb79932..f7f8702 100644 (file)
@@ -2265,9 +2265,9 @@ void SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const S
             if (as_IB(image)->asBitmapForImageFilters(&bitmap)) {
                 SkPoint pt;
                 iter.fMatrix->mapXY(x, y, &pt);
-                iter.fDevice->drawBitmapAsSpriteWithImageFilter(iter, bitmap,
-                                                                SkScalarRoundToInt(pt.fX),
-                                                                SkScalarRoundToInt(pt.fY), pnt);
+                iter.fDevice->drawBitmapAsSprite(iter, bitmap,
+                                                 SkScalarRoundToInt(pt.fX),
+                                                 SkScalarRoundToInt(pt.fY), pnt);
             }
         } else {
             iter.fDevice->drawImage(iter, image, x, y, pnt);
@@ -2347,9 +2347,9 @@ void SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, cons
         if (drawAsSprite && pnt.getImageFilter()) {
             SkPoint pt;
             iter.fMatrix->mapXY(x, y, &pt);
-            iter.fDevice->drawBitmapAsSpriteWithImageFilter(iter, bitmap,
-                                                            SkScalarRoundToInt(pt.fX),
-                                                            SkScalarRoundToInt(pt.fY), pnt);
+            iter.fDevice->drawBitmapAsSprite(iter, bitmap,
+                                             SkScalarRoundToInt(pt.fX),
+                                             SkScalarRoundToInt(pt.fY), pnt);
         } else {
             iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint());
         }
index 0c0dfa9..fb4b48f 100644 (file)
@@ -403,13 +403,10 @@ void SkBaseDevice::drawTextOnPath(const SkDraw& draw, const void* text, size_t b
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-void SkBaseDevice::drawBitmapAsSpriteWithImageFilter(const SkDraw& draw, const SkBitmap& bitmap,
-                                                     int x, int y,
-                                                     const SkPaint& paint) {
+void SkBaseDevice::drawBitmapAsSprite(const SkDraw& draw, const SkBitmap& bitmap, int x, int y,
+                                      const SkPaint& paint) {
     SkImageFilter* filter = paint.getImageFilter();
-    SkASSERT(filter);
-
-    if (!this->canHandleImageFilter(filter)) {
+    if (filter && !this->canHandleImageFilter(filter)) {
         SkImageFilter::DeviceProxy proxy(this);
         SkIPoint offset = SkIPoint::Make(0, 0);
         SkMatrix matrix = *draw.fMatrix;
index ee153e9..8046706 100644 (file)
@@ -5,16 +5,14 @@
  * found in the LICENSE file.
  */
 
+#include "SkBitmap.h"
 #include "SkBlurImageFilter.h"
-
-#include "SkAutoPixmapStorage.h"
 #include "SkColorPriv.h"
+#include "SkDevice.h"
 #include "SkGpuBlurUtils.h"
 #include "SkOpts.h"
 #include "SkReadBuffer.h"
-#include "SkSpecialImage.h"
 #include "SkWriteBuffer.h"
-
 #if SK_SUPPORT_GPU
 #include "GrContext.h"
 #include "SkGr.h"
@@ -55,8 +53,8 @@ void SkBlurImageFilter::flatten(SkWriteBuffer& buffer) const {
     buffer.writeScalar(fSigma.fHeight);
 }
 
-static void get_box3_params(SkScalar s, int *kernelSize, int* kernelSize3, int *lowOffset,
-                            int *highOffset)
+static void getBox3Params(SkScalar s, int *kernelSize, int* kernelSize3, int *lowOffset,
+                          int *highOffset)
 {
     float pi = SkScalarToFloat(SK_ScalarPI);
     int d = static_cast<int>(floorf(SkScalarToFloat(s) * 3.0f * sqrtf(2.0f * pi) / 4.0f + 0.5f));
@@ -71,109 +69,77 @@ static void get_box3_params(SkScalar s, int *kernelSize, int* kernelSize3, int *
     }
 }
 
-SkSpecialImage* SkBlurImageFilter::onFilterImage(SkSpecialImage* source, const Context& ctx,
-                                                 SkIPoint* offset) const {
-    SkIPoint inputOffset = SkIPoint::Make(0, 0);
-
-    SkAutoTUnref<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset));
-    if (!input) {
-        return nullptr;
+bool SkBlurImageFilter::onFilterImageDeprecated(Proxy* proxy,
+                                                const SkBitmap& source, const Context& ctx,
+                                                SkBitmap* dst, SkIPoint* offset) const {
+    SkBitmap src = source;
+    SkIPoint srcOffset = SkIPoint::Make(0, 0);
+    if (!this->filterInputDeprecated(0, proxy, source, ctx, &src, &srcOffset)) {
+        return false;
     }
 
-    SkIRect inputBounds = SkIRect::MakeXYWH(inputOffset.fX, inputOffset.fY,
-                                            input->width(), input->height());
+    if (src.colorType() != kN32_SkColorType) {
+        return false;
+    }
 
+    SkIRect srcBounds = src.bounds();
+    srcBounds.offset(srcOffset);
     SkIRect dstBounds;
-    if (!this->applyCropRect(this->mapContext(ctx), inputBounds, &dstBounds)) {
-        return nullptr;
+    if (!this->applyCropRect(this->mapContext(ctx), srcBounds, &dstBounds)) {
+        return false;
     }
-    if (!inputBounds.intersect(dstBounds)) {
-        return nullptr;
+    if (!srcBounds.intersect(dstBounds)) {
+        return false;
     }
 
-    const SkVector sigma = map_sigma(fSigma, ctx.ctm());
-
-#if SK_SUPPORT_GPU
-    if (input->peekTexture()) {
-        if (0 == sigma.x() && 0 == sigma.y()) {
-            offset->fX = inputBounds.x();
-            offset->fY = inputBounds.y();
-            return input->makeSubset(inputBounds.makeOffset(-inputOffset.x(),
-                                                            -inputOffset.y())).release();
-        }
-
-        GrTexture* inputTexture = input->peekTexture();
-
-        offset->fX = dstBounds.fLeft;
-        offset->fY = dstBounds.fTop;
-        inputBounds.offset(-inputOffset);
-        dstBounds.offset(-inputOffset);
-        SkRect inputBoundsF(SkRect::Make(inputBounds));
-        SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(inputTexture->getContext(),
-                                                                 inputTexture,
-                                                                 false,
-                                                                 SkRect::Make(dstBounds),
-                                                                 &inputBoundsF,
-                                                                 sigma.x(),
-                                                                 sigma.y()));
-        if (!tex) {
-            return nullptr;
-        }
-
-        return SkSpecialImage::MakeFromGpu(source->internal_getProxy(),
-                                           SkIRect::MakeWH(dstBounds.width(), dstBounds.height()),
-                                           kNeedNewImageUniqueID_SpecialImage,
-                                           tex).release();
-    }
-#endif
+    SkVector sigma = map_sigma(fSigma, ctx.ctm());
 
     int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX;
     int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY;
-    get_box3_params(sigma.x(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffsetX);
-    get_box3_params(sigma.y(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffsetY);
+    getBox3Params(sigma.x(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffsetX);
+    getBox3Params(sigma.y(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffsetY);
 
     if (kernelSizeX < 0 || kernelSizeY < 0) {
-        return nullptr;
+        return false;
     }
 
     if (kernelSizeX == 0 && kernelSizeY == 0) {
-        offset->fX = inputBounds.x();
-        offset->fY = inputBounds.y();
-        return input->makeSubset(inputBounds.makeOffset(-inputOffset.x(),
-                                                        -inputOffset.y())).release();
+        src.extractSubset(dst, srcBounds.makeOffset(-srcOffset.x(), -srcOffset.y()));
+        offset->fX = srcBounds.x();
+        offset->fY = srcBounds.y();
+        return true;
     }
 
-    SkPixmap inputPixmap;
-
-    if (!input->peekPixels(&inputPixmap)) {
-        return nullptr;
+    SkAutoLockPixels alp(src);
+    if (!src.getPixels()) {
+        return false;
     }
 
-    if (inputPixmap.colorType() != kN32_SkColorType) {
-        return nullptr;
+    SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstBounds.width(), dstBounds.height()));
+    if (!device) {
+        return false;
     }
+    *dst = device->accessBitmap(false);
+    SkAutoLockPixels alp_dst(*dst);
 
-    SkImageInfo info = SkImageInfo::Make(dstBounds.width(), dstBounds.height(),
-                                         inputPixmap.colorType(), inputPixmap.alphaType());
-
-    SkBitmap tmp, dst;
-    if (!tmp.tryAllocPixels(info) || !dst.tryAllocPixels(info)) {
-        return nullptr;
+    SkAutoTUnref<SkBaseDevice> tempDevice(proxy->createDevice(dst->width(), dst->height()));
+    if (!tempDevice) {
+        return false;
     }
+    SkBitmap temp = tempDevice->accessBitmap(false);
+    SkAutoLockPixels alpTemp(temp);
 
     offset->fX = dstBounds.fLeft;
     offset->fY = dstBounds.fTop;
-    SkPMColor* t = tmp.getAddr32(0, 0);
-    SkPMColor* d = dst.getAddr32(0, 0);
+    SkPMColor* t = temp.getAddr32(0, 0);
+    SkPMColor* d = dst->getAddr32(0, 0);
     int w = dstBounds.width(), h = dstBounds.height();
-    const SkPMColor* s = inputPixmap.addr32(inputBounds.x() - inputOffset.x(),
-                                            inputBounds.y() - inputOffset.y());
-    inputBounds.offset(-dstBounds.x(), -dstBounds.y());
+    const SkPMColor* s = src.getAddr32(srcBounds.x() - srcOffset.x(), srcBounds.y() - srcOffset.y());
+    srcBounds.offset(-dstBounds.x(), -dstBounds.y());
     dstBounds.offset(-dstBounds.x(), -dstBounds.y());
-    SkIRect inputBoundsT = SkIRect::MakeLTRB(inputBounds.top(), inputBounds.left(),
-                                             inputBounds.bottom(), inputBounds.right());
+    SkIRect srcBoundsT = SkIRect::MakeLTRB(srcBounds.top(), srcBounds.left(), srcBounds.bottom(), srcBounds.right());
     SkIRect dstBoundsT = SkIRect::MakeWH(dstBounds.height(), dstBounds.width());
-    int sw = int(inputPixmap.rowBytes() >> 2);
+    int sw = src.rowBytesAsPixels();
 
     /**
      *
@@ -194,26 +160,22 @@ SkSpecialImage* SkBlurImageFilter::onFilterImage(SkSpecialImage* source, const C
      * images, and all memory reads are contiguous.
      */
     if (kernelSizeX > 0 && kernelSizeY > 0) {
-        SkOpts::box_blur_xx(s, sw,  inputBounds,  t, kernelSizeX,  lowOffsetX,  highOffsetX, w, h);
-        SkOpts::box_blur_xx(t,  w,  dstBounds,    d, kernelSizeX,  highOffsetX, lowOffsetX,  w, h);
-        SkOpts::box_blur_xy(d,  w,  dstBounds,    t, kernelSizeX3, highOffsetX, highOffsetX, w, h);
-        SkOpts::box_blur_xx(t,  h,  dstBoundsT,   d, kernelSizeY,  lowOffsetY,  highOffsetY, h, w);
-        SkOpts::box_blur_xx(d,  h,  dstBoundsT,   t, kernelSizeY,  highOffsetY, lowOffsetY,  h, w);
-        SkOpts::box_blur_xy(t,  h,  dstBoundsT,   d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
+        SkOpts::box_blur_xx(s, sw,  srcBounds,  t, kernelSizeX,  lowOffsetX,  highOffsetX, w, h);
+        SkOpts::box_blur_xx(t,  w,  dstBounds,  d, kernelSizeX,  highOffsetX, lowOffsetX,  w, h);
+        SkOpts::box_blur_xy(d,  w,  dstBounds,  t, kernelSizeX3, highOffsetX, highOffsetX, w, h);
+        SkOpts::box_blur_xx(t,  h,  dstBoundsT, d, kernelSizeY,  lowOffsetY,  highOffsetY, h, w);
+        SkOpts::box_blur_xx(d,  h,  dstBoundsT, t, kernelSizeY,  highOffsetY, lowOffsetY,  h, w);
+        SkOpts::box_blur_xy(t,  h,  dstBoundsT, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
     } else if (kernelSizeX > 0) {
-        SkOpts::box_blur_xx(s, sw,  inputBounds,  d, kernelSizeX,  lowOffsetX,  highOffsetX, w, h);
-        SkOpts::box_blur_xx(d,  w,  dstBounds,    t, kernelSizeX,  highOffsetX, lowOffsetX,  w, h);
-        SkOpts::box_blur_xx(t,  w,  dstBounds,    d, kernelSizeX3, highOffsetX, highOffsetX, w, h);
+        SkOpts::box_blur_xx(s, sw,  srcBounds,  d, kernelSizeX,  lowOffsetX,  highOffsetX, w, h);
+        SkOpts::box_blur_xx(d,  w,  dstBounds,  t, kernelSizeX,  highOffsetX, lowOffsetX,  w, h);
+        SkOpts::box_blur_xx(t,  w,  dstBounds,  d, kernelSizeX3, highOffsetX, highOffsetX, w, h);
     } else if (kernelSizeY > 0) {
-        SkOpts::box_blur_yx(s, sw,  inputBoundsT, d, kernelSizeY,  lowOffsetY,  highOffsetY, h, w);
-        SkOpts::box_blur_xx(d,  h,  dstBoundsT,   t, kernelSizeY,  highOffsetY, lowOffsetY,  h, w);
-        SkOpts::box_blur_xy(t,  h,  dstBoundsT,   d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
+        SkOpts::box_blur_yx(s, sw,  srcBoundsT, d, kernelSizeY,  lowOffsetY,  highOffsetY, h, w);
+        SkOpts::box_blur_xx(d,  h,  dstBoundsT, t, kernelSizeY,  highOffsetY, lowOffsetY,  h, w);
+        SkOpts::box_blur_xy(t,  h,  dstBoundsT, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
     }
-
-    return SkSpecialImage::MakeFromRaster(source->internal_getProxy(), 
-                                          SkIRect::MakeWH(dstBounds.width(),
-                                                          dstBounds.height()),
-                                          dst).release();
+    return true;
 }
 
 
@@ -231,6 +193,55 @@ SkIRect SkBlurImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix
                           SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3))));
 }
 
+bool SkBlurImageFilter::filterImageGPUDeprecated(Proxy* proxy, const SkBitmap& src,
+                                                 const Context& ctx,
+                                                 SkBitmap* result, SkIPoint* offset) const {
+#if SK_SUPPORT_GPU
+    SkBitmap input = src;
+    SkIPoint srcOffset = SkIPoint::Make(0, 0);
+    if (!this->filterInputGPUDeprecated(0, proxy, src, ctx, &input, &srcOffset)) {
+        return false;
+    }
+    SkIRect srcBounds = input.bounds();
+    srcBounds.offset(srcOffset);
+    SkIRect dstBounds;
+    if (!this->applyCropRect(this->mapContext(ctx), srcBounds, &dstBounds)) {
+        return false;
+    }
+    if (!srcBounds.intersect(dstBounds)) {
+        return false;
+    }
+    SkVector sigma = map_sigma(fSigma, ctx.ctm());
+    if (sigma.x() == 0 && sigma.y() == 0) {
+        input.extractSubset(result, srcBounds.makeOffset(-srcOffset.x(), -srcOffset.y()));
+        offset->fX = srcBounds.x();
+        offset->fY = srcBounds.y();
+        return true;
+    }
+    offset->fX = dstBounds.fLeft;
+    offset->fY = dstBounds.fTop;
+    srcBounds.offset(-srcOffset);
+    dstBounds.offset(-srcOffset);
+    SkRect srcBoundsF(SkRect::Make(srcBounds));
+    GrTexture* inputTexture = input.getTexture();
+    SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(inputTexture->getContext(),
+                                                             inputTexture,
+                                                             false,
+                                                             SkRect::Make(dstBounds),
+                                                             &srcBoundsF,
+                                                             sigma.x(),
+                                                             sigma.y()));
+    if (!tex) {
+        return false;
+    }
+    GrWrapTextureInBitmap(tex, dstBounds.width(), dstBounds.height(), false, result);
+    return true;
+#else
+    SkDEBUGFAIL("Should not call in GPU-less build");
+    return false;
+#endif
+}
+
 #ifndef SK_IGNORE_TO_STRING
 void SkBlurImageFilter::toString(SkString* str) const {
     str->appendf("SkBlurImageFilter: (");
index 6fa56da..823e9b8 100644 (file)
@@ -221,38 +221,6 @@ GrRenderTarget* SkGpuDevice::CreateRenderTarget(
     return texture->asRenderTarget();
 }
 
-// This method ensures that we always have a texture-backed "bitmap" when we finally
-// call through to the base impl so that the image filtering code will take the
-// gpu-specific paths. This mirrors SkCanvas::internalDrawDevice (the other
-// use of SkImageFilter::filterImage) in that the source and dest will have
-// homogenous backing (e.g., raster or gpu).
-void SkGpuDevice::drawBitmapAsSpriteWithImageFilter(const SkDraw& draw, const SkBitmap& bitmap,
-                                                    int x, int y, const SkPaint& paint) {
-    if (bitmap.getTexture()) {
-        INHERITED::drawBitmapAsSpriteWithImageFilter(draw, bitmap, x, y, paint);
-        return;
-    }
-
-    SkAutoLockPixels alp(bitmap, !bitmap.getTexture());
-    if (!bitmap.getTexture() && !bitmap.readyToDraw()) {
-        return;
-    }
-
-    GrTexture* texture;
-    // draw sprite neither filters nor tiles.
-    AutoBitmapTexture abt(fContext, bitmap, GrTextureParams::ClampNoFilter(), &texture);
-    if (!texture) {
-        return;
-    }
-
-    SkBitmap newBitmap;
-
-    GrWrapTextureInBitmap(texture, texture->width(), texture->height(),
-                          bitmap.isOpaque(), &newBitmap);
-
-    INHERITED::drawBitmapAsSpriteWithImageFilter(draw, newBitmap, x, y, paint);
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
 bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
index 81bbedb..e57da44 100644 (file)
@@ -262,9 +262,6 @@ private:
     static GrRenderTarget* CreateRenderTarget(GrContext*, SkBudgeted, const SkImageInfo&,
                                               int sampleCount, GrTextureStorageAllocator);
 
-    void drawBitmapAsSpriteWithImageFilter(const SkDraw&, const SkBitmap&, int x, int y,
-                                           const SkPaint&) override;
-
     friend class GrAtlasTextContext;
     friend class SkSurface_Gpu;      // for access to surfaceProps
     typedef SkBaseDevice INHERITED;