Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Unified Diff: src/core/SkImageFilter.cpp

Issue 1612953004: Image filters: Make a recursive, forward-mapping bounds traversal. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Update to ToT Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/effects/SkTileImageFilter.h ('k') | src/core/SkLocalMatrixImageFilter.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkImageFilter.cpp
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index 821edc0e1abbd6af85e2b9f41a6e28a5a27ef4de..9fca5cf6c9d65ddc7580fffa13252b8328fe3fc3 100644
--- a/src/core/SkImageFilter.cpp
+++ b/src/core/SkImageFilter.cpp
@@ -66,12 +66,13 @@ void SkImageFilter::CropRect::toString(SkString* str) const {
}
#endif
-bool SkImageFilter::CropRect::applyTo(const SkIRect& imageBounds, const Context& ctx,
+void SkImageFilter::CropRect::applyTo(const SkIRect& imageBounds,
+ const SkMatrix& ctm,
SkIRect* cropped) const {
*cropped = imageBounds;
if (fFlags) {
SkRect devCropR;
- ctx.ctm().mapRect(&devCropR, fRect);
+ ctm.mapRect(&devCropR, fRect);
const SkIRect devICropR = devCropR.roundOut();
// Compute the left/top first, in case we have to read them to compute right/bottom
@@ -88,12 +89,6 @@ bool SkImageFilter::CropRect::applyTo(const SkIRect& imageBounds, const Context&
cropped->fBottom = cropped->fTop + devICropR.height();
}
}
- // 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
- // primitive. If we didn't do this, we would be processing the filter
- // at the full crop rect size in every tile.
- return cropped->intersect(ctx.clipBounds());
}
///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -274,9 +269,22 @@ bool SkImageFilter::filterInput(int index, Proxy* proxy, const SkBitmap& src,
return input->filterImage(proxy, src, this->mapContext(ctx), result, offset);
}
-bool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const {
+bool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst,
+ MapDirection direction) const {
SkASSERT(dst);
- return this->onFilterBounds(src, ctm, dst);
+ SkIRect bounds;
+ if (kReverse_MapDirection == direction) {
+ this->onFilterNodeBounds(src, ctm, &bounds, direction);
+ return this->onFilterBounds(bounds, ctm, dst, 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;
+ }
}
void SkImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
@@ -396,7 +404,13 @@ bool SkImageFilter::applyCropRect(const Context& ctx, const SkBitmap& src,
src.getBounds(srcBounds);
srcBounds->offset(srcOffset);
this->onFilterNodeBounds(*srcBounds, ctx.ctm(), dstBounds, kForward_MapDirection);
- return fCropRect.applyTo(*dstBounds, ctx, dstBounds);
+ fCropRect.applyTo(*dstBounds, 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
+ // primitive. If we didn't do this, we would be processing the filter
+ // at the full crop rect size in every tile.
+ return dstBounds->intersect(ctx.clipBounds());
}
bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitmap& src,
@@ -406,7 +420,8 @@ bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitm
srcBounds.offset(*srcOffset);
SkIRect dstBounds;
this->onFilterNodeBounds(srcBounds, ctx.ctm(), &dstBounds, kForward_MapDirection);
- if (!fCropRect.applyTo(dstBounds, ctx, bounds)) {
+ fCropRect.applyTo(dstBounds, ctx.ctm(), bounds);
+ if (!bounds->intersect(ctx.clipBounds())) {
return false;
}
@@ -428,18 +443,17 @@ bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitm
}
bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
- SkIRect* dst) const {
+ SkIRect* dst, MapDirection direction) const {
if (fInputCount < 1) {
*dst = src;
return true;
}
- SkIRect bounds, totalBounds;
- this->onFilterNodeBounds(src, ctm, &bounds, kReverse_MapDirection);
+ SkIRect totalBounds;
for (int i = 0; i < fInputCount; ++i) {
SkImageFilter* filter = this->getInput(i);
- SkIRect rect = bounds;
- if (filter && !filter->filterBounds(bounds, ctm, &rect)) {
+ SkIRect rect = src;
+ if (filter && !filter->filterBounds(src, ctm, &rect, direction)) {
return false;
}
if (0 == i) {
« no previous file with comments | « include/effects/SkTileImageFilter.h ('k') | src/core/SkLocalMatrixImageFilter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698