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());
}
Example #2
0
    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);
    }