| Index: src/effects/SkBlurImageFilter.cpp
|
| diff --git a/src/effects/SkBlurImageFilter.cpp b/src/effects/SkBlurImageFilter.cpp
|
| index 157a0c333573cc44253343f2ec3ceabd1955b8ea..25383cda0688fec5e823a8e5172c1816d99bf02b 100644
|
| --- a/src/effects/SkBlurImageFilter.cpp
|
| +++ b/src/effects/SkBlurImageFilter.cpp
|
| @@ -21,8 +21,11 @@ SkBlurImageFilter::SkBlurImageFilter(SkFlattenableReadBuffer& buffer)
|
| fSigma.fHeight = buffer.readScalar();
|
| }
|
|
|
| -SkBlurImageFilter::SkBlurImageFilter(SkScalar sigmaX, SkScalar sigmaY, SkImageFilter* input)
|
| - : INHERITED(input), fSigma(SkSize::Make(sigmaX, sigmaY)) {
|
| +SkBlurImageFilter::SkBlurImageFilter(SkScalar sigmaX,
|
| + SkScalar sigmaY,
|
| + SkImageFilter* input,
|
| + const SkIRect* cropRect)
|
| + : INHERITED(input, cropRect), fSigma(SkSize::Make(sigmaX, sigmaY)) {
|
| SkASSERT(sigmaX >= 0 && sigmaY >= 0);
|
| }
|
|
|
| @@ -33,13 +36,13 @@ void SkBlurImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
|
| }
|
|
|
| static void boxBlurX(const SkBitmap& src, SkBitmap* dst, int kernelSize,
|
| - int leftOffset, int rightOffset)
|
| + int leftOffset, int rightOffset, const SkIRect& bounds)
|
| {
|
| - int width = src.width(), height = src.height();
|
| + int width = bounds.width(), height = bounds.height();
|
| int rightBorder = SkMin32(rightOffset + 1, width);
|
| for (int y = 0; y < height; ++y) {
|
| int sumA = 0, sumR = 0, sumG = 0, sumB = 0;
|
| - SkPMColor* p = src.getAddr32(0, y);
|
| + SkPMColor* p = src.getAddr32(bounds.fLeft, y + bounds.fTop);
|
| for (int i = 0; i < rightBorder; ++i) {
|
| sumA += SkGetPackedA32(*p);
|
| sumR += SkGetPackedR32(*p);
|
| @@ -48,7 +51,7 @@ static void boxBlurX(const SkBitmap& src, SkBitmap* dst, int kernelSize,
|
| p++;
|
| }
|
|
|
| - const SkColor* sptr = src.getAddr32(0, y);
|
| + const SkColor* sptr = src.getAddr32(bounds.fLeft, bounds.fTop + y);
|
| SkColor* dptr = dst->getAddr32(0, y);
|
| for (int x = 0; x < width; ++x) {
|
| *dptr = SkPackARGB32(sumA / kernelSize,
|
| @@ -76,15 +79,15 @@ static void boxBlurX(const SkBitmap& src, SkBitmap* dst, int kernelSize,
|
| }
|
|
|
| static void boxBlurY(const SkBitmap& src, SkBitmap* dst, int kernelSize,
|
| - int topOffset, int bottomOffset)
|
| + int topOffset, int bottomOffset, const SkIRect& bounds)
|
| {
|
| - int width = src.width(), height = src.height();
|
| + int width = bounds.width(), height = bounds.height();
|
| int bottomBorder = SkMin32(bottomOffset + 1, height);
|
| int srcStride = src.rowBytesAsPixels();
|
| int dstStride = dst->rowBytesAsPixels();
|
| for (int x = 0; x < width; ++x) {
|
| int sumA = 0, sumR = 0, sumG = 0, sumB = 0;
|
| - SkColor* p = src.getAddr32(x, 0);
|
| + SkColor* p = src.getAddr32(bounds.fLeft + x, bounds.fTop);
|
| for (int i = 0; i < bottomBorder; ++i) {
|
| sumA += SkGetPackedA32(*p);
|
| sumR += SkGetPackedR32(*p);
|
| @@ -93,7 +96,7 @@ static void boxBlurY(const SkBitmap& src, SkBitmap* dst, int kernelSize,
|
| p += srcStride;
|
| }
|
|
|
| - const SkColor* sptr = src.getAddr32(x, 0);
|
| + const SkColor* sptr = src.getAddr32(bounds.fLeft + x, bounds.fTop);
|
| SkColor* dptr = dst->getAddr32(x, 0);
|
| for (int y = 0; y < height; ++y) {
|
| *dptr = SkPackARGB32(sumA / kernelSize,
|
| @@ -153,7 +156,14 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
|
| return false;
|
| }
|
|
|
| - dst->setConfig(src.config(), src.width(), src.height());
|
| + SkIRect srcBounds, dstBounds;
|
| + src.getBounds(&srcBounds);
|
| + if (!this->applyCropRect(&srcBounds)) {
|
| + return false;
|
| + }
|
| +
|
| + dst->setConfig(src.config(), srcBounds.width(), srcBounds.height());
|
| + dst->getBounds(&dstBounds);
|
| dst->allocPixels();
|
| int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX;
|
| int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY;
|
| @@ -176,21 +186,23 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
|
| }
|
|
|
| if (kernelSizeX > 0 && kernelSizeY > 0) {
|
| - boxBlurX(src, &temp, kernelSizeX, lowOffsetX, highOffsetX);
|
| - boxBlurY(temp, dst, kernelSizeY, lowOffsetY, highOffsetY);
|
| - boxBlurX(*dst, &temp, kernelSizeX, highOffsetX, lowOffsetX);
|
| - boxBlurY(temp, dst, kernelSizeY, highOffsetY, lowOffsetY);
|
| - boxBlurX(*dst, &temp, kernelSizeX3, highOffsetX, highOffsetX);
|
| - boxBlurY(temp, dst, kernelSizeY3, highOffsetY, highOffsetY);
|
| + boxBlurX(src, &temp, kernelSizeX, lowOffsetX, highOffsetX, srcBounds);
|
| + boxBlurY(temp, dst, kernelSizeY, lowOffsetY, highOffsetY, dstBounds);
|
| + boxBlurX(*dst, &temp, kernelSizeX, highOffsetX, lowOffsetX, dstBounds);
|
| + boxBlurY(temp, dst, kernelSizeY, highOffsetY, lowOffsetY, dstBounds);
|
| + boxBlurX(*dst, &temp, kernelSizeX3, highOffsetX, highOffsetX, dstBounds);
|
| + boxBlurY(temp, dst, kernelSizeY3, highOffsetY, highOffsetY, dstBounds);
|
| } else if (kernelSizeX > 0) {
|
| - boxBlurX(src, dst, kernelSizeX, lowOffsetX, highOffsetX);
|
| - boxBlurX(*dst, &temp, kernelSizeX, highOffsetX, lowOffsetX);
|
| - boxBlurX(temp, dst, kernelSizeX3, highOffsetX, highOffsetX);
|
| + boxBlurX(src, dst, kernelSizeX, lowOffsetX, highOffsetX, srcBounds);
|
| + boxBlurX(*dst, &temp, kernelSizeX, highOffsetX, lowOffsetX, dstBounds);
|
| + boxBlurX(temp, dst, kernelSizeX3, highOffsetX, highOffsetX, dstBounds);
|
| } else if (kernelSizeY > 0) {
|
| - boxBlurY(src, dst, kernelSizeY, lowOffsetY, highOffsetY);
|
| - boxBlurY(*dst, &temp, kernelSizeY, highOffsetY, lowOffsetY);
|
| - boxBlurY(temp, dst, kernelSizeY3, highOffsetY, highOffsetY);
|
| + boxBlurY(src, dst, kernelSizeY, lowOffsetY, highOffsetY, srcBounds);
|
| + boxBlurY(*dst, &temp, kernelSizeY, highOffsetY, lowOffsetY, dstBounds);
|
| + boxBlurY(temp, dst, kernelSizeY3, highOffsetY, highOffsetY, dstBounds);
|
| }
|
| + offset->fX += srcBounds.fLeft;
|
| + offset->fY += srcBounds.fTop;
|
| return true;
|
| }
|
|
|
| @@ -202,12 +214,21 @@ bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, SkBitm
|
| return false;
|
| }
|
| GrTexture* source = input.getTexture();
|
| - SkRect rect;
|
| + SkIRect rect;
|
| src.getBounds(&rect);
|
| + if (!this->applyCropRect(&rect)) {
|
| + return false;
|
| + }
|
| SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(source->getContext(),
|
| - source, false, rect,
|
| - fSigma.width(), fSigma.height()));
|
| - return SkImageFilterUtils::WrapTexture(tex, src.width(), src.height(), result);
|
| + source,
|
| + false,
|
| + SkRect::Make(rect),
|
| + true,
|
| + fSigma.width(),
|
| + fSigma.height()));
|
| + offset->fX += rect.fLeft;
|
| + offset->fY += rect.fTop;
|
| + return SkImageFilterUtils::WrapTexture(tex, rect.width(), rect.height(), result);
|
| #else
|
| SkDEBUGFAIL("Should not call in GPU-less build");
|
| return false;
|
|
|