Index: src/effects/SkXfermodeImageFilter.cpp |
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp |
index c3f8487ab6fe4f12718f6323675e6d7f924af331..73e9cdbeb82c981e8cbadb7b89814b24982710ac 100644 |
--- a/src/effects/SkXfermodeImageFilter.cpp |
+++ b/src/effects/SkXfermodeImageFilter.cpp |
@@ -43,32 +43,33 @@ void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const { |
} |
bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy, |
- const SkBitmap& src, |
- const Context& ctx, |
- SkBitmap* dst, |
- SkIPoint* offset) const { |
- SkBitmap background = src, foreground = src; |
+ const SkImage* src, |
+ const Context& ctx, |
+ SkAutoTUnref<const SkImage>& dst, |
+ SkIPoint* offset) const { |
+ SkAutoTUnref<const SkImage> background(SkRef(src)); |
+ SkAutoTUnref<const SkImage> foreground(SkRef(src)); |
SkImageFilter* backgroundInput = getInput(0); |
SkImageFilter* foregroundInput = getInput(1); |
SkIPoint backgroundOffset = SkIPoint::Make(0, 0); |
if (backgroundInput && |
- !backgroundInput->filterImage(proxy, src, ctx, &background, &backgroundOffset)) { |
- background.reset(); |
+ !backgroundInput->filterImage(proxy, src, ctx, background, &backgroundOffset)) { |
+ background.reset(NULL); |
} |
SkIPoint foregroundOffset = SkIPoint::Make(0, 0); |
if (foregroundInput && |
- !foregroundInput->filterImage(proxy, src, ctx, &foreground, &foregroundOffset)) { |
- foreground.reset(); |
+ !foregroundInput->filterImage(proxy, src, ctx, foreground, &foregroundOffset)) { |
+ foreground.reset(NULL); |
} |
SkIRect bounds, foregroundBounds; |
if (!applyCropRect(ctx, foreground, foregroundOffset, &foregroundBounds)) { |
foregroundBounds.setEmpty(); |
- foreground.reset(); |
+ foreground.reset(NULL); |
} |
if (!applyCropRect(ctx, background, backgroundOffset, &bounds)) { |
bounds.setEmpty(); |
- background.reset(); |
+ background.reset(NULL); |
} |
bounds.join(foregroundBounds); |
if (bounds.isEmpty()) { |
@@ -82,16 +83,29 @@ bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy, |
SkCanvas canvas(device); |
canvas.translate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top())); |
SkPaint paint; |
- paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
- canvas.drawBitmap(background, SkIntToScalar(backgroundOffset.fX), |
- SkIntToScalar(backgroundOffset.fY), &paint); |
+ if (NULL != background) { |
+ paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
+ canvas.drawImage(background, SkIntToScalar(backgroundOffset.fX), |
+ SkIntToScalar(backgroundOffset.fY), &paint); |
+ } |
paint.setXfermode(fMode); |
- canvas.drawBitmap(foreground, SkIntToScalar(foregroundOffset.fX), |
- SkIntToScalar(foregroundOffset.fY), &paint); |
+ if (NULL != foreground) { |
+ canvas.drawImage(foreground, SkIntToScalar(foregroundOffset.fX), |
+ SkIntToScalar(foregroundOffset.fY), &paint); |
+ } |
canvas.clipRect(SkRect::Make(foregroundBounds), SkRegion::kDifference_Op); |
paint.setColor(SK_ColorTRANSPARENT); |
canvas.drawPaint(paint); |
- *dst = device->accessBitmap(false); |
+ |
+ foreground.reset(NULL); |
+ background.reset(NULL); |
+ |
+ SkImage* image = device->newImageSnapshot(); |
+ if (NULL == image) { |
+ return false; |
+ } |
+ dst.reset(image); |
+ |
offset->fX = bounds.left(); |
offset->fY = bounds.top(); |
return true; |
@@ -115,38 +129,40 @@ bool SkXfermodeImageFilter::canFilterImageGPU() const { |
} |
bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy, |
- const SkBitmap& src, |
+ const SkImage* src, |
const Context& ctx, |
- SkBitmap* result, |
+ SkAutoTUnref<const SkImage>& result, |
SkIPoint* offset) const { |
- SkBitmap background = src; |
+ SkAutoTUnref<const SkImage> background(SkRef(src)); |
SkIPoint backgroundOffset = SkIPoint::Make(0, 0); |
- if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &background, |
+ if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, background, |
&backgroundOffset)) { |
return onFilterImage(proxy, src, ctx, result, offset); |
} |
- GrTexture* backgroundTex = background.getTexture(); |
+ GrTexture* backgroundTex = background->getTexture(); |
if (NULL == backgroundTex) { |
SkASSERT(false); |
return false; |
} |
- SkBitmap foreground = src; |
+ SkAutoTUnref<const SkImage> foreground(SkRef(src)); |
SkIPoint foregroundOffset = SkIPoint::Make(0, 0); |
- if (getInput(1) && !getInput(1)->getInputResultGPU(proxy, src, ctx, &foreground, |
+ if (getInput(1) && !getInput(1)->getInputResultGPU(proxy, src, ctx, foreground, |
&foregroundOffset)) { |
return onFilterImage(proxy, src, ctx, result, offset); |
} |
- GrTexture* foregroundTex = foreground.getTexture(); |
+ GrTexture* foregroundTex = foreground->getTexture(); |
GrContext* context = foregroundTex->getContext(); |
GrFragmentProcessor* xferProcessor = NULL; |
+ const SkRect srcRect = SkRect::MakeWH(src->width(), src->height()); |
+ |
GrSurfaceDesc desc; |
desc.fFlags = kRenderTarget_GrSurfaceFlag; |
- desc.fWidth = src.width(); |
- desc.fHeight = src.height(); |
+ desc.fWidth = srcRect.width(); |
+ desc.fHeight = srcRect.height(); |
desc.fConfig = kSkia8888_GrPixelConfig; |
SkAutoTUnref<GrTexture> dst( |
context->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch)); |
@@ -165,8 +181,7 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy, |
SkIntToScalar(backgroundOffset.fY-foregroundOffset.fY)); |
- SkRect srcRect; |
- src.getBounds(&srcRect); |
+ |
GrPaint paint; |
paint.addColorTextureProcessor(foregroundTex, foregroundMatrix); |
@@ -175,7 +190,9 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy, |
offset->fX = backgroundOffset.fX; |
offset->fY = backgroundOffset.fY; |
- WrapTexture(dst, src.width(), src.height(), result); |
+ if (!WrapTexture(dst, srcRect.width(), srcRect.height(), result)) { |
+ return false; |
+ } |
return true; |
} |