static sk_sp<SkSpecialImage> apply_morphology( GrContext* context, SkSpecialImage* input, const SkIRect& rect, GrMorphologyEffect::Type morphType, SkISize radius, const SkImageFilter::OutputProperties& outputProperties) { sk_sp<GrTextureProxy> srcTexture(input->asTextureProxyRef(context)); SkASSERT(srcTexture); sk_sp<SkColorSpace> colorSpace = sk_ref_sp(outputProperties.colorSpace()); GrPixelConfig config = SkColorType2GrPixelConfig(outputProperties.colorType()); // setup new clip const GrFixedClip clip(SkIRect::MakeWH(srcTexture->width(), srcTexture->height())); const SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height()); SkIRect srcRect = rect; SkASSERT(radius.width() > 0 || radius.height() > 0); if (radius.fWidth > 0) { sk_sp<GrRenderTargetContext> dstRTContext( context->contextPriv().makeDeferredRenderTargetContext( SkBackingFit::kApprox, rect.width(), rect.height(), config, colorSpace)); if (!dstRTContext) { return nullptr; } apply_morphology_pass(dstRTContext.get(), clip, std::move(srcTexture), srcRect, dstRect, radius.fWidth, morphType, GrMorphologyEffect::Direction::kX); SkIRect clearRect = SkIRect::MakeXYWH(dstRect.fLeft, dstRect.fBottom, dstRect.width(), radius.fHeight); GrColor clearColor = GrMorphologyEffect::Type::kErode == morphType ? SK_ColorWHITE : SK_ColorTRANSPARENT; dstRTContext->clear(&clearRect, clearColor, GrRenderTargetContext::CanClearFullscreen::kNo); srcTexture = dstRTContext->asTextureProxyRef(); srcRect = dstRect; } if (radius.fHeight > 0) { sk_sp<GrRenderTargetContext> dstRTContext( context->contextPriv().makeDeferredRenderTargetContext( SkBackingFit::kApprox, rect.width(), rect.height(), config, colorSpace)); if (!dstRTContext) { return nullptr; } apply_morphology_pass(dstRTContext.get(), clip, std::move(srcTexture), srcRect, dstRect, radius.fHeight, morphType, GrMorphologyEffect::Direction::kY); srcTexture = dstRTContext->asTextureProxyRef(); } return SkSpecialImage::MakeDeferredFromGpu(context, SkIRect::MakeWH(rect.width(), rect.height()), kNeedNewImageUniqueID_SpecialImage, std::move(srcTexture), std::move(colorSpace), &input->props()); }
static sk_sp<SkSpecialImage> apply_morphology(GrContext* context, SkSpecialImage* input, const SkIRect& rect, GrMorphologyEffect::MorphologyType morphType, SkISize radius) { SkAutoTUnref<GrTexture> srcTexture(input->asTextureRef(context)); SkASSERT(srcTexture); // setup new clip GrClip clip(SkRect::MakeWH(SkIntToScalar(srcTexture->width()), SkIntToScalar(srcTexture->height()))); SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height()); GrSurfaceDesc desc; desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fWidth = rect.width(); desc.fHeight = rect.height(); desc.fConfig = kSkia8888_GrPixelConfig; SkIRect srcRect = rect; SkASSERT(radius.width() > 0 || radius.height() > 0); if (radius.fWidth > 0) { GrTexture* scratch = context->textureProvider()->createApproxTexture(desc); if (!scratch) { return nullptr; } SkAutoTUnref<GrDrawContext> dstDrawContext( context->drawContext(scratch->asRenderTarget())); if (!dstDrawContext) { return nullptr; } apply_morphology_pass(dstDrawContext, clip, srcTexture, srcRect, dstRect, radius.fWidth, morphType, Gr1DKernelEffect::kX_Direction); SkIRect clearRect = SkIRect::MakeXYWH(dstRect.fLeft, dstRect.fBottom, dstRect.width(), radius.fHeight); GrColor clearColor = GrMorphologyEffect::kErode_MorphologyType == morphType ? SK_ColorWHITE : SK_ColorTRANSPARENT; dstDrawContext->clear(&clearRect, clearColor, false); srcTexture.reset(scratch); srcRect = dstRect; } if (radius.fHeight > 0) { GrTexture* scratch = context->textureProvider()->createApproxTexture(desc); if (!scratch) { return nullptr; } SkAutoTUnref<GrDrawContext> dstDrawContext( context->drawContext(scratch->asRenderTarget())); if (!dstDrawContext) { return nullptr; } apply_morphology_pass(dstDrawContext, clip, srcTexture, srcRect, dstRect, radius.fHeight, morphType, Gr1DKernelEffect::kY_Direction); srcTexture.reset(scratch); } return SkSpecialImage::MakeFromGpu(input->internal_getProxy(), SkIRect::MakeWH(rect.width(), rect.height()), kNeedNewImageUniqueID_SpecialImage, srcTexture, &input->props()); }