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); }
sk_sp<SkSurface> onMakeTightSurface(const SkImageFilter::OutputProperties& outProps, const SkISize& size, SkAlphaType at) const override { SkColorSpace* colorSpace = outProps.colorSpace(); SkColorType colorType = colorSpace && colorSpace->gammaIsLinear() ? kRGBA_F16_SkColorType : kRGBA_8888_SkColorType; SkImageInfo info = SkImageInfo::Make(size.width(), size.height(), colorType, at, sk_ref_sp(colorSpace)); return SkSurface::MakeRenderTarget(fContext, SkBudgeted::kYes, info); }
sk_sp<SkSpecialSurface> onMakeSurface(const SkImageFilter::OutputProperties& outProps, const SkISize& size, SkAlphaType at) const override { if (!fContext) { return nullptr; } SkColorSpace* colorSpace = outProps.colorSpace(); return SkSpecialSurface::MakeRenderTarget( fContext, size.width(), size.height(), GrRenderableConfigForColorSpace(colorSpace), sk_ref_sp(colorSpace)); }
sk_sp<SkSurface> onMakeTightSurface(const SkImageFilter::OutputProperties& outProps, const SkISize& size, SkAlphaType at) const override { #if RASTER_IMAGE_FILTERS_SUPPORT_SRGB_AND_F16 SkColorSpace* colorSpace = outProps.colorSpace(); #else SkColorSpace* colorSpace = nullptr; #endif SkColorType colorType = colorSpace && colorSpace->gammaIsLinear() ? kRGBA_F16_SkColorType : kN32_SkColorType; SkImageInfo info = SkImageInfo::Make(size.width(), size.height(), colorType, at, sk_ref_sp(colorSpace)); return SkSurface::MakeRaster(info); }