Change signatures of filter bounds methods to return a rect.
authorsenorblanco <senorblanco@chromium.org>
Mon, 21 Mar 2016 21:51:59 +0000 (14:51 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 21 Mar 2016 21:51:59 +0000 (14:51 -0700)
Change filterBounds(), onFilterBounds() and onFilterNodeBounds() and computeFastBounds() to
return the destination rectangle. There was no code path that could
return false, and returning rects by value is ok now.

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

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

28 files changed:
include/core/SkImageFilter.h
include/effects/SkBlurImageFilter.h
include/effects/SkComposeImageFilter.h
include/effects/SkDisplacementMapEffect.h
include/effects/SkDropShadowImageFilter.h
include/effects/SkImageSource.h
include/effects/SkMatrixConvolutionImageFilter.h
include/effects/SkMorphologyImageFilter.h
include/effects/SkOffsetImageFilter.h
include/effects/SkTileImageFilter.h
src/core/SkCanvas.cpp
src/core/SkImageFilter.cpp
src/core/SkLocalMatrixImageFilter.cpp
src/core/SkLocalMatrixImageFilter.h
src/core/SkMatrixImageFilter.cpp
src/core/SkMatrixImageFilter.h
src/core/SkPaint.cpp
src/effects/SkBlurImageFilter.cpp
src/effects/SkComposeImageFilter.cpp
src/effects/SkDisplacementMapEffect.cpp
src/effects/SkDropShadowImageFilter.cpp
src/effects/SkImageSource.cpp
src/effects/SkMatrixConvolutionImageFilter.cpp
src/effects/SkMorphologyImageFilter.cpp
src/effects/SkOffsetImageFilter.cpp
src/effects/SkTileImageFilter.cpp
src/gpu/GrLayerHoister.cpp
tests/ImageFilterTest.cpp

index f9090be..e58497d 100644 (file)
@@ -164,11 +164,17 @@ public:
      * image would be required to fill the given rect (typically, clip bounds).
      * Used for clipping and temp-buffer allocations, so the result need not
      * be exact, but should never be smaller than the real answer. The default
-     * implementation recursively unions all input bounds, or returns false if
-     * no inputs.
+     * implementation recursively unions all input bounds, or returns the
+     * source rect if no inputs.
      */
+    SkIRect filterBounds(const SkIRect& src, const SkMatrix& ctm,
+                         MapDirection = kReverse_MapDirection) const;
+
+#ifdef SK_SUPPORT_LEGACY_FILTERBOUNDS_RETURN
+    /* DEPRECATED */
     bool filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst,
                       MapDirection = kReverse_MapDirection) const;
+#endif
 
     /**
      *  Returns true if the filter can be processed on the GPU.  This is most
@@ -246,7 +252,7 @@ public:
     CropRect getCropRect() const { return fCropRect; }
 
     // Default impl returns union of all input bounds.
-    virtual void computeFastBounds(const SkRect&, SkRect*) const;
+    virtual SkRect computeFastBounds(const SkRect&) const;
 
     // Can this filter DAG compute the resulting bounds of an object-space rectangle?
     virtual bool canComputeFastBounds() const;
@@ -358,19 +364,17 @@ protected:
                                           SkIPoint* offset) const;
 
     /**
-     * This function recurses into its inputs with the given clip rect (first
+     * This function recurses into its inputs with the given rect (first
      * argument), calls filterBounds() with the given map direction on each,
-     * and unions the result (third argument). If the rect cannot be mapped,
-     * false is returned and the destination rect is left unchanged.
-     * If a derived class has special recursion requirements (e.g., it has an
-     * input which does not participate in bounds computation), it can be
-     * overridden here.
+     * and returns the union of those results. If a derived class has special
+     * recursion requirements (e.g., it has an input which does not participate
+     * in bounds computation), it can be overridden here.
      *
      * Note that this function is *not* responsible for mapping the rect for
      * this node's filter bounds requirements (i.e., calling
      * onFilterNodeBounds()); that is handled by filterBounds().
      */
-    virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*, MapDirection) const;
+    virtual SkIRect onFilterBounds(const SkIRect&, const SkMatrix&, MapDirection) const;
 
     /**
      * Performs a forwards or reverse mapping of the given rect to accommodate
@@ -385,7 +389,7 @@ protected:
      * in both forward and reverse directions. Unlike
      * onFilterBounds(), this function is non-recursive.
      */
-    virtual void onFilterNodeBounds(const SkIRect&, const SkMatrix&, SkIRect*, MapDirection) const;
+    virtual SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix&, MapDirection) const;
 
     // Helper function which invokes filter processing on the input at the
     // specified "index". If the input is null, it leaves "result" and
index 6612b21..8a2d211 100644 (file)
@@ -21,7 +21,7 @@ public:
         return new SkBlurImageFilter(sigmaX, sigmaY, input, cropRect);
     }
 
-    void computeFastBounds(const SkRect&, SkRect*) const override;
+    SkRect computeFastBounds(const SkRect&) const override;
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurImageFilter)
@@ -30,8 +30,7 @@ protected:
     void flatten(SkWriteBuffer&) const override;
     bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result,
                                  SkIPoint* offset) const override;
-    void onFilterNodeBounds(const SkIRect& src, const SkMatrix&,
-                            SkIRect* dst, MapDirection) 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;
index bdef08b..8c93b56 100644 (file)
@@ -22,7 +22,7 @@ public:
         SkImageFilter* inputs[2] = { outer, inner };
         return new SkComposeImageFilter(inputs);
     }
-    void computeFastBounds(const SkRect& src, SkRect* dst) const override;
+    SkRect computeFastBounds(const SkRect& src) const override;
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeImageFilter)
@@ -34,7 +34,7 @@ protected:
     }
     SkSpecialImage* onFilterImage(SkSpecialImage* source, const Context&,
                                   SkIPoint* offset) const override;
-    bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*, MapDirection) const override;
+    SkIRect onFilterBounds(const SkIRect&, const SkMatrix&, MapDirection) const override;
 
 private:
     typedef SkImageFilter INHERITED;
index 6aee97f..a5b81e8 100644 (file)
@@ -36,11 +36,11 @@ public:
                                  const Context& ctx,
                                  SkBitmap* dst,
                                  SkIPoint* offset) const override;
-    void computeFastBounds(const SkRect& src, SkRect* dst) const override;
+    SkRect computeFastBounds(const SkRect& src) const override;
 
-    virtual bool onFilterBounds(const SkIRect& src, const SkMatrix&,
-                                SkIRect* dst, MapDirection) const override;
-    void onFilterNodeBounds(const SkIRect&, const SkMatrix&, SkIRect*, MapDirection) const override;
+    virtual SkIRect onFilterBounds(const SkIRect& src, const SkMatrix&,
+                                   MapDirection) const override;
+    SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix&, MapDirection) const override;
 
 #if SK_SUPPORT_GPU
     bool canFilterImageGPU() const override { return true; }
index 2be77ce..1212c3f 100644 (file)
@@ -27,7 +27,7 @@ public:
                                            cropRect);
     }
 
-    void computeFastBounds(const SkRect&, SkRect*) const override;
+    SkRect computeFastBounds(const SkRect&) const override;
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDropShadowImageFilter)
 
@@ -35,8 +35,7 @@ protected:
     void flatten(SkWriteBuffer&) const override;
     bool onFilterImageDeprecated(Proxy*, const SkBitmap& source, const Context&, SkBitmap* result,
                                  SkIPoint* loc) const override;
-    void onFilterNodeBounds(const SkIRect& src, const SkMatrix&,
-                            SkIRect* dst, MapDirection) const override;
+    SkIRect onFilterNodeBounds(const SkIRect& src, const SkMatrix&, MapDirection) const override;
 
 private:
     SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor,
index 084028d..293a052 100644 (file)
@@ -20,7 +20,7 @@ public:
                                  const SkRect& dstRect,
                                  SkFilterQuality);
 
-    void computeFastBounds(const SkRect& src, SkRect* dst) const override;
+    SkRect computeFastBounds(const SkRect& src) const override;
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkImageSource)
index 40ebe20..a4abb0d 100644 (file)
@@ -79,7 +79,7 @@ protected:
 
     bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&,
                                  SkBitmap* result, SkIPoint* loc) const override;
-    void onFilterNodeBounds(const SkIRect&, const SkMatrix&, SkIRect*, MapDirection) const override;
+    SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix&, MapDirection) const override;
     bool canComputeFastBounds() const override;
 
 #if SK_SUPPORT_GPU
index 62e6f53..f4f1260 100644 (file)
@@ -15,9 +15,8 @@
 
 class SK_API SkMorphologyImageFilter : public SkImageFilter {
 public:
-    void computeFastBounds(const SkRect& src, SkRect* dst) const override;
-    void onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
-                            SkIRect* dst, MapDirection) const override;
+    SkRect computeFastBounds(const SkRect& src) const override;
+    SkIRect onFilterNodeBounds(const SkIRect& src, const SkMatrix&, MapDirection) const override;
 
     /**
      * All morphology procs have the same signature: src is the source buffer, dst the
index 768bd67..0b9ca83 100644 (file)
@@ -21,7 +21,7 @@ public:
         return new SkOffsetImageFilter(dx, dy, input, cropRect);
     }
 
-    void computeFastBounds(const SkRect& src, SkRect* dst) const override;
+    SkRect computeFastBounds(const SkRect& src) const override;
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkOffsetImageFilter)
@@ -30,7 +30,7 @@ protected:
     void flatten(SkWriteBuffer&) const override;
     SkSpecialImage* onFilterImage(SkSpecialImage* source, const Context&,
                                   SkIPoint* offset) const override;
-    void onFilterNodeBounds(const SkIRect&, const SkMatrix&, SkIRect*, MapDirection) const override;
+    SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix&, MapDirection) const override;
 
 private:
     SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input, const CropRect*);
index eef337f..ad334a3 100644 (file)
@@ -23,10 +23,9 @@ public:
 
     bool onFilterImageDeprecated(Proxy* proxy, const SkBitmap& src, const Context& ctx,
                                  SkBitmap* dst, SkIPoint* offset) const override;
-    bool onFilterBounds(const SkIRect& src, const SkMatrix&,
-                        SkIRect* dst, MapDirection) const override;
-    void onFilterNodeBounds(const SkIRect&, const SkMatrix&, SkIRect*, MapDirection) const override;
-    void computeFastBounds(const SkRect& src, SkRect* dst) const override;
+    SkIRect onFilterBounds(const SkIRect& src, const SkMatrix&, MapDirection) const override;
+    SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix&, MapDirection) const override;
+    SkRect computeFastBounds(const SkRect& src) const override;
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTileImageFilter)
index 3acb913..3efb44c 100644 (file)
@@ -1077,7 +1077,7 @@ bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlag
     const SkMatrix& ctm = fMCRec->fMatrix;  // this->getTotalMatrix()
 
     if (imageFilter) {
-        imageFilter->filterBounds(clipBounds, ctm, &clipBounds);
+        clipBounds = imageFilter->filterBounds(clipBounds, ctm);
         if (bounds && !imageFilter->canComputeFastBounds()) {
             bounds = nullptr;
         }
index 4ae839c..1c223a5 100644 (file)
@@ -290,47 +290,42 @@ bool SkImageFilter::filterInputDeprecated(int index, Proxy* proxy, const SkBitma
     return tmp->internal_getBM(result);
 }
 
+#ifdef SK_SUPPORT_LEGACY_FILTERBOUNDS_RETURN
 bool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst,
                                  MapDirection direction) const {
-    SkASSERT(dst);
-    SkIRect bounds;
+    *dst = filterBounds(src, ctm, direction);
+    return true;
+}
+#endif
+
+SkIRect SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm,
+                                 MapDirection direction) const {
     if (kReverse_MapDirection == direction) {
-        this->onFilterNodeBounds(src, ctm, &bounds, direction);
-        return this->onFilterBounds(bounds, ctm, dst, direction);
+        SkIRect bounds = this->onFilterNodeBounds(src, ctm, direction);
+        return this->onFilterBounds(bounds, ctm, direction);
     } else {
-        SkIRect temp;
-        if (!this->onFilterBounds(src, ctm, &bounds, direction)) {
-            return false;
-        }
-        this->onFilterNodeBounds(bounds, ctm, &temp, direction);
-        this->getCropRect().applyTo(temp, ctm, dst);
-        return true;
+        SkIRect bounds = this->onFilterBounds(src, ctm, direction);
+        bounds = this->onFilterNodeBounds(bounds, ctm, direction);
+        SkIRect dst;
+        this->getCropRect().applyTo(bounds, ctm, &dst);
+        return dst;
     }
 }
 
-void SkImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
+SkRect SkImageFilter::computeFastBounds(const SkRect& src) const {
     if (0 == fInputCount) {
-        *dst = src;
-        return;
-    }
-    // We can't work directly on dst, since src and dst may alias.
-    SkRect combinedBounds;
-    if (this->getInput(0)) {
-        this->getInput(0)->computeFastBounds(src, &combinedBounds);
-    } else {
-        combinedBounds = src;
+        return src;
     }
+    SkRect combinedBounds = this->getInput(0) ? this->getInput(0)->computeFastBounds(src) : src;
     for (int i = 1; i < fInputCount; i++) {
         SkImageFilter* input = this->getInput(i);
         if (input) {
-            SkRect bounds;
-            input->computeFastBounds(src, &bounds);
-            combinedBounds.join(bounds);
+            combinedBounds.join(input->computeFastBounds(src));
         } else {
             combinedBounds.join(src);
         }
     }
-    *dst = combinedBounds;
+    return combinedBounds;
 }
 
 bool SkImageFilter::canComputeFastBounds() const {
@@ -442,8 +437,8 @@ bool SkImageFilter::asAColorFilter(SkColorFilter** filterPtr) const {
 
 bool SkImageFilter::applyCropRect(const Context& ctx, const SkIRect& srcBounds,
                                   SkIRect* dstBounds) const {
-    this->onFilterNodeBounds(srcBounds, ctx.ctm(), dstBounds, kForward_MapDirection);
-    fCropRect.applyTo(*dstBounds, ctx.ctm(), dstBounds);
+    SkIRect temp = this->onFilterNodeBounds(srcBounds, ctx.ctm(), kForward_MapDirection);
+    fCropRect.applyTo(temp, ctx.ctm(), dstBounds);
     // Intersect against the clip bounds, in case the crop rect has
     // grown the bounds beyond the original clip. This can happen for
     // example in tiling, where the clip is much smaller than the filtered
@@ -458,8 +453,7 @@ bool SkImageFilter::applyCropRectDeprecated(const Context& ctx, Proxy* proxy, co
     SkIRect srcBounds;
     src.getBounds(&srcBounds);
     srcBounds.offset(*srcOffset);
-    SkIRect dstBounds;
-    this->onFilterNodeBounds(srcBounds, ctx.ctm(), &dstBounds, kForward_MapDirection);
+    SkIRect dstBounds = this->onFilterNodeBounds(srcBounds, ctx.ctm(), kForward_MapDirection);
     fCropRect.applyTo(dstBounds, ctx.ctm(), bounds);
     if (!bounds->intersect(ctx.clipBounds())) {
         return false;
@@ -510,8 +504,7 @@ SkSpecialImage* SkImageFilter::applyCropRect(const Context& ctx,
     SkIRect srcBounds;
     srcBounds = SkIRect::MakeXYWH(srcOffset->fX, srcOffset->fY, src->width(), src->height());
 
-    SkIRect dstBounds;
-    this->onFilterNodeBounds(srcBounds, ctx.ctm(), &dstBounds, kForward_MapDirection);
+    SkIRect dstBounds = this->onFilterNodeBounds(srcBounds, ctx.ctm(), kForward_MapDirection);
     fCropRect.applyTo(dstBounds, ctx.ctm(), bounds);
     if (!bounds->intersect(ctx.clipBounds())) {
         return nullptr;
@@ -529,20 +522,16 @@ SkSpecialImage* SkImageFilter::applyCropRect(const Context& ctx,
     }
 }
 
-bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
-                                   SkIRect* dst, MapDirection direction) const {
+SkIRect SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
+                                      MapDirection direction) const {
     if (fInputCount < 1) {
-        *dst = src;
-        return true;
+        return src;
     }
 
     SkIRect totalBounds;
     for (int i = 0; i < fInputCount; ++i) {
         SkImageFilter* filter = this->getInput(i);
-        SkIRect rect = src;
-        if (filter && !filter->filterBounds(src, ctm, &rect, direction)) {
-            return false;
-        }
+        SkIRect rect = filter ? filter->filterBounds(src, ctm, direction) : src;
         if (0 == i) {
             totalBounds = rect;
         } else {
@@ -550,22 +539,17 @@ bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
         }
     }
 
-    // don't modify dst until now, so we don't accidentally change it in the
-    // loop, but then return false on the next filter.
-    *dst = totalBounds;
-    return true;
+    return totalBounds;
 }
 
-void SkImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix&,
-                                       SkIRect* dst, MapDirection) const {
-    *dst = src;
+SkIRect SkImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix&, MapDirection) const {
+    return src;
 }
 
 
 SkImageFilter::Context SkImageFilter::mapContext(const Context& ctx) const {
-    SkIRect clipBounds;
-    this->onFilterNodeBounds(ctx.clipBounds(), ctx.ctm(), &clipBounds,
-                             MapDirection::kReverse_MapDirection);
+    SkIRect clipBounds = this->onFilterNodeBounds(ctx.clipBounds(), ctx.ctm(),
+                                                  MapDirection::kReverse_MapDirection);
     return Context(ctx.ctm(), clipBounds, ctx.cache());
 }
 
index 4a9dea3..3214d2d 100644 (file)
@@ -45,9 +45,9 @@ bool SkLocalMatrixImageFilter::onFilterImageDeprecated(Proxy* proxy, const SkBit
     return this->filterInputDeprecated(0, proxy, src, localCtx, result, offset);
 }
 
-bool SkLocalMatrixImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& matrix,
-                                              SkIRect* dst, MapDirection direction) const {
-    return this->getInput(0)->filterBounds(src, SkMatrix::Concat(matrix, fLocalM), dst, direction);
+SkIRect SkLocalMatrixImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& matrix,
+                                                 MapDirection direction) const {
+    return this->getInput(0)->filterBounds(src, SkMatrix::Concat(matrix, fLocalM), direction);
 }
 
 #ifndef SK_IGNORE_TO_STRING
index f2fd062..da49df4 100644 (file)
@@ -27,8 +27,7 @@ protected:
     void flatten(SkWriteBuffer&) const override;
     bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&,
                                  SkBitmap* result, SkIPoint* offset) const override;
-    bool onFilterBounds(const SkIRect& src, const SkMatrix&, SkIRect* dst,
-                        MapDirection) const override;
+    SkIRect onFilterBounds(const SkIRect& src, const SkMatrix&, MapDirection) const override;
 
 private:
     SkLocalMatrixImageFilter(const SkMatrix& localM, SkImageFilter* input);
index 5a585ef..ec221fd 100644 (file)
@@ -91,36 +91,32 @@ bool SkMatrixImageFilter::onFilterImageDeprecated(Proxy* proxy,
     return true;
 }
 
-void SkMatrixImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
-    SkRect bounds = src;
-    if (getInput(0)) {
-        getInput(0)->computeFastBounds(src, &bounds);
-    }
-    fTransform.mapRect(dst, bounds);
+SkRect SkMatrixImageFilter::computeFastBounds(const SkRect& src) const {
+    SkRect bounds = this->getInput(0) ? this->getInput(0)->computeFastBounds(src) : src;
+    SkRect dst;
+    fTransform.mapRect(&dst, bounds);
+    return dst;
 }
 
-void SkMatrixImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
-                                             SkIRect* dst, MapDirection direction) const {
+SkIRect SkMatrixImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
+                                                MapDirection direction) const {
     SkMatrix matrix;
     if (!ctm.invert(&matrix)) {
-        *dst = src;
-        return;
+        return src;
     }
     if (kForward_MapDirection == direction) {
         matrix.postConcat(fTransform);
     } else {
         SkMatrix transformInverse;
         if (!fTransform.invert(&transformInverse)) {
-            *dst = src;
-            return;
+            return src;
         }
         matrix.postConcat(transformInverse);
     }
     matrix.postConcat(ctm);
     SkRect floatBounds;
     matrix.mapRect(&floatBounds, SkRect::Make(src));
-    SkIRect bounds = floatBounds.roundOut();
-    *dst = bounds;
+    return floatBounds.roundOut();
 }
 
 #ifndef SK_IGNORE_TO_STRING
index 4d5b52d..0631a8b 100644 (file)
@@ -33,7 +33,7 @@ public:
                                        SkImageFilter* input = nullptr);
     virtual ~SkMatrixImageFilter();
 
-    void computeFastBounds(const SkRect&, SkRect*) const override;
+    SkRect computeFastBounds(const SkRect&) const override;
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMatrixImageFilter)
@@ -46,8 +46,7 @@ protected:
 
     bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&,
                                  SkBitmap* result, SkIPoint* loc) const override;
-    void onFilterNodeBounds(const SkIRect& src, const SkMatrix&,
-                            SkIRect* dst, MapDirection) const override;
+    SkIRect onFilterNodeBounds(const SkIRect& src, const SkMatrix&, MapDirection) const override;
 
 private:
     SkMatrix              fTransform;
index 5baabd3..19bdcaf 100644 (file)
@@ -2044,7 +2044,7 @@ const SkRect& SkPaint::doComputeFastBounds(const SkRect& origSrc,
     }
 
     if (this->getImageFilter()) {
-        this->getImageFilter()->computeFastBounds(*storage, storage);
+        *storage = this->getImageFilter()->computeFastBounds(*storage);
     }
 
     return *storage;
index 249e697..8046706 100644 (file)
@@ -179,23 +179,18 @@ bool SkBlurImageFilter::onFilterImageDeprecated(Proxy* proxy,
 }
 
 
-void SkBlurImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
-    if (this->getInput(0)) {
-        this->getInput(0)->computeFastBounds(src, dst);
-    } else {
-        *dst = src;
-    }
-
-    dst->outset(SkScalarMul(fSigma.width(), SkIntToScalar(3)),
-                SkScalarMul(fSigma.height(), SkIntToScalar(3)));
+SkRect SkBlurImageFilter::computeFastBounds(const SkRect& src) const {
+    SkRect bounds = this->getInput(0) ? this->getInput(0)->computeFastBounds(src) : src;
+    bounds.outset(SkScalarMul(fSigma.width(), SkIntToScalar(3)),
+                  SkScalarMul(fSigma.height(), SkIntToScalar(3)));
+    return bounds;
 }
 
-void SkBlurImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
-                                           SkIRect* dst, MapDirection) const {
-    *dst = src;
+SkIRect SkBlurImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
+                                              MapDirection) const {
     SkVector sigma = map_sigma(fSigma, ctm);
-    dst->outset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))),
-                SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3))));
+    return src.makeOutset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))),
+                          SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3))));
 }
 
 bool SkBlurImageFilter::filterImageGPUDeprecated(Proxy* proxy, const SkBitmap& src,
index b921661..86a4d50 100644 (file)
 #include "SkWriteBuffer.h"
 
 
-void SkComposeImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
+SkRect SkComposeImageFilter::computeFastBounds(const SkRect& src) const {
     SkImageFilter* outer = getInput(0);
     SkImageFilter* inner = getInput(1);
 
-    SkRect tmp;
-    inner->computeFastBounds(src, &tmp);
-    outer->computeFastBounds(tmp, dst);
+    return outer->computeFastBounds(inner->computeFastBounds(src));
 }
 
 SkSpecialImage* SkComposeImageFilter::onFilterImage(SkSpecialImage* source, const Context& ctx,
@@ -27,7 +25,7 @@ SkSpecialImage* SkComposeImageFilter::onFilterImage(SkSpecialImage* source, cons
     // filter, so that the inner filter produces the pixels that the outer
     // filter requires as input. This matters if the outer filter moves pixels.
     SkIRect innerClipBounds;
-    getInput(0)->filterBounds(ctx.clipBounds(), ctx.ctm(), &innerClipBounds);
+    innerClipBounds = getInput(0)->filterBounds(ctx.clipBounds(), ctx.ctm());
     Context innerContext(ctx.ctm(), innerClipBounds, ctx.cache());
     SkIPoint innerOffset = SkIPoint::Make(0, 0);
     SkAutoTUnref<SkSpecialImage> inner(this->filterInput(1, source, innerContext, &innerOffset));
@@ -51,16 +49,12 @@ SkSpecialImage* SkComposeImageFilter::onFilterImage(SkSpecialImage* source, cons
     return outer.release();
 }
 
-bool SkComposeImageFilter::onFilterBounds(const SkIRect& src,
-                                          const SkMatrix& ctm,
-                                          SkIRect* dst,
-                                          MapDirection direction) const {
+SkIRect SkComposeImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
+                                             MapDirection direction) const {
     SkImageFilter* outer = this->getInput(0);
     SkImageFilter* inner = this->getInput(1);
 
-    SkIRect tmp;
-    return inner->filterBounds(src, ctm, &tmp, direction) &&
-           outer->filterBounds(tmp, ctm, dst, direction);
+    return outer->filterBounds(inner->filterBounds(src, ctm, direction), ctm, direction);
 }
 
 SkFlattenable* SkComposeImageFilter::CreateProc(SkReadBuffer& buffer) {
index 7940203..ab4767c 100644 (file)
@@ -265,32 +265,27 @@ bool SkDisplacementMapEffect::onFilterImageDeprecated(Proxy* proxy,
     return true;
 }
 
-void SkDisplacementMapEffect::computeFastBounds(const SkRect& src, SkRect* dst) const {
-    if (this->getColorInput()) {
-        this->getColorInput()->computeFastBounds(src, dst);
-    } else {
-        *dst = src;
-    }
-    dst->outset(SkScalarAbs(fScale) * SK_ScalarHalf, SkScalarAbs(fScale) * SK_ScalarHalf);
+SkRect SkDisplacementMapEffect::computeFastBounds(const SkRect& src) const {
+    SkRect bounds = this->getColorInput() ? this->getColorInput()->computeFastBounds(src) : src;
+    bounds.outset(SkScalarAbs(fScale) * SK_ScalarHalf, SkScalarAbs(fScale) * SK_ScalarHalf);
+    return bounds;
 }
 
-void SkDisplacementMapEffect::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
-                                   SkIRect* dst, MapDirection) const {
-    *dst = src;
+SkIRect SkDisplacementMapEffect::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
+                                                    MapDirection) const {
     SkVector scale = SkVector::Make(fScale, fScale);
     ctm.mapVectors(&scale, 1);
-    dst->outset(SkScalarCeilToInt(SkScalarAbs(scale.fX) * SK_ScalarHalf),
-                SkScalarCeilToInt(SkScalarAbs(scale.fY) * SK_ScalarHalf));
+    return src.makeOutset(SkScalarCeilToInt(SkScalarAbs(scale.fX) * SK_ScalarHalf),
+                          SkScalarCeilToInt(SkScalarAbs(scale.fY) * SK_ScalarHalf));
 }
 
-bool SkDisplacementMapEffect::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
-                                             SkIRect* dst, MapDirection direction) const {
+SkIRect SkDisplacementMapEffect::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
+                                                MapDirection direction) const {
     // Recurse only into color input.
     if (this->getColorInput()) {
-        return this->getColorInput()->filterBounds(src, ctm, dst, direction);
+        return this->getColorInput()->filterBounds(src, ctm, direction);
     }
-    *dst = src;
-    return true;
+    return src;
 }
 
 #ifndef SK_IGNORE_TO_STRING
index e2e72c1..deece35 100644 (file)
@@ -99,41 +99,37 @@ bool SkDropShadowImageFilter::onFilterImageDeprecated(Proxy* proxy, const SkBitm
     return true;
 }
 
-void SkDropShadowImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
-    if (getInput(0)) {
-        getInput(0)->computeFastBounds(src, dst);
-    } else {
-        *dst = src;
-    }
-
-    SkRect shadowBounds = *dst;
+SkRect SkDropShadowImageFilter::computeFastBounds(const SkRect& src) const {
+    SkRect bounds = this->getInput(0) ? this->getInput(0)->computeFastBounds(src) : src;
+    SkRect shadowBounds = bounds;
     shadowBounds.offset(fDx, fDy);
     shadowBounds.outset(SkScalarMul(fSigmaX, SkIntToScalar(3)),
                         SkScalarMul(fSigmaY, SkIntToScalar(3)));
     if (fShadowMode == kDrawShadowAndForeground_ShadowMode) {
-        dst->join(shadowBounds);
+        bounds.join(shadowBounds);
     } else {
-        *dst = shadowBounds;
+        bounds = shadowBounds;
     }
+    return bounds;
 }
 
-void SkDropShadowImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
-                                                 SkIRect* dst, MapDirection direction) const {
-    *dst = src;
+SkIRect SkDropShadowImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
+                                                    MapDirection direction) const {
     SkVector offsetVec = SkVector::Make(fDx, fDy);
     if (kReverse_MapDirection == direction) {
         offsetVec.negate();
     }
     ctm.mapVectors(&offsetVec, 1);
-    dst->offset(SkScalarCeilToInt(offsetVec.x()),
-                SkScalarCeilToInt(offsetVec.y()));
+    SkIRect dst = src.makeOffset(SkScalarCeilToInt(offsetVec.x()),
+                                 SkScalarCeilToInt(offsetVec.y()));
     SkVector sigma = SkVector::Make(fSigmaX, fSigmaY);
     ctm.mapVectors(&sigma, 1);
-    dst->outset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))),
+    dst.outset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))),
                 SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3))));
     if (fShadowMode == kDrawShadowAndForeground_ShadowMode) {
-        dst->join(src);
+        dst.join(src);
     }
+    return dst;
 }
 
 #ifndef SK_IGNORE_TO_STRING
index c0a8dee..d63eda9 100644 (file)
@@ -113,8 +113,8 @@ SkSpecialImage* SkImageSource::onFilterImage(SkSpecialImage* source, const Conte
     return surf->makeImageSnapshot().release();
 }
 
-void SkImageSource::computeFastBounds(const SkRect& src, SkRect* dst) const {
-    *dst = fDstRect;
+SkRect SkImageSource::computeFastBounds(const SkRect& src) const {
+    return fDstRect;
 }
 
 #ifndef SK_IGNORE_TO_STRING
index 0d14caf..7a25f5f 100644 (file)
@@ -323,17 +323,18 @@ bool SkMatrixConvolutionImageFilter::onFilterImageDeprecated(Proxy* proxy,
     return true;
 }
 
-void SkMatrixConvolutionImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
-                                                    SkIRect* dst, MapDirection direction) const {
-    *dst = src;
+SkIRect SkMatrixConvolutionImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
+                                                           MapDirection direction) const {
+    SkIRect dst = src;
     int w = fKernelSize.width() - 1, h = fKernelSize.height() - 1;
-    dst->fRight += w;
-    dst->fBottom += h;
+    dst.fRight += w;
+    dst.fBottom += h;
     if (kReverse_MapDirection == direction) {
-        dst->offset(-fKernelOffset);
+        dst.offset(-fKernelOffset);
     } else {
-        dst->offset(fKernelOffset - SkIPoint::Make(w, h));
+        dst.offset(fKernelOffset - SkIPoint::Make(w, h));
     }
+    return dst;
 }
 
 bool SkMatrixConvolutionImageFilter::canComputeFastBounds() const {
index 61b0c33..204f4f3 100644 (file)
@@ -142,22 +142,18 @@ bool SkDilateImageFilter::onFilterImageDeprecated(Proxy* proxy,
                                     proxy, source, ctx, dst, offset);
 }
 
-void SkMorphologyImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
-    if (this->getInput(0)) {
-        this->getInput(0)->computeFastBounds(src, dst);
-    } else {
-        *dst = src;
-    }
-    dst->outset(SkIntToScalar(fRadius.width()), SkIntToScalar(fRadius.height()));
+SkRect SkMorphologyImageFilter::computeFastBounds(const SkRect& src) const {
+    SkRect bounds = this->getInput(0) ? this->getInput(0)->computeFastBounds(src) : src;
+    bounds.outset(SkIntToScalar(fRadius.width()), SkIntToScalar(fRadius.height()));
+    return bounds;
 }
 
-void SkMorphologyImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
-                                                 SkIRect* dst, MapDirection) const {
-    *dst = src;
+SkIRect SkMorphologyImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
+                                                    MapDirection) const {
     SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()),
                                      SkIntToScalar(this->radius().height()));
     ctm.mapVectors(&radius, 1);
-    dst->outset(SkScalarCeilToInt(radius.x()), SkScalarCeilToInt(radius.y()));
+    return src.makeOutset(SkScalarCeilToInt(radius.x()), SkScalarCeilToInt(radius.y()));
 }
 
 SkFlattenable* SkErodeImageFilter::CreateProc(SkReadBuffer& buffer) {
index f3d2bb0..8e4b878 100644 (file)
@@ -65,25 +65,21 @@ SkSpecialImage* SkOffsetImageFilter::onFilterImage(SkSpecialImage* source,
     }
 }
 
-void SkOffsetImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
-    if (getInput(0)) {
-        getInput(0)->computeFastBounds(src, dst);
-    } else {
-        *dst = src;
-    }
-    dst->offset(fOffset.fX, fOffset.fY);
+SkRect SkOffsetImageFilter::computeFastBounds(const SkRect& src) const {
+    SkRect bounds = this->getInput(0) ? this->getInput(0)->computeFastBounds(src) : src;
+    bounds.offset(fOffset.fX, fOffset.fY);
+    return bounds;
 }
 
-void SkOffsetImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
-                                             SkIRect* dst, MapDirection direction) const {
+SkIRect SkOffsetImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
+                                                MapDirection direction) const {
     SkVector vec;
     ctm.mapVectors(&vec, &fOffset, 1);
     if (kReverse_MapDirection == direction) {
         vec.negate();
     }
 
-    *dst = src;
-    dst->offset(SkScalarCeilToInt(vec.fX), SkScalarCeilToInt(vec.fY));
+    return src.makeOffset(SkScalarCeilToInt(vec.fX), SkScalarCeilToInt(vec.fY));
 }
 
 SkFlattenable* SkOffsetImageFilter::CreateProc(SkReadBuffer& buffer) {
index dff8e9b..e6b561d 100644 (file)
@@ -106,22 +106,20 @@ bool SkTileImageFilter::onFilterImageDeprecated(Proxy* proxy, const SkBitmap& sr
     return true;
 }
 
-void SkTileImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
-                                          SkIRect* dst, MapDirection direction) const {
+SkIRect SkTileImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
+                                              MapDirection direction) const {
     SkRect rect = kReverse_MapDirection == direction ? fSrcRect : fDstRect;
     ctm.mapRect(&rect);
-    rect.roundOut(dst);
+    return rect.roundOut();
 }
 
-bool SkTileImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
-                                       SkIRect* dst, MapDirection direction) const {
+SkIRect SkTileImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix&, MapDirection) const {
     // Don't recurse into inputs.
-    *dst = src;
-    return true;
+    return src;
 }
 
-void SkTileImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
-    *dst = fDstRect;
+SkRect SkTileImageFilter::computeFastBounds(const SkRect& src) const {
+    return fDstRect;
 }
 
 SkFlattenable* SkTileImageFilter::CreateProc(SkReadBuffer& buffer) {
index 0fef0ef..5638d8a 100644 (file)
@@ -93,7 +93,7 @@ static bool compute_source_rect(const SkLayerInfo::BlockInfo& info, const SkMatr
     totMat.preConcat(info.fLocalMat);
 
     if (info.fPaint && info.fPaint->getImageFilter()) {
-        info.fPaint->getImageFilter()->filterBounds(clipBounds, totMat, &clipBounds);
+        clipBounds = info.fPaint->getImageFilter()->filterBounds(clipBounds, totMat);
     }
 
     if (!info.fSrcBounds.isEmpty()) {
index b9b0028..fd916cf 100644 (file)
@@ -756,7 +756,7 @@ DEF_TEST(ImageFilterBlurThenShadowBounds, reporter) {
 
     SkIRect bounds = SkIRect::MakeXYWH(0, 0, 100, 100);
     SkIRect expectedBounds = SkIRect::MakeXYWH(-133, -133, 236, 236);
-    filter2->filterBounds(bounds, SkMatrix::I(), &bounds);
+    bounds = filter2->filterBounds(bounds, SkMatrix::I());
 
     REPORTER_ASSERT(reporter, bounds == expectedBounds);
 }
@@ -767,7 +767,7 @@ DEF_TEST(ImageFilterShadowThenBlurBounds, reporter) {
 
     SkIRect bounds = SkIRect::MakeXYWH(0, 0, 100, 100);
     SkIRect expectedBounds = SkIRect::MakeXYWH(-133, -133, 236, 236);
-    filter2->filterBounds(bounds, SkMatrix::I(), &bounds);
+    bounds = filter2->filterBounds(bounds, SkMatrix::I());
 
     REPORTER_ASSERT(reporter, bounds == expectedBounds);
 }
@@ -778,7 +778,7 @@ DEF_TEST(ImageFilterDilateThenBlurBounds, reporter) {
 
     SkIRect bounds = SkIRect::MakeXYWH(0, 0, 100, 100);
     SkIRect expectedBounds = SkIRect::MakeXYWH(-132, -132, 234, 234);
-    filter2->filterBounds(bounds, SkMatrix::I(), &bounds);
+    bounds = filter2->filterBounds(bounds, SkMatrix::I());
 
     REPORTER_ASSERT(reporter, bounds == expectedBounds);
 }
@@ -791,8 +791,7 @@ DEF_TEST(ImageFilterComposedBlurFastBounds, reporter) {
     SkRect boundsSrc = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100));
     SkRect expectedBounds = SkRect::MakeXYWH(
         SkIntToScalar(-6), SkIntToScalar(-6), SkIntToScalar(112), SkIntToScalar(112));
-    SkRect boundsDst = SkRect::MakeEmpty();
-    composedFilter->computeFastBounds(boundsSrc, &boundsDst);
+    SkRect boundsDst = composedFilter->computeFastBounds(boundsSrc);
 
     REPORTER_ASSERT(reporter, boundsDst == expectedBounds);
 }
@@ -806,7 +805,7 @@ DEF_TEST(ImageFilterUnionBounds, reporter) {
             nullptr, offset.get(), nullptr));
         SkRect bounds = SkRect::MakeWH(100, 100);
         // Intentionally aliasing here, as that's what the real callers do.
-        composite->computeFastBounds(bounds, &bounds);
+        bounds = composite->computeFastBounds(bounds);
         REPORTER_ASSERT(reporter, bounds == SkRect::MakeWH(150, 100));
     }
     {
@@ -814,7 +813,7 @@ DEF_TEST(ImageFilterUnionBounds, reporter) {
             nullptr, nullptr, offset.get()));
         SkRect bounds = SkRect::MakeWH(100, 100);
         // Intentionally aliasing here, as that's what the real callers do.
-        composite->computeFastBounds(bounds, &bounds);
+        bounds = composite->computeFastBounds(bounds);
         REPORTER_ASSERT(reporter, bounds == SkRect::MakeWH(150, 100));
     }
 }