aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkMatrixImageFilter.cpp
diff options
context:
space:
mode:
authorGravatar senorblanco <senorblanco@chromium.org>2015-12-09 10:11:43 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-12-09 10:11:43 -0800
commitdb64af3b178a19ecb47d2b9a373113687d8921fd (patch)
treeb63e1f0102ee216ea4f642b9a9d5dc7eb66753f6 /src/core/SkMatrixImageFilter.cpp
parent02046c50b294ae2b28e562b0e6e281e4ef823352 (diff)
Fix filter primitive bounds computations.
Make each filter responsible for expanding its destination bounds. Previously, we were using a union of all intermediate bounds sizes via join() calls in many image filters' computeFastBounds(), due to the fact that those filters could only produce bitmaps the same size as their inputs. Now, we compute optimal bounds for each filter as follows: 1) Pass the (unmodified) clip bounds to the root node of the DAG in the first recursive call to onFilterImage() as the Context's fClipBounds. 2) Reverse-map the clip: when recursing up the DAG in filterInput[GPU](), apply filter-specific expansion to the clip by calling calling onFilterNodeBounds(... kReverse). This allows upstream nodes to have a clip that respects the current node's requirements. This is done via helper function mapContext(). 3) Forward-map the source bitmap: just prior to applying the crop rect in applyCropRect(), we determine the filter's preferred bounds by mapping the source bitmap bounds forwards via onFilterNodeBounds(..., kForward). NOTE: GMs affected by this change: fast_slow_blurimagefilter: fast and slow paths now produce the same result spritebitmap: drawSprite() and drawBitmap() paths now produce the same result filterfastbounds: fast bounds are optimized; all drop-shadow results now appear apply-filter: snug and not-snug cases give same results dropshadowimagefilter: drawSprite() results now show shadows draw-with-filter: no artifacts on erode edges; blur edges no longer clipped displacement, imagefiltersbase, imagefiltersclipped, imagefilterscropexpand, imagefiltersscaled, matriximagefilter, resizeimagefilter, localmatriximagefilter, testimagefilters: fixed incorrect clipping imagefilterstransformed, morphology: no artifacts on erode edges BUG=skia:1062,skia:3194,skia:3939,skia:4337,skia:4526 Review URL: https://codereview.chromium.org/1308703007
Diffstat (limited to 'src/core/SkMatrixImageFilter.cpp')
-rw-r--r--src/core/SkMatrixImageFilter.cpp29
1 files changed, 16 insertions, 13 deletions
diff --git a/src/core/SkMatrixImageFilter.cpp b/src/core/SkMatrixImageFilter.cpp
index 4370ddadee..4138ccf677 100644
--- a/src/core/SkMatrixImageFilter.cpp
+++ b/src/core/SkMatrixImageFilter.cpp
@@ -97,30 +97,33 @@ void SkMatrixImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) cons
getInput(0)->computeFastBounds(src, &bounds);
}
fTransform.mapRect(dst, bounds);
+#ifdef SK_SUPPORT_SRC_BOUNDS_BLOAT_FOR_IMAGEFILTERS
dst->join(bounds); // Work around for skia:3194
+#endif
}
-bool SkMatrixImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
- SkIRect* dst) const {
- SkMatrix transformInverse;
- if (!fTransform.invert(&transformInverse)) {
- return false;
- }
+void SkMatrixImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
+ SkIRect* dst, MapDirection direction) const {
SkMatrix matrix;
if (!ctm.invert(&matrix)) {
- return false;
+ *dst = src;
+ return;
+ }
+ if (kForward_MapDirection == direction) {
+ matrix.postConcat(fTransform);
+ } else {
+ SkMatrix transformInverse;
+ if (!fTransform.invert(&transformInverse)) {
+ *dst = src;
+ return;
+ }
+ matrix.postConcat(transformInverse);
}
- matrix.postConcat(transformInverse);
matrix.postConcat(ctm);
SkRect floatBounds;
matrix.mapRect(&floatBounds, SkRect::Make(src));
SkIRect bounds = floatBounds.roundOut();
- if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) {
- return false;
- }
-
*dst = bounds;
- return true;
}
#ifndef SK_IGNORE_TO_STRING