From ad3dc0da218cc43c9917a256d4afb8cf0d7c5899 Mon Sep 17 00:00:00 2001 From: robertphillips Date: Fri, 15 Apr 2016 05:06:11 -0700 Subject: [PATCH] Switch SkLightingImageFilter 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=1887103002 Review URL: https://codereview.chromium.org/1887103002 --- src/effects/SkLightingImageFilter.cpp | 329 +++++++++++++++++++--------------- 1 file changed, 184 insertions(+), 145 deletions(-) diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp index e60e7ed..b37fc28 100644 --- a/src/effects/SkLightingImageFilter.cpp +++ b/src/effects/SkLightingImageFilter.cpp @@ -8,9 +8,9 @@ #include "SkLightingImageFilter.h" #include "SkBitmap.h" #include "SkColorPriv.h" -#include "SkDevice.h" #include "SkPoint3.h" #include "SkReadBuffer.h" +#include "SkSpecialImage.h" #include "SkTypes.h" #include "SkWriteBuffer.h" @@ -355,9 +355,10 @@ protected: } #if SK_SUPPORT_GPU - bool canFilterImageGPU() const override { return true; } - bool filterImageGPUDeprecated(Proxy*, const SkBitmap& src, const Context&, - SkBitmap* result, SkIPoint* offset) const override; + sk_sp filterImageGPU(SkSpecialImage* source, + SkSpecialImage* input, + const SkIRect& bounds, + const SkMatrix& matrix) const; virtual GrFragmentProcessor* getFragmentProcessor(GrTexture*, const SkMatrix&, const SkIRect* srcBounds, @@ -395,47 +396,40 @@ void SkLightingImageFilterInternal::drawRect(GrDrawContext* drawContext, drawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect); } -bool SkLightingImageFilterInternal::filterImageGPUDeprecated(Proxy* proxy, - const SkBitmap& src, - const Context& ctx, - SkBitmap* result, - SkIPoint* offset) const { - SkBitmap input = src; - SkIPoint srcOffset = SkIPoint::Make(0, 0); - if (!this->filterInputGPUDeprecated(0, proxy, src, ctx, &input, &srcOffset)) { - return false; - } - SkIRect srcBounds = input.bounds(); - srcBounds.offset(srcOffset); - SkIRect bounds; - if (!this->applyCropRect(ctx, srcBounds, &bounds)) { - return false; - } - SkRect dstRect = SkRect::MakeWH(SkIntToScalar(bounds.width()), - SkIntToScalar(bounds.height())); - GrTexture* srcTexture = input.getTexture(); - GrContext* context = srcTexture->getContext(); +sk_sp SkLightingImageFilterInternal::filterImageGPU(SkSpecialImage* source, + SkSpecialImage* input, + const SkIRect& offsetBounds, + const SkMatrix& matrix) const { + SkASSERT(source->isTextureBacked()); + + GrContext* context = source->getContext(); + + sk_sp inputTexture(input->asTextureRef(context)); + SkASSERT(inputTexture); GrSurfaceDesc desc; desc.fFlags = kRenderTarget_GrSurfaceFlag, - desc.fWidth = bounds.width(); - desc.fHeight = bounds.height(); + desc.fWidth = offsetBounds.width(); + desc.fHeight = offsetBounds.height(); desc.fConfig = kRGBA_8888_GrPixelConfig; - SkAutoTUnref dst(context->textureProvider()->createApproxTexture(desc)); + sk_sp dst(context->textureProvider()->createApproxTexture(desc)); if (!dst) { - return false; + return nullptr; + } + + sk_sp drawContext(context->drawContext(dst->asRenderTarget())); + if (!drawContext) { + return nullptr; } + SkRect dstRect = SkRect::MakeWH(SkIntToScalar(offsetBounds.width()), + SkIntToScalar(offsetBounds.height())); + // setup new clip GrClip clip(dstRect); - offset->fX = bounds.left(); - offset->fY = bounds.top(); - SkMatrix matrix(ctx.ctm()); - matrix.postTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top())); - bounds.offset(-srcOffset); - srcBounds.offset(-srcOffset); + const SkIRect inputBounds = SkIRect::MakeWH(input->width(), input->height()); SkRect topLeft = SkRect::MakeXYWH(0, 0, 1, 1); SkRect top = SkRect::MakeXYWH(1, 0, dstRect.width() - 2, 1); SkRect topRight = SkRect::MakeXYWH(dstRect.width() - 1, 0, 1, 1); @@ -446,32 +440,30 @@ bool SkLightingImageFilterInternal::filterImageGPUDeprecated(Proxy* proxy, SkRect bottom = SkRect::MakeXYWH(1, dstRect.height() - 1, dstRect.width() - 2, 1); SkRect bottomRight = SkRect::MakeXYWH(dstRect.width() - 1, dstRect.height() - 1, 1, 1); - SkAutoTUnref drawContext(context->drawContext(dst->asRenderTarget())); - if (!drawContext) { - return false; - } - - const SkIRect* pSrcBounds = srcBounds.contains(bounds) ? nullptr : &srcBounds; - this->drawRect(drawContext, srcTexture, matrix, clip, topLeft, kTopLeft_BoundaryMode, - pSrcBounds, bounds); - this->drawRect(drawContext, srcTexture, matrix, clip, top, kTop_BoundaryMode, - pSrcBounds, bounds); - this->drawRect(drawContext, srcTexture, matrix, clip, topRight, kTopRight_BoundaryMode, - pSrcBounds, bounds); - this->drawRect(drawContext, srcTexture, matrix, clip, left, kLeft_BoundaryMode, - pSrcBounds, bounds); - this->drawRect(drawContext, srcTexture, matrix, clip, interior, kInterior_BoundaryMode, - pSrcBounds, bounds); - this->drawRect(drawContext, srcTexture, matrix, clip, right, kRight_BoundaryMode, - pSrcBounds, bounds); - this->drawRect(drawContext, srcTexture, matrix, clip, bottomLeft, kBottomLeft_BoundaryMode, - pSrcBounds, bounds); - this->drawRect(drawContext, srcTexture, matrix, clip, bottom, kBottom_BoundaryMode, - pSrcBounds, bounds); - this->drawRect(drawContext, srcTexture, matrix, clip, bottomRight, - kBottomRight_BoundaryMode, pSrcBounds, bounds); - GrWrapTextureInBitmap(dst, bounds.width(), bounds.height(), false, result); - return true; + const SkIRect* pSrcBounds = inputBounds.contains(offsetBounds) ? nullptr : &inputBounds; + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, topLeft, + kTopLeft_BoundaryMode, pSrcBounds, offsetBounds); + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, top, kTop_BoundaryMode, + pSrcBounds, offsetBounds); + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, topRight, + kTopRight_BoundaryMode, pSrcBounds, offsetBounds); + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, left, kLeft_BoundaryMode, + pSrcBounds, offsetBounds); + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, interior, + kInterior_BoundaryMode, pSrcBounds, offsetBounds); + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, right, kRight_BoundaryMode, + pSrcBounds, offsetBounds); + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, bottomLeft, + kBottomLeft_BoundaryMode, pSrcBounds, offsetBounds); + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, bottom, + kBottom_BoundaryMode, pSrcBounds, offsetBounds); + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, bottomRight, + kBottomRight_BoundaryMode, pSrcBounds, offsetBounds); + + return SkSpecialImage::MakeFromGpu(source->internal_getProxy(), + SkIRect::MakeWH(offsetBounds.width(), offsetBounds.height()), + kNeedNewImageUniqueID_SpecialImage, + dst.get()); } #endif @@ -492,8 +484,10 @@ protected: SkScalar kd, sk_sp input, const CropRect* cropRect); void flatten(SkWriteBuffer& buffer) const override; - bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&, - SkBitmap* result, SkIPoint* offset) const override; + + sk_sp onFilterImage(SkSpecialImage* source, const Context&, + SkIPoint* offset) const override; + #if SK_SUPPORT_GPU GrFragmentProcessor* getFragmentProcessor(GrTexture*, const SkMatrix&, const SkIRect* bounds, BoundaryMode) const override; @@ -501,8 +495,9 @@ protected: private: friend class SkLightingImageFilter; - typedef SkLightingImageFilterInternal INHERITED; SkScalar fKD; + + typedef SkLightingImageFilterInternal INHERITED; }; class SkSpecularLightingImageFilter : public SkLightingImageFilterInternal { @@ -524,8 +519,10 @@ protected: SkScalar shininess, sk_sp input, const CropRect*); void flatten(SkWriteBuffer& buffer) const override; - bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&, - SkBitmap* result, SkIPoint* offset) const override; + + sk_sp onFilterImage(SkSpecialImage* source, const Context&, + SkIPoint* offset) const override; + #if SK_SUPPORT_GPU GrFragmentProcessor* getFragmentProcessor(GrTexture*, const SkMatrix&, const SkIRect* bounds, BoundaryMode) const override; @@ -1239,79 +1236,99 @@ void SkDiffuseLightingImageFilter::flatten(SkWriteBuffer& buffer) const { buffer.writeScalar(fKD); } -bool SkDiffuseLightingImageFilter::onFilterImageDeprecated(Proxy* proxy, - const SkBitmap& source, - const Context& ctx, - SkBitmap* dst, - SkIPoint* offset) const { - SkBitmap src = source; - SkIPoint srcOffset = SkIPoint::Make(0, 0); - if (!this->filterInputDeprecated(0, proxy, source, ctx, &src, &srcOffset)) { - return false; +sk_sp SkDiffuseLightingImageFilter::onFilterImage(SkSpecialImage* source, + const Context& ctx, + SkIPoint* offset) const { + SkIPoint inputOffset = SkIPoint::Make(0, 0); + sk_sp input(this->filterInput(0, source, ctx, &inputOffset)); + if (!input) { + return nullptr; } - if (src.colorType() != kN32_SkColorType) { - return false; - } - SkIRect srcBounds = src.bounds(); - srcBounds.offset(srcOffset); + const SkIRect inputBounds = SkIRect::MakeXYWH(inputOffset.x(), inputOffset.y(), + input->width(), input->height()); SkIRect bounds; - if (!this->applyCropRect(ctx, srcBounds, &bounds)) { - return false; + if (!this->applyCropRect(ctx, inputBounds, &bounds)) { + return nullptr; } + offset->fX = bounds.left(); + offset->fY = bounds.top(); + bounds.offset(-inputOffset); + +#if SK_SUPPORT_GPU + if (source->isTextureBacked()) { + SkMatrix matrix(ctx.ctm()); + matrix.postTranslate(SkIntToScalar(-offset->fX), SkIntToScalar(-offset->fY)); + + return this->filterImageGPU(source, input.get(), bounds, matrix); + } +#endif + if (bounds.width() < 2 || bounds.height() < 2) { - return false; + return nullptr; + } + + SkBitmap inputBM; + + if (!input->getROPixels(&inputBM)) { + return nullptr; } - SkAutoLockPixels alp(src); - if (!src.getPixels()) { - return false; + if (inputBM.colorType() != kN32_SkColorType) { + return nullptr; } - SkAutoTUnref device(proxy->createDevice(bounds.width(), bounds.height())); - if (!device) { - return false; + SkAutoLockPixels alp(inputBM); + if (!inputBM.getPixels()) { + return nullptr; + } + + const SkImageInfo info = SkImageInfo::MakeN32Premul(bounds.width(), bounds.height()); + + SkBitmap dst; + if (!dst.tryAllocPixels(info)) { + return nullptr; } - *dst = device->accessBitmap(false); - SkAutoLockPixels alp_dst(*dst); + + SkAutoLockPixels dstLock(dst); SkMatrix matrix(ctx.ctm()); - matrix.postTranslate(SkIntToScalar(-srcOffset.x()), SkIntToScalar(-srcOffset.y())); - SkAutoTUnref transformedLight(light()->transform(matrix)); + matrix.postTranslate(SkIntToScalar(-inputOffset.x()), SkIntToScalar(-inputOffset.y())); + + sk_sp transformedLight(light()->transform(matrix)); DiffuseLightingType lightingType(fKD); - offset->fX = bounds.left(); - offset->fY = bounds.top(); - bounds.offset(-srcOffset); switch (transformedLight->type()) { case SkImageFilterLight::kDistant_LightType: lightBitmap(lightingType, - transformedLight, - src, - dst, + transformedLight.get(), + inputBM, + &dst, surfaceScale(), bounds); break; case SkImageFilterLight::kPoint_LightType: lightBitmap(lightingType, - transformedLight, - src, - dst, + transformedLight.get(), + inputBM, + &dst, surfaceScale(), bounds); break; case SkImageFilterLight::kSpot_LightType: lightBitmap(lightingType, - transformedLight, - src, - dst, + transformedLight.get(), + inputBM, + &dst, surfaceScale(), bounds); break; } - return true; + return SkSpecialImage::MakeFromRaster(source->internal_getProxy(), + SkIRect::MakeWH(bounds.width(), bounds.height()), + dst); } #ifndef SK_IGNORE_TO_STRING @@ -1385,78 +1402,100 @@ void SkSpecularLightingImageFilter::flatten(SkWriteBuffer& buffer) const { buffer.writeScalar(fShininess); } -bool SkSpecularLightingImageFilter::onFilterImageDeprecated(Proxy* proxy, - const SkBitmap& source, - const Context& ctx, - SkBitmap* dst, - SkIPoint* offset) const { - SkBitmap src = source; - SkIPoint srcOffset = SkIPoint::Make(0, 0); - if (!this->filterInputDeprecated(0, proxy, source, ctx, &src, &srcOffset)) { - return false; +sk_sp SkSpecularLightingImageFilter::onFilterImage(SkSpecialImage* source, + const Context& ctx, + SkIPoint* offset) const { + SkIPoint inputOffset = SkIPoint::Make(0, 0); + sk_sp input(this->filterInput(0, source, ctx, &inputOffset)); + if (!input) { + return nullptr; } - if (src.colorType() != kN32_SkColorType) { - return false; + const SkIRect inputBounds = SkIRect::MakeXYWH(inputOffset.x(), inputOffset.y(), + input->width(), input->height()); + SkIRect bounds; + if (!this->applyCropRect(ctx, inputBounds, &bounds)) { + return nullptr; } - SkIRect srcBounds = src.bounds(); - srcBounds.offset(srcOffset); - SkIRect bounds; - if (!this->applyCropRect(ctx, srcBounds, &bounds)) { - return false; + offset->fX = bounds.left(); + offset->fY = bounds.top(); + bounds.offset(-inputOffset); + +#if SK_SUPPORT_GPU + if (source->isTextureBacked()) { + SkMatrix matrix(ctx.ctm()); + matrix.postTranslate(SkIntToScalar(-offset->fX), SkIntToScalar(-offset->fY)); + + return this->filterImageGPU(source, input.get(), bounds, matrix); } +#endif if (bounds.width() < 2 || bounds.height() < 2) { - return false; + return nullptr; + } + + SkBitmap inputBM; + + if (!input->getROPixels(&inputBM)) { + return nullptr; } - SkAutoLockPixels alp(src); - if (!src.getPixels()) { - return false; + if (inputBM.colorType() != kN32_SkColorType) { + return nullptr; } - SkAutoTUnref device(proxy->createDevice(bounds.width(), bounds.height())); - if (!device) { - return false; + SkAutoLockPixels alp(inputBM); + if (!inputBM.getPixels()) { + return nullptr; } - *dst = device->accessBitmap(false); - SkAutoLockPixels alp_dst(*dst); + + const SkImageInfo info = SkImageInfo::MakeN32Premul(bounds.width(), bounds.height()); + + SkBitmap dst; + if (!dst.tryAllocPixels(info)) { + return nullptr; + } + + SkAutoLockPixels dstLock(dst); SpecularLightingType lightingType(fKS, fShininess); - offset->fX = bounds.left(); - offset->fY = bounds.top(); + SkMatrix matrix(ctx.ctm()); - matrix.postTranslate(SkIntToScalar(-srcOffset.x()), SkIntToScalar(-srcOffset.y())); - SkAutoTUnref transformedLight(light()->transform(matrix)); - bounds.offset(-srcOffset); + matrix.postTranslate(SkIntToScalar(-inputOffset.x()), SkIntToScalar(-inputOffset.y())); + + sk_sp transformedLight(light()->transform(matrix)); + switch (transformedLight->type()) { case SkImageFilterLight::kDistant_LightType: lightBitmap(lightingType, - transformedLight, - src, - dst, + transformedLight.get(), + inputBM, + &dst, surfaceScale(), bounds); break; case SkImageFilterLight::kPoint_LightType: lightBitmap(lightingType, - transformedLight, - src, - dst, + transformedLight.get(), + inputBM, + &dst, surfaceScale(), bounds); break; case SkImageFilterLight::kSpot_LightType: lightBitmap(lightingType, - transformedLight, - src, - dst, + transformedLight.get(), + inputBM, + &dst, surfaceScale(), bounds); break; } - return true; + + return SkSpecialImage::MakeFromRaster(source->internal_getProxy(), + SkIRect::MakeWH(bounds.width(), bounds.height()), + dst); } #ifndef SK_IGNORE_TO_STRING -- 2.7.4