aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/SkImageFilter.cpp63
-rw-r--r--src/effects/SkBlurImageFilter.cpp16
-rwxr-xr-xsrc/effects/SkColorFilterImageFilter.cpp4
-rw-r--r--src/effects/SkDisplacementMapEffect.cpp60
-rw-r--r--src/effects/SkDropShadowImageFilter.cpp7
-rw-r--r--src/effects/SkLightingImageFilter.cpp25
-rw-r--r--src/effects/SkMatrixConvolutionImageFilter.cpp4
-rwxr-xr-xsrc/effects/SkMergeImageFilter.cpp3
-rw-r--r--src/effects/SkMorphologyImageFilter.cpp8
-rw-r--r--src/effects/SkOffsetImageFilter.cpp5
-rw-r--r--src/effects/SkRectShaderImageFilter.cpp3
-rw-r--r--src/effects/SkXfermodeImageFilter.cpp11
12 files changed, 114 insertions, 95 deletions
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index 6613f09b93..2be66e787c 100644
--- a/src/core/SkImageFilter.cpp
+++ b/src/core/SkImageFilter.cpp
@@ -8,6 +8,7 @@
#include "SkImageFilter.h"
#include "SkBitmap.h"
+#include "SkDevice.h"
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"
#include "SkRect.h"
@@ -155,9 +156,7 @@ bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Cont
}
GrTexture* srcTexture = input.getTexture();
SkIRect bounds;
- src.getBounds(&bounds);
- bounds.offset(srcOffset);
- if (!this->applyCropRect(&bounds, ctx.ctm())) {
+ if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, &input)) {
return false;
}
SkRect srcRect = SkRect::Make(bounds);
@@ -196,18 +195,60 @@ bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Cont
#endif
}
-bool SkImageFilter::applyCropRect(SkIRect* rect, const SkMatrix& matrix) const {
+bool SkImageFilter::applyCropRect(const Context& ctx, const SkBitmap& src,
+ const SkIPoint& srcOffset, SkIRect* bounds) const {
+ SkIRect srcBounds;
+ src.getBounds(&srcBounds);
+ srcBounds.offset(srcOffset);
SkRect cropRect;
- matrix.mapRect(&cropRect, fCropRect.rect());
+ ctx.ctm().mapRect(&cropRect, fCropRect.rect());
SkIRect cropRectI;
cropRect.roundOut(&cropRectI);
uint32_t flags = fCropRect.flags();
- // If the original crop rect edges were unset, max out the new crop edges
- if (!(flags & CropRect::kHasLeft_CropEdge)) cropRectI.fLeft = SK_MinS32;
- if (!(flags & CropRect::kHasTop_CropEdge)) cropRectI.fTop = SK_MinS32;
- if (!(flags & CropRect::kHasRight_CropEdge)) cropRectI.fRight = SK_MaxS32;
- if (!(flags & CropRect::kHasBottom_CropEdge)) cropRectI.fBottom = SK_MaxS32;
- return rect->intersect(cropRectI);
+ if (flags & CropRect::kHasLeft_CropEdge) srcBounds.fLeft = cropRectI.fLeft;
+ if (flags & CropRect::kHasTop_CropEdge) srcBounds.fTop = cropRectI.fTop;
+ if (flags & CropRect::kHasRight_CropEdge) srcBounds.fRight = cropRectI.fRight;
+ if (flags & CropRect::kHasBottom_CropEdge) srcBounds.fBottom = cropRectI.fBottom;
+ if (!srcBounds.intersect(ctx.clipBounds())) {
+ return false;
+ }
+ *bounds = srcBounds;
+ return true;
+}
+
+bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitmap& src,
+ SkIPoint* srcOffset, SkIRect* bounds, SkBitmap* dst) const {
+ SkIRect srcBounds;
+ src.getBounds(&srcBounds);
+ srcBounds.offset(*srcOffset);
+ SkRect cropRect;
+ ctx.ctm().mapRect(&cropRect, fCropRect.rect());
+ SkIRect cropRectI;
+ cropRect.roundOut(&cropRectI);
+ uint32_t flags = fCropRect.flags();
+ *bounds = srcBounds;
+ if (flags & CropRect::kHasLeft_CropEdge) bounds->fLeft = cropRectI.fLeft;
+ if (flags & CropRect::kHasTop_CropEdge) bounds->fTop = cropRectI.fTop;
+ if (flags & CropRect::kHasRight_CropEdge) bounds->fRight = cropRectI.fRight;
+ if (flags & CropRect::kHasBottom_CropEdge) bounds->fBottom = cropRectI.fBottom;
+ if (!bounds->intersect(ctx.clipBounds())) {
+ return false;
+ }
+ if (srcBounds.contains(*bounds)) {
+ *dst = src;
+ return true;
+ } else {
+ SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds->width(), bounds->height()));
+ if (!device) {
+ return false;
+ }
+ SkCanvas canvas(device);
+ canvas.clear(0x00000000);
+ canvas.drawBitmap(src, srcOffset->x() - bounds->x(), srcOffset->y() - bounds->y());
+ *srcOffset = SkIPoint::Make(bounds->x(), bounds->y());
+ *dst = device->accessBitmap(false);
+ return true;
+ }
}
bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
diff --git a/src/effects/SkBlurImageFilter.cpp b/src/effects/SkBlurImageFilter.cpp
index adcb28f90d..ffebe54225 100644
--- a/src/effects/SkBlurImageFilter.cpp
+++ b/src/effects/SkBlurImageFilter.cpp
@@ -146,15 +146,13 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
return false;
}
- SkAutoLockPixels alp(src);
- if (!src.getPixels()) {
+ SkIRect srcBounds, dstBounds;
+ if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &srcBounds, &src)) {
return false;
}
- SkIRect srcBounds, dstBounds;
- src.getBounds(&srcBounds);
- srcBounds.offset(srcOffset);
- if (!this->applyCropRect(&srcBounds, ctx.ctm())) {
+ SkAutoLockPixels alp(src);
+ if (!src.getPixels()) {
return false;
}
@@ -258,13 +256,11 @@ bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const
if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffset)) {
return false;
}
- GrTexture* source = input.getTexture();
SkIRect rect;
- src.getBounds(&rect);
- rect.offset(srcOffset);
- if (!this->applyCropRect(&rect, ctx.ctm())) {
+ if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &rect, &input)) {
return false;
}
+ GrTexture* source = input.getTexture();
SkVector sigma, localSigma = SkVector::Make(fSigma.width(), fSigma.height());
ctx.ctm().mapVectors(&sigma, &localSigma, 1);
offset->fX = rect.fLeft;
diff --git a/src/effects/SkColorFilterImageFilter.cpp b/src/effects/SkColorFilterImageFilter.cpp
index 0de73301b1..8cdd546b99 100755
--- a/src/effects/SkColorFilterImageFilter.cpp
+++ b/src/effects/SkColorFilterImageFilter.cpp
@@ -109,9 +109,7 @@ bool SkColorFilterImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& sourc
}
SkIRect bounds;
- src.getBounds(&bounds);
- bounds.offset(srcOffset);
- if (!this->applyCropRect(&bounds, ctx.ctm())) {
+ if (!this->applyCropRect(ctx, src, srcOffset, &bounds)) {
return false;
}
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index a1c18c647e..4b26a5f846 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);
diff --git a/src/effects/SkDropShadowImageFilter.cpp b/src/effects/SkDropShadowImageFilter.cpp
index 94055ce8ae..40ab8cf641 100644
--- a/src/effects/SkDropShadowImageFilter.cpp
+++ b/src/effects/SkDropShadowImageFilter.cpp
@@ -66,9 +66,7 @@ bool SkDropShadowImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source
return false;
SkIRect bounds;
- src.getBounds(&bounds);
- bounds.offset(srcOffset);
- if (!this->applyCropRect(&bounds, ctx.ctm())) {
+ if (!this->applyCropRect(ctx, src, srcOffset, &bounds)) {
return false;
}
@@ -90,7 +88,8 @@ bool SkDropShadowImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source
paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
SkVector offsetVec, localOffsetVec = SkVector::Make(fDx, fDy);
ctx.ctm().mapVectors(&offsetVec, &localOffsetVec, 1);
- canvas.translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop));
+ canvas.translate(SkIntToScalar(srcOffset.fX - bounds.fLeft),
+ SkIntToScalar(srcOffset.fY - bounds.fTop));
canvas.drawBitmap(src, offsetVec.fX, offsetVec.fY, &paint);
canvas.drawBitmap(src, 0, 0);
*result = device->accessBitmap(false);
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index 206be1b62d..54bb1c890b 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -946,19 +946,17 @@ bool SkDiffuseLightingImageFilter::onFilterImage(Proxy* proxy,
if (src.colorType() != kPMColor_SkColorType) {
return false;
}
- SkAutoLockPixels alp(src);
- if (!src.getPixels()) {
+ SkIRect bounds;
+ if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) {
return false;
}
- SkIRect bounds;
- src.getBounds(&bounds);
- bounds.offset(srcOffset);
- if (!this->applyCropRect(&bounds, ctx.ctm())) {
+ if (bounds.width() < 2 || bounds.height() < 2) {
return false;
}
- if (bounds.width() < 2 || bounds.height() < 2) {
+ SkAutoLockPixels alp(src);
+ if (!src.getPixels()) {
return false;
}
@@ -1039,15 +1037,9 @@ bool SkSpecularLightingImageFilter::onFilterImage(Proxy* proxy,
if (src.colorType() != kPMColor_SkColorType) {
return false;
}
- SkAutoLockPixels alp(src);
- if (!src.getPixels()) {
- return false;
- }
SkIRect bounds;
- src.getBounds(&bounds);
- bounds.offset(srcOffset);
- if (!this->applyCropRect(&bounds, ctx.ctm())) {
+ if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) {
return false;
}
@@ -1055,6 +1047,11 @@ bool SkSpecularLightingImageFilter::onFilterImage(Proxy* proxy,
return false;
}
+ SkAutoLockPixels alp(src);
+ if (!src.getPixels()) {
+ return false;
+ }
+
dst->setConfig(src.config(), bounds.width(), bounds.height());
dst->allocPixels();
if (!dst->getPixels()) {
diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp
index 1df1ff9de0..7b9812ddbc 100644
--- a/src/effects/SkMatrixConvolutionImageFilter.cpp
+++ b/src/effects/SkMatrixConvolutionImageFilter.cpp
@@ -265,9 +265,7 @@ bool SkMatrixConvolutionImageFilter::onFilterImage(Proxy* proxy,
}
SkIRect bounds;
- src.getBounds(&bounds);
- bounds.offset(srcOffset);
- if (!this->applyCropRect(&bounds, ctx.ctm())) {
+ if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) {
return false;
}
diff --git a/src/effects/SkMergeImageFilter.cpp b/src/effects/SkMergeImageFilter.cpp
index ff36e5b068..adf9afe9b3 100755
--- a/src/effects/SkMergeImageFilter.cpp
+++ b/src/effects/SkMergeImageFilter.cpp
@@ -73,8 +73,7 @@ bool SkMergeImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src,
}
SkIRect bounds;
- src.getBounds(&bounds);
- if (!this->applyCropRect(&bounds, ctx.ctm())) {
+ if (!this->applyCropRect(ctx, src, SkIPoint::Make(0, 0), &bounds)) {
return false;
}
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 90940b9452..fb69758edd 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -154,9 +154,7 @@ bool SkMorphologyImageFilter::filterImageGeneric(SkMorphologyImageFilter::Proc p
}
SkIRect bounds;
- src.getBounds(&bounds);
- bounds.offset(srcOffset);
- if (!this->applyCropRect(&bounds, ctx.ctm())) {
+ if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) {
return false;
}
@@ -547,9 +545,7 @@ bool SkMorphologyImageFilter::filterImageGPUGeneric(bool dilate,
return false;
}
SkIRect bounds;
- input.getBounds(&bounds);
- bounds.offset(srcOffset);
- if (!this->applyCropRect(&bounds, ctx.ctm())) {
+ if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, &input)) {
return false;
}
SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()),
diff --git a/src/effects/SkOffsetImageFilter.cpp b/src/effects/SkOffsetImageFilter.cpp
index 98eb05bf1d..ae35a4ca2f 100644
--- a/src/effects/SkOffsetImageFilter.cpp
+++ b/src/effects/SkOffsetImageFilter.cpp
@@ -42,10 +42,7 @@ bool SkOffsetImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source,
}
SkIRect bounds;
- src.getBounds(&bounds);
- bounds.offset(srcOffset);
-
- if (!applyCropRect(&bounds, ctx.ctm())) {
+ if (!this->applyCropRect(ctx, src, srcOffset, &bounds)) {
return false;
}
diff --git a/src/effects/SkRectShaderImageFilter.cpp b/src/effects/SkRectShaderImageFilter.cpp
index dad0e02525..13e59c2c27 100644
--- a/src/effects/SkRectShaderImageFilter.cpp
+++ b/src/effects/SkRectShaderImageFilter.cpp
@@ -56,8 +56,7 @@ bool SkRectShaderImageFilter::onFilterImage(Proxy* proxy,
SkBitmap* result,
SkIPoint* offset) const {
SkIRect bounds;
- source.getBounds(&bounds);
- if (!this->applyCropRect(&bounds, ctx.ctm())) {
+ if (!this->applyCropRect(ctx, source, SkIPoint::Make(0, 0), &bounds)) {
return false;
}
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
index ebfd16c4db..901353fabe 100644
--- a/src/effects/SkXfermodeImageFilter.cpp
+++ b/src/effects/SkXfermodeImageFilter.cpp
@@ -62,14 +62,13 @@ bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy,
}
SkIRect bounds, foregroundBounds;
- background.getBounds(&bounds);
- bounds.offset(backgroundOffset);
- foreground.getBounds(&foregroundBounds);
- foregroundBounds.offset(foregroundOffset);
- bounds.join(foregroundBounds);
- if (!applyCropRect(&bounds, ctx.ctm())) {
+ if (!applyCropRect(ctx, foreground, foregroundOffset, &foregroundBounds)) {
+ return false;
+ }
+ if (!applyCropRect(ctx, background, backgroundOffset, &bounds)) {
return false;
}
+ bounds.join(foregroundBounds);
SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
if (NULL == device.get()) {