aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects
diff options
context:
space:
mode:
authorGravatar senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-04-01 19:15:23 +0000
committerGravatar senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-04-01 19:15:23 +0000
commitee845ae4940779280a853269d7d797dc9eb89201 (patch)
treeb71229988f2bca3b02a05f3d5d4eb52474ecb729 /src/effects
parent58af0c895f5a18f46e9594d7d170f60c70481f30 (diff)
Fix SkXfermodeImageFilter when an input is cropped out.
If one of inputs to SkXfermodeImageFilter draws nothing, either due to it being cropped out upstream, or within the filter itself, the filter should still draw the other input, since otherwise the result will be incorrect. For the GPU path, since we can't detect this case in canFilterImageGPU() without recursing, we'll just drop to the generic path if either input is empty, since we can't use the effect in that case anyway. While we're at it, let's drop to the generic path if the xfermode can't be expressed as an effect, since the code here was doing a 2-pass render in that case anyway, which is equivalent to what the (xfermode == NULL) case was doing anyway. R=bsalomon@google.com, sugoi@chromium.org Review URL: https://codereview.chromium.org/220723007 git-svn-id: http://skia.googlecode.com/svn/trunk@14016 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/effects')
-rw-r--r--src/effects/SkXfermodeImageFilter.cpp48
1 files changed, 24 insertions, 24 deletions
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
index 901353fabe..acb8fd381b 100644
--- a/src/effects/SkXfermodeImageFilter.cpp
+++ b/src/effects/SkXfermodeImageFilter.cpp
@@ -53,22 +53,27 @@ bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy,
SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
if (backgroundInput &&
!backgroundInput->filterImage(proxy, src, ctx, &background, &backgroundOffset)) {
- return false;
+ background.reset();
}
SkIPoint foregroundOffset = SkIPoint::Make(0, 0);
if (foregroundInput &&
!foregroundInput->filterImage(proxy, src, ctx, &foreground, &foregroundOffset)) {
- return false;
+ foreground.reset();
}
SkIRect bounds, foregroundBounds;
if (!applyCropRect(ctx, foreground, foregroundOffset, &foregroundBounds)) {
- return false;
+ foregroundBounds.setEmpty();
+ foreground.reset();
}
if (!applyCropRect(ctx, background, backgroundOffset, &bounds)) {
- return false;
+ bounds.setEmpty();
+ background.reset();
}
bounds.join(foregroundBounds);
+ if (bounds.isEmpty()) {
+ return false;
+ }
SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
if (NULL == device.get()) {
@@ -94,6 +99,10 @@ bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy,
#if SK_SUPPORT_GPU
+bool SkXfermodeImageFilter::canFilterImageGPU() const {
+ return fMode && fMode->asNewEffect(NULL, NULL) && !cropRectIsSet();
+}
+
bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
const SkBitmap& src,
const Context& ctx,
@@ -103,14 +112,14 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &background,
&backgroundOffset)) {
- return false;
+ return onFilterImage(proxy, src, ctx, result, offset);
}
GrTexture* backgroundTex = background.getTexture();
SkBitmap foreground = src;
SkIPoint foregroundOffset = SkIPoint::Make(0, 0);
if (getInput(1) && !getInput(1)->getInputResultGPU(proxy, src, ctx, &foreground,
&foregroundOffset)) {
- return false;
+ return onFilterImage(proxy, src, ctx, result, offset);
}
GrTexture* foregroundTex = foreground.getTexture();
GrContext* context = foregroundTex->getContext();
@@ -128,8 +137,9 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
GrContext::AutoRenderTarget art(context, dst->asRenderTarget());
- SkXfermode::Coeff sm, dm;
- if (!SkXfermode::AsNewEffectOrCoeff(fMode, &xferEffect, &sm, &dm, backgroundTex)) {
+ if (!fMode || !fMode->asNewEffect(&xferEffect, backgroundTex)) {
+ // canFilterImageGPU() should've taken care of this
+ SkASSERT(false);
return false;
}
@@ -140,22 +150,12 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
SkRect srcRect;
src.getBounds(&srcRect);
- if (NULL != xferEffect) {
- GrPaint paint;
- paint.addColorTextureEffect(foregroundTex, foregroundMatrix);
- paint.addColorEffect(xferEffect)->unref();
- context->drawRect(paint, srcRect);
- } else {
- GrPaint backgroundPaint;
- SkMatrix backgroundMatrix = GrEffect::MakeDivByTextureWHMatrix(backgroundTex);
- backgroundPaint.addColorTextureEffect(backgroundTex, backgroundMatrix);
- context->drawRect(backgroundPaint, srcRect);
-
- GrPaint foregroundPaint;
- foregroundPaint.setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm));
- foregroundPaint.addColorTextureEffect(foregroundTex, foregroundMatrix);
- context->drawRect(foregroundPaint, srcRect);
- }
+
+ GrPaint paint;
+ paint.addColorTextureEffect(foregroundTex, foregroundMatrix);
+ paint.addColorEffect(xferEffect)->unref();
+ context->drawRect(paint, srcRect);
+
offset->fX = backgroundOffset.fX;
offset->fY = backgroundOffset.fY;
WrapTexture(dst, src.width(), src.height(), result);