diff options
author | senorblanco <senorblanco@chromium.org> | 2015-12-09 10:11:43 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-09 10:11:43 -0800 |
commit | db64af3b178a19ecb47d2b9a373113687d8921fd (patch) | |
tree | b63e1f0102ee216ea4f642b9a9d5dc7eb66753f6 /src/core/SkMatrixImageFilter.cpp | |
parent | 02046c50b294ae2b28e562b0e6e281e4ef823352 (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.cpp | 29 |
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 |