Chromium Code Reviews| Index: src/image/SkImage_Gpu.cpp |
| diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp |
| index f7a73b9e0130ab9257856e0e125ef4b1f2b5fc0f..7656f3938c26c52c3a5e88089d9f623436d9d556 100644 |
| --- a/src/image/SkImage_Gpu.cpp |
| +++ b/src/image/SkImage_Gpu.cpp |
| @@ -220,27 +220,55 @@ public: |
| } |
| }; |
| +static SkIRect compute_fast_ibounds(SkImageFilter* filter, const SkIRect& srcBounds) { |
| + SkRect fastBounds; |
| + fastBounds.set(srcBounds); |
| + filter->computeFastBounds(fastBounds, &fastBounds); |
| + return fastBounds.roundOut(); |
| +} |
| + |
| SkImage* SkImage_Gpu::onApplyFilter(SkImageFilter* filter, SkIPoint* offsetResult, |
| bool forceResultToOriginalSize) const { |
|
Stephen White
2015/10/14 21:41:43
As discussed, please change this bool to a nullabl
|
| - if (!forceResultToOriginalSize || !filter->canFilterImageGPU()) { |
| - return this->INHERITED::onApplyFilter(filter, offsetResult, forceResultToOriginalSize); |
| - } |
| + const SkIRect srcBounds = SkIRect::MakeWH(this->width(), this->height()); |
| - SkBitmap src; |
| - GrWrapTextureInBitmap(fTexture, this->width(), this->height(), this->isOpaque(), &src); |
| + if (forceResultToOriginalSize) { |
| + SkBitmap src; |
| + GrWrapTextureInBitmap(fTexture, this->width(), this->height(), this->isOpaque(), &src); |
| - GrContext* context = fTexture->getContext(); |
| - SkGpuImageFilterProxy proxy(context); |
| - SkImageFilter::Context ctx(SkMatrix::I(), |
| - SkIRect::MakeWH(this->width(), this->height()), |
| - SkImageFilter::Cache::Get()); |
| + const SkIRect clipBounds = srcBounds; |
| + SkGpuImageFilterProxy proxy(fTexture->getContext()); |
| + SkImageFilter::Context ctx(SkMatrix::I(), clipBounds, SkImageFilter::Cache::Get()); |
| - SkBitmap dst; |
| - if (filter->filterImageGPU(&proxy, src, ctx, &dst, offsetResult)) { |
| - return new SkImage_Gpu(dst.width(), dst.height(), kNeedNewImageUniqueID, dst.alphaType(), |
| - dst.getTexture(), SkSurface::kNo_Budgeted); |
| + SkBitmap dst; |
| + if (filter->canFilterImageGPU()) { |
| + if (!filter->filterImageGPU(&proxy, src, ctx, &dst, offsetResult)) { |
|
Stephen White
2015/10/14 21:41:43
This is going to bypass the caching logic in filte
|
| + return nullptr; |
| + } |
| + } else { |
| + if (!filter->filterImage(&proxy, src, ctx, &dst, offsetResult)) { |
| + return nullptr; |
| + } |
| + } |
| + if (dst.getTexture()) { |
| + return new SkImage_Gpu(dst.width(), dst.height(), kNeedNewImageUniqueID, dst.alphaType(), |
| + dst.getTexture(), SkSurface::kNo_Budgeted); |
| + } |
| + // fall-through to the drawing case |
| } |
| - return nullptr; |
| + |
| + const SkIRect dstR = forceResultToOriginalSize ? |
| + srcBounds : compute_fast_ibounds(filter, srcBounds); |
| + |
| + SkImageInfo info = SkImageInfo::MakeN32Premul(dstR.width(), dstR.height()); |
| + SkAutoTUnref<SkSurface> surface(this->onNewSurface(info)); |
| + |
| + SkPaint paint; |
| + paint.setImageFilter(filter); |
| + surface->getCanvas()->drawImage(this, SkIntToScalar(-dstR.x()), SkIntToScalar(-dstR.y()), |
| + &paint); |
| + |
| + offsetResult->set(dstR.x(), dstR.y()); |
| + return surface->newImageSnapshot(); |
| } |
| /////////////////////////////////////////////////////////////////////////////////////////////////// |