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()); }
sk_sp<SkSpecialSurface> onMakeSurface(const SkImageFilter::OutputProperties& outProps, const SkISize& size, SkAlphaType at, const SkSurfaceProps* props) const override { if (!fContext) { return nullptr; } return SkSpecialSurface::MakeRenderTarget( fContext, size.width(), size.height(), SkColorType2GrPixelConfig(outProps.colorType()), sk_ref_sp(outProps.colorSpace()), props); }