| 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;
|
| }
|
|
|
|
|