From f230c6d979d7035cbf6995da8a0161e7802b92b7 Mon Sep 17 00:00:00 2001 From: robertphillips Date: Fri, 15 Apr 2016 12:47:42 -0700 Subject: [PATCH] Switch SkXfermodeImagerFilter over to new onFilterImage interface TBR=reed@google.com GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1894643002 Review URL: https://codereview.chromium.org/1894643002 --- include/effects/SkXfermodeImageFilter.h | 21 ++-- src/effects/SkXfermodeImageFilter.cpp | 175 +++++++++++++++++--------------- 2 files changed, 106 insertions(+), 90 deletions(-) diff --git a/include/effects/SkXfermodeImageFilter.h b/include/effects/SkXfermodeImageFilter.h index 6344227..96d4fef 100644 --- a/include/effects/SkXfermodeImageFilter.h +++ b/include/effects/SkXfermodeImageFilter.h @@ -18,7 +18,7 @@ class SK_API SkXfermodeImageFilter : public SkImageFilter { * This filter takes an xfermode, and uses it to composite the foreground * over the background. If foreground or background is NULL, the input * bitmap (src) is used instead. - */ + */ public: static sk_sp Make(sk_sp mode, sk_sp background, @@ -53,18 +53,19 @@ public: SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkXfermodeImageFilter) - bool onFilterImageDeprecated(Proxy* proxy, - const SkBitmap& src, - const Context& ctx, - SkBitmap* dst, - SkIPoint* offset) const override; +protected: + sk_sp onFilterImage(SkSpecialImage* source, const Context&, + SkIPoint* offset) const override; + #if SK_SUPPORT_GPU - bool canFilterImageGPU() const override; - bool filterImageGPUDeprecated(Proxy* proxy, const SkBitmap& src, const Context& ctx, - SkBitmap* result, SkIPoint* offset) const override; + sk_sp filterImageGPU(SkSpecialImage* source, + sk_sp background, + const SkIPoint& backgroundOffset, + sk_sp foreground, + const SkIPoint& foregroundOffset, + const SkIRect& bounds) const; #endif -protected: SkXfermodeImageFilter(sk_sp mode, sk_sp inputs[2], const CropRect* cropRect); void flatten(SkWriteBuffer&) const override; diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp index 330f839..af58a64 100644 --- a/src/effects/SkXfermodeImageFilter.cpp +++ b/src/effects/SkXfermodeImageFilter.cpp @@ -6,10 +6,12 @@ */ #include "SkXfermodeImageFilter.h" + #include "SkCanvas.h" -#include "SkDevice.h" #include "SkColorPriv.h" #include "SkReadBuffer.h" +#include "SkSpecialImage.h" +#include "SkSpecialSurface.h" #include "SkWriteBuffer.h" #include "SkXfermode.h" #if SK_SUPPORT_GPU @@ -35,14 +37,13 @@ SkXfermodeImageFilter::SkXfermodeImageFilter(sk_sp mode, sk_sp inputs[2], const CropRect* cropRect) : INHERITED(inputs, 2, cropRect) - , fMode(std::move(mode)) -{} + , fMode(std::move(mode)) { +} sk_sp SkXfermodeImageFilter::CreateProc(SkReadBuffer& buffer) { SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2); sk_sp mode(buffer.readXfermode()); - return Make(std::move(mode), common.getInput(0), common.getInput(1), - &common.cropRect()); + return Make(std::move(mode), common.getInput(0), common.getInput(1), &common.cropRect()); } void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const { @@ -50,51 +51,83 @@ void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const { buffer.writeFlattenable(fMode.get()); } -bool SkXfermodeImageFilter::onFilterImageDeprecated(Proxy* proxy, - const SkBitmap& src, - const Context& ctx, - SkBitmap* dst, - SkIPoint* offset) const { - SkBitmap background = src, foreground = src; +sk_sp SkXfermodeImageFilter::onFilterImage(SkSpecialImage* source, + const Context& ctx, + SkIPoint* offset) const { SkIPoint backgroundOffset = SkIPoint::Make(0, 0); - if (!this->filterInputDeprecated(0, proxy, src, ctx, &background, &backgroundOffset)) { - background.reset(); - } + sk_sp background(this->filterInput(0, source, ctx, &backgroundOffset)); + SkIPoint foregroundOffset = SkIPoint::Make(0, 0); - if (!this->filterInputDeprecated(1, proxy, src, ctx, &foreground, &foregroundOffset)) { - foreground.reset(); + sk_sp foreground(this->filterInput(1, source, ctx, &foregroundOffset)); + + SkIRect foregroundBounds = SkIRect::EmptyIRect(); + if (foreground) { + foregroundBounds = SkIRect::MakeXYWH(foregroundOffset.x(), foregroundOffset.y(), + foreground->width(), foreground->height()); } - SkIRect foregroundBounds = foreground.bounds(); - foregroundBounds.offset(foregroundOffset); - SkIRect srcBounds = background.bounds(); - srcBounds.offset(backgroundOffset); + SkIRect srcBounds = SkIRect::EmptyIRect(); + if (background) { + srcBounds = SkIRect::MakeXYWH(backgroundOffset.x(), backgroundOffset.y(), + background->width(), background->height()); + } + srcBounds.join(foregroundBounds); + if (srcBounds.isEmpty()) { + return nullptr; + } + SkIRect bounds; if (!this->applyCropRect(ctx, srcBounds, &bounds)) { - return false; + return nullptr; + } + + offset->fX = bounds.left(); + offset->fY = bounds.top(); + +#if SK_SUPPORT_GPU + if (source->isTextureBacked()) { + return this->filterImageGPU(source, + background, backgroundOffset, + foreground, foregroundOffset, + bounds); } +#endif - SkAutoTUnref device(proxy->createDevice(bounds.width(), bounds.height())); - if (nullptr == device.get()) { - return false; + const SkImageInfo info = SkImageInfo::MakeN32(bounds.width(), bounds.height(), + kPremul_SkAlphaType); + sk_sp surf(source->makeSurface(info)); + if (!surf) { + return nullptr; } - SkCanvas canvas(device); - canvas.translate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top())); + + SkCanvas* canvas = surf->getCanvas(); + SkASSERT(canvas); + + 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 (background) { + background->draw(canvas, + SkIntToScalar(backgroundOffset.fX), SkIntToScalar(backgroundOffset.fY), + &paint); + } + paint.setXfermode(fMode); - canvas.drawBitmap(foreground, SkIntToScalar(foregroundOffset.fX), - SkIntToScalar(foregroundOffset.fY), &paint); - canvas.clipRect(SkRect::Make(foregroundBounds), SkRegion::kDifference_Op); + + if (foreground) { + foreground->draw(canvas, + 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); - offset->fX = bounds.left(); - offset->fY = bounds.top(); - return true; + canvas->drawPaint(paint); + + return surf->makeImageSnapshot(); } #ifndef SK_IGNORE_TO_STRING @@ -121,46 +154,26 @@ void SkXfermodeImageFilter::toString(SkString* str) const { #if SK_SUPPORT_GPU -bool SkXfermodeImageFilter::canFilterImageGPU() const { - return !this->cropRectIsSet(); -} - #include "SkXfermode_proccoeff.h" -bool SkXfermodeImageFilter::filterImageGPUDeprecated(Proxy* proxy, - const SkBitmap& src, - const Context& ctx, - SkBitmap* result, - SkIPoint* offset) const { - GrContext* context = nullptr; - SkBitmap background = src; - SkIPoint backgroundOffset = SkIPoint::Make(0, 0); - if (!this->filterInputGPUDeprecated(0, proxy, src, ctx, &background, &backgroundOffset)) { - background.reset(); - } - GrTexture* backgroundTex = background.getTexture(); - if (backgroundTex) { - context = backgroundTex->getContext(); - } +sk_sp SkXfermodeImageFilter::filterImageGPU(SkSpecialImage* source, + sk_sp background, + const SkIPoint& backgroundOffset, + sk_sp foreground, + const SkIPoint& foregroundOffset, + const SkIRect& bounds) const { + SkASSERT(source->isTextureBacked()); - SkBitmap foreground = src; - SkIPoint foregroundOffset = SkIPoint::Make(0, 0); - if (!this->filterInputGPUDeprecated(1, proxy, src, ctx, &foreground, &foregroundOffset)) { - foreground.reset(); - } - GrTexture* foregroundTex = foreground.getTexture(); - if (foregroundTex) { - context = foregroundTex->getContext(); - } + GrContext* context = source->getContext(); - if (!context) { - return false; + sk_sp backgroundTex, foregroundTex; + + if (background) { + backgroundTex.reset(background->asTextureRef(context)); } - SkIRect bounds = background.bounds().makeOffset(backgroundOffset.x(), backgroundOffset.y()); - bounds.join(foreground.bounds().makeOffset(foregroundOffset.x(), foregroundOffset.y())); - if (bounds.isEmpty()) { - return false; + if (foreground) { + foregroundTex.reset(foreground->asTextureRef(context)); } GrSurfaceDesc desc; @@ -170,7 +183,7 @@ bool SkXfermodeImageFilter::filterImageGPUDeprecated(Proxy* proxy, desc.fConfig = kSkia8888_GrPixelConfig; SkAutoTUnref dst(context->textureProvider()->createApproxTexture(desc)); if (!dst) { - return false; + return nullptr; } GrPaint paint; @@ -183,8 +196,9 @@ bool SkXfermodeImageFilter::filterImageGPUDeprecated(Proxy* proxy, backgroundMatrix.preTranslate(SkIntToScalar(-backgroundOffset.fX), SkIntToScalar(-backgroundOffset.fY)); bgFP.reset(GrTextureDomainEffect::Create( - backgroundTex, backgroundMatrix, - GrTextureDomain::MakeTexelDomain(backgroundTex, background.bounds()), + backgroundTex.get(), backgroundMatrix, + GrTextureDomain::MakeTexelDomain(backgroundTex.get(), + background->subset()), GrTextureDomain::kDecal_Mode, GrTextureParams::kNone_FilterMode)); } else { @@ -201,8 +215,9 @@ bool SkXfermodeImageFilter::filterImageGPUDeprecated(Proxy* proxy, SkAutoTUnref foregroundFP; foregroundFP.reset(GrTextureDomainEffect::Create( - foregroundTex, foregroundMatrix, - GrTextureDomain::MakeTexelDomain(foregroundTex, foreground.bounds()), + foregroundTex.get(), foregroundMatrix, + GrTextureDomain::MakeTexelDomain(foregroundTex.get(), + foreground->subset()), GrTextureDomain::kDecal_Mode, GrTextureParams::kNone_FilterMode)); @@ -235,17 +250,17 @@ bool SkXfermodeImageFilter::filterImageGPUDeprecated(Proxy* proxy, SkAutoTUnref drawContext(context->drawContext(dst->asRenderTarget())); if (!drawContext) { - return false; + return nullptr; } SkMatrix matrix; matrix.setTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top())); drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(bounds)); - offset->fX = bounds.left(); - offset->fY = bounds.top(); - GrWrapTextureInBitmap(dst, bounds.width(), bounds.height(), false, result); - return true; + return SkSpecialImage::MakeFromGpu(source->internal_getProxy(), + SkIRect::MakeWH(bounds.width(), bounds.height()), + kNeedNewImageUniqueID_SpecialImage, + dst.get()); } #endif -- 2.7.4