| Index: src/effects/SkXfermodeImageFilter.cpp
|
| diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
|
| index 3ff6c491b5f6c759cbec733dbe51065b5cf9aab4..c2013fdb86d04f812d22c4c830ea1dea4ed8caec 100644
|
| --- a/src/effects/SkXfermodeImageFilter.cpp
|
| +++ b/src/effects/SkXfermodeImageFilter.cpp
|
| @@ -147,13 +147,18 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
|
| }
|
| GrTexture* foregroundTex = foreground.getTexture();
|
| GrContext* context = foregroundTex->getContext();
|
| + SkIRect bounds = background.bounds().makeOffset(backgroundOffset.x(), backgroundOffset.y());
|
| + bounds.join(foreground.bounds().makeOffset(foregroundOffset.x(), foregroundOffset.y()));
|
| + if (bounds.isEmpty()) {
|
| + return false;
|
| + }
|
|
|
| const GrFragmentProcessor* xferFP = nullptr;
|
|
|
| GrSurfaceDesc desc;
|
| desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
| - desc.fWidth = src.width();
|
| - desc.fHeight = src.height();
|
| + desc.fWidth = bounds.width();
|
| + desc.fHeight = bounds.height();
|
| desc.fConfig = kSkia8888_GrPixelConfig;
|
| SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxTexture(desc));
|
| if (!dst) {
|
| @@ -161,32 +166,36 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
|
| }
|
|
|
| GrPaint paint;
|
| - SkMatrix bgMatrix;
|
| - bgMatrix.setIDiv(backgroundTex->width(), backgroundTex->height());
|
| - SkAutoTUnref<const GrFragmentProcessor> bgFP(
|
| - GrSimpleTextureEffect::Create(backgroundTex, bgMatrix));
|
| + SkMatrix backgroundMatrix;
|
| + backgroundMatrix.setIDiv(backgroundTex->width(), backgroundTex->height());
|
| + backgroundMatrix.preTranslate(SkIntToScalar(-backgroundOffset.fX),
|
| + SkIntToScalar(-backgroundOffset.fY));
|
| + SkAutoTUnref<const GrFragmentProcessor> bgFP(GrTextureDomainEffect::Create(
|
| + backgroundTex, backgroundMatrix,
|
| + GrTextureDomain::MakeTexelDomain(backgroundTex, background.bounds()),
|
| + GrTextureDomain::kDecal_Mode,
|
| + GrTextureParams::kNone_FilterMode)
|
| + );
|
| if (!fMode || !fMode->asFragmentProcessor(&xferFP, bgFP)) {
|
| // canFilterImageGPU() should've taken care of this
|
| SkASSERT(false);
|
| return false;
|
| }
|
|
|
| - SkMatrix foregroundMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(foregroundTex);
|
| - foregroundMatrix.preTranslate(SkIntToScalar(backgroundOffset.fX-foregroundOffset.fX),
|
| - SkIntToScalar(backgroundOffset.fY-foregroundOffset.fY));
|
| -
|
| + SkMatrix foregroundMatrix;
|
| + foregroundMatrix.setIDiv(foregroundTex->width(), foregroundTex->height());
|
| + foregroundMatrix.preTranslate(SkIntToScalar(-foregroundOffset.fX),
|
| + SkIntToScalar(-foregroundOffset.fY));
|
|
|
| - SkRect srcRect;
|
| - src.getBounds(&srcRect);
|
|
|
| - SkAutoTUnref<const GrFragmentProcessor> foregroundDomain(GrTextureDomainEffect::Create(
|
| + SkAutoTUnref<const GrFragmentProcessor> foregroundFP(GrTextureDomainEffect::Create(
|
| foregroundTex, foregroundMatrix,
|
| GrTextureDomain::MakeTexelDomain(foregroundTex, foreground.bounds()),
|
| GrTextureDomain::kDecal_Mode,
|
| GrTextureParams::kNone_FilterMode)
|
| );
|
|
|
| - paint.addColorFragmentProcessor(foregroundDomain.get());
|
| + paint.addColorFragmentProcessor(foregroundFP.get());
|
| if (xferFP) {
|
| paint.addColorFragmentProcessor(xferFP)->unref();
|
| }
|
| @@ -197,11 +206,13 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
|
| return false;
|
| }
|
|
|
| - drawContext->drawRect(GrClip::WideOpen(), paint, SkMatrix::I(), srcRect);
|
| + SkMatrix matrix;
|
| + matrix.setTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()));
|
| + drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(bounds));
|
|
|
| - offset->fX = backgroundOffset.fX;
|
| - offset->fY = backgroundOffset.fY;
|
| - WrapTexture(dst, src.width(), src.height(), result);
|
| + offset->fX = bounds.left();
|
| + offset->fY = bounds.top();
|
| + WrapTexture(dst, bounds.width(), bounds.height(), result);
|
| return true;
|
| }
|
|
|
|
|