Index: src/effects/SkDisplacementMapEffect.cpp |
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp |
index a1c18c647ef6c168b222ead68bf321a872e8cdee..4b26a5f846083f55de3e6707fcc9adf700ed9e7f 100644 |
--- a/src/effects/SkDisplacementMapEffect.cpp |
+++ b/src/effects/SkDisplacementMapEffect.cpp |
@@ -209,26 +209,23 @@ bool SkDisplacementMapEffect::onFilterImage(Proxy* proxy, |
(color.colorType() != kPMColor_SkColorType)) { |
return false; |
} |
- |
- SkAutoLockPixels alp_displacement(displ), alp_color(color); |
- if (!displ.getPixels() || !color.getPixels()) { |
- return false; |
- } |
SkIRect bounds; |
- color.getBounds(&bounds); |
- bounds.offset(colorOffset); |
- if (!this->applyCropRect(&bounds, ctx.ctm())) { |
+ // Since computeDisplacement does bounds checking on color pixel access, we don't need to pad |
+ // the color bitmap to bounds here. |
+ if (!this->applyCropRect(ctx, color, colorOffset, &bounds)) { |
return false; |
} |
SkIRect displBounds; |
- displ.getBounds(&displBounds); |
- displBounds.offset(displOffset); |
- if (!this->applyCropRect(&displBounds, ctx.ctm())) { |
+ if (!this->applyCropRect(ctx, proxy, displ, &displOffset, &displBounds, &displ)) { |
return false; |
} |
if (!bounds.intersect(displBounds)) { |
return false; |
} |
+ SkAutoLockPixels alp_displacement(displ), alp_color(color); |
+ if (!displ.getPixels() || !color.getPixels()) { |
+ return false; |
+ } |
dst->setConfig(color.config(), bounds.width(), bounds.height()); |
if (!dst->allocPixels()) { |
@@ -254,14 +251,18 @@ void SkDisplacementMapEffect::computeFastBounds(const SkRect& src, SkRect* dst) |
} else { |
*dst = src; |
} |
+ dst->outset(fScale * SK_ScalarHalf, fScale * SK_ScalarHalf); |
} |
bool SkDisplacementMapEffect::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, |
SkIRect* dst) const { |
- if (getColorInput()) { |
- return getColorInput()->filterBounds(src, ctm, dst); |
+ SkIRect bounds = src; |
+ if (getColorInput() && !getColorInput()->filterBounds(src, ctm, &bounds)) { |
+ return false; |
} |
- *dst = src; |
+ bounds.outset(SkScalarCeilToInt(fScale * SK_ScalarHalf), |
+ SkScalarCeilToInt(fScale * SK_ScalarHalf)); |
+ *dst = bounds; |
return true; |
} |
@@ -356,7 +357,6 @@ bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, |
&colorOffset)) { |
return false; |
} |
- GrTexture* color = colorBM.getTexture(); |
SkBitmap displacementBM = src; |
SkIPoint displacementOffset = SkIPoint::Make(0, 0); |
if (getDisplacementInput() && |
@@ -364,6 +364,21 @@ bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, |
&displacementOffset)) { |
return false; |
} |
+ SkIRect bounds; |
+ // Since GrDisplacementMapEffect does bounds checking on color pixel access, we don't need to |
+ // pad the color bitmap to bounds here. |
+ if (!this->applyCropRect(ctx, colorBM, colorOffset, &bounds)) { |
+ return false; |
+ } |
+ SkIRect displBounds; |
+ if (!this->applyCropRect(ctx, proxy, displacementBM, |
+ &displacementOffset, &displBounds, &displacementBM)) { |
+ return false; |
+ } |
+ if (!bounds.intersect(displBounds)) { |
+ return false; |
+ } |
+ GrTexture* color = colorBM.getTexture(); |
GrTexture* displacement = displacementBM.getTexture(); |
GrContext* context = color->getContext(); |
@@ -380,21 +395,6 @@ bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, |
SkVector scale = SkVector::Make(fScale, fScale); |
ctx.ctm().mapVectors(&scale, 1); |
- SkIRect bounds; |
- colorBM.getBounds(&bounds); |
- bounds.offset(colorOffset); |
- if (!this->applyCropRect(&bounds, ctx.ctm())) { |
- return false; |
- } |
- SkIRect displBounds; |
- displacementBM.getBounds(&displBounds); |
- displBounds.offset(displacementOffset); |
- if (!this->applyCropRect(&displBounds, ctx.ctm())) { |
- return false; |
- } |
- if (!bounds.intersect(displBounds)) { |
- return false; |
- } |
GrPaint paint; |
SkMatrix offsetMatrix = GrEffect::MakeDivByTextureWHMatrix(displacement); |