diff options
author | Robert Phillips <robertphillips@google.com> | 2017-02-24 08:37:13 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-02-24 14:21:50 +0000 |
commit | 875218ebd816eb8931c64c5018ce2dc9bc8fd695 (patch) | |
tree | e2936879d44b66aea231b3098342866b9ddf714c | |
parent | e3d4421e67d328fc0994bbfd25deab0ce3964dc2 (diff) |
Wrap cached GrTextures in GrTextureProxies (e.g., blur profiles, nine-patch blurs, etc.)
This is pulled out of: https://skia-review.googlesource.com/c/8823/ (Remove GrFragmentProcessor-derived class' GrTexture-based ctors)
Change-Id: I5feac04dc1bf54bd74c65febdf6bba9e7ce28f55
Reviewed-on: https://skia-review.googlesource.com/8942
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
-rw-r--r-- | src/effects/GrCircleBlurFragmentProcessor.cpp | 40 | ||||
-rw-r--r-- | src/effects/GrCircleBlurFragmentProcessor.h | 8 | ||||
-rw-r--r-- | src/effects/SkBlurMaskFilter.cpp | 66 | ||||
-rw-r--r-- | src/gpu/GrClipStackClip.cpp | 48 | ||||
-rw-r--r-- | src/gpu/GrClipStackClip.h | 10 | ||||
-rw-r--r-- | src/gpu/SkGr.cpp | 4 | ||||
-rw-r--r-- | tests/ClipStackTest.cpp | 7 |
7 files changed, 109 insertions, 74 deletions
diff --git a/src/effects/GrCircleBlurFragmentProcessor.cpp b/src/effects/GrCircleBlurFragmentProcessor.cpp index 6332895b84..de4bb58231 100644 --- a/src/effects/GrCircleBlurFragmentProcessor.cpp +++ b/src/effects/GrCircleBlurFragmentProcessor.cpp @@ -82,15 +82,17 @@ void GrCircleBlurFragmentProcessor::GLSLProcessor::onSetData(const GrGLSLProgram /////////////////////////////////////////////////////////////////////////////// -GrCircleBlurFragmentProcessor::GrCircleBlurFragmentProcessor(const SkRect& circle, +GrCircleBlurFragmentProcessor::GrCircleBlurFragmentProcessor(GrTextureProvider* textureProvider, + const SkRect& circle, float textureRadius, float solidRadius, - GrTexture* blurProfile) + sk_sp<GrTextureProxy> blurProfile) : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag) , fCircle(circle) , fSolidRadius(solidRadius) , fTextureRadius(textureRadius) - , fBlurProfileSampler(blurProfile, GrSamplerParams::kBilerp_FilterMode) { + , fBlurProfileSampler(textureProvider, std::move(blurProfile), + GrSamplerParams::kBilerp_FilterMode) { this->initClassID<GrCircleBlurFragmentProcessor>(); this->addTextureSampler(&fBlurProfileSampler); } @@ -258,8 +260,10 @@ static uint8_t* create_half_plane_profile(int profileWidth) { return profile; } -static GrTexture* create_profile_texture(GrTextureProvider* textureProvider, const SkRect& circle, - float sigma, float* solidRadius, float* textureRadius) { +static sk_sp<GrTextureProxy> create_profile_texture(GrTextureProvider* textureProvider, + const SkRect& circle, + float sigma, + float* solidRadius, float* textureRadius) { float circleR = circle.width() / 2.0f; // Profile textures are cached by the ratio of sigma to circle radius and by the size of the // profile texture (binned by powers of 2). @@ -295,7 +299,8 @@ static GrTexture* create_profile_texture(GrTextureProvider* textureProvider, con builder[0] = sigmaToCircleRRatioFixed; builder.finish(); - GrTexture *blurProfile = textureProvider->findAndRefTextureByUniqueKey(key); + // MDB TODO (caching): this side-steps the issue of texture proxies with unique IDs + sk_sp<GrTexture> blurProfile(textureProvider->findAndRefTextureByUniqueKey(key)); if (!blurProfile) { static constexpr int kProfileTextureWidth = 512; GrSurfaceDesc texDesc; @@ -313,28 +318,33 @@ static GrTexture* create_profile_texture(GrTextureProvider* textureProvider, con kProfileTextureWidth)); } - blurProfile = textureProvider->createTexture(texDesc, SkBudgeted::kYes, profile.get(), 0); - if (blurProfile) { - textureProvider->assignUniqueKeyToTexture(key, blurProfile); + blurProfile.reset(textureProvider->createTexture(texDesc, SkBudgeted::kYes, + profile.get(), 0)); + if (!blurProfile) { + return nullptr; } + + textureProvider->assignUniqueKeyToTexture(key, blurProfile.get()); } - return blurProfile; + return GrSurfaceProxy::MakeWrapped(std::move(blurProfile)); } ////////////////////////////////////////////////////////////////////////////// -sk_sp<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(GrTextureProvider*textureProvider, +sk_sp<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(GrTextureProvider* textureProvider, const SkRect& circle, float sigma) { float solidRadius; float textureRadius; - sk_sp<GrTexture> profile(create_profile_texture(textureProvider, circle, sigma, - &solidRadius, &textureRadius)); + sk_sp<GrTextureProxy> profile(create_profile_texture(textureProvider, circle, sigma, + &solidRadius, &textureRadius)); if (!profile) { return nullptr; } - return sk_sp<GrFragmentProcessor>( - new GrCircleBlurFragmentProcessor(circle, textureRadius, solidRadius, profile.get())); + return sk_sp<GrFragmentProcessor>(new GrCircleBlurFragmentProcessor(textureProvider, + circle, + textureRadius, solidRadius, + std::move(profile))); } ////////////////////////////////////////////////////////////////////////////// diff --git a/src/effects/GrCircleBlurFragmentProcessor.h b/src/effects/GrCircleBlurFragmentProcessor.h index f577cc7e42..9b1fdbf08a 100644 --- a/src/effects/GrCircleBlurFragmentProcessor.h +++ b/src/effects/GrCircleBlurFragmentProcessor.h @@ -34,8 +34,7 @@ public: return str; } - static sk_sp<GrFragmentProcessor> Make(GrTextureProvider*textureProvider, - const SkRect& circle, float sigma); + static sk_sp<GrFragmentProcessor> Make(GrTextureProvider*, const SkRect& circle, float sigma); private: // This nested GLSL processor implementation is defined in the cpp file. @@ -46,8 +45,9 @@ private: * The x texture coord should map from 0 to 1 across the radius range of solidRadius to * solidRadius + textureRadius. */ - GrCircleBlurFragmentProcessor(const SkRect& circle, float textureRadius, float innerRadius, - GrTexture* blurProfile); + GrCircleBlurFragmentProcessor(GrTextureProvider*, const SkRect& circle, + float textureRadius, float innerRadius, + sk_sp<GrTextureProxy> blurProfile); GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp index 69b518235e..507b6975f8 100644 --- a/src/effects/SkBlurMaskFilter.cpp +++ b/src/effects/SkBlurMaskFilter.cpp @@ -780,7 +780,7 @@ public: return nullptr; } - sk_sp<GrTexture> blurProfile(CreateBlurProfileTexture(textureProvider, sigma)); + sk_sp<GrTextureProxy> blurProfile(CreateBlurProfileTexture(textureProvider, sigma)); if (!blurProfile) { return nullptr; } @@ -804,8 +804,8 @@ public: precision = kDefault_GrSLPrecision; } - return sk_sp<GrFragmentProcessor>( - new GrRectBlurEffect(rect, sigma, blurProfile.get(), precision)); + return sk_sp<GrFragmentProcessor>(new GrRectBlurEffect(textureProvider, rect, sigma, + std::move(blurProfile), precision)); } const SkRect& getRect() const { return fRect; } @@ -813,8 +813,8 @@ public: GrSLPrecision precision() const { return fPrecision; } private: - GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blurProfile, - GrSLPrecision fPrecision); + GrRectBlurEffect(GrTextureProvider*, const SkRect& rect, float sigma, + sk_sp<GrTextureProxy> blurProfile, GrSLPrecision fPrecision); GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; @@ -822,7 +822,7 @@ private: bool onIsEqual(const GrFragmentProcessor&) const override; - static GrTexture* CreateBlurProfileTexture(GrTextureProvider*, float sigma); + static sk_sp<GrTextureProxy> CreateBlurProfileTexture(GrTextureProvider*, float sigma); SkRect fRect; float fSigma; @@ -940,8 +940,9 @@ void GrGLRectBlurEffect::onSetData(const GrGLSLProgramDataManager& pdman, pdman.set1f(fProfileSizeUniform, SkScalarCeilToScalar(6*rbe.getSigma())); } -GrTexture* GrRectBlurEffect::CreateBlurProfileTexture(GrTextureProvider* textureProvider, - float sigma) { +// MDB TODO (caching): This side-steps the issue of texture proxies with unique IDs +sk_sp<GrTextureProxy> GrRectBlurEffect::CreateBlurProfileTexture(GrTextureProvider* textureProvider, + float sigma) { GrSurfaceDesc texDesc; unsigned int profileSize = SkScalarCeilToInt(6*sigma); @@ -957,26 +958,31 @@ GrTexture* GrRectBlurEffect::CreateBlurProfileTexture(GrTextureProvider* texture builder[0] = profileSize; builder.finish(); - GrTexture *blurProfile = textureProvider->findAndRefTextureByUniqueKey(key); + sk_sp<GrTexture> blurProfile(textureProvider->findAndRefTextureByUniqueKey(key)); if (!blurProfile) { std::unique_ptr<uint8_t[]> profile(SkBlurMask::ComputeBlurProfile(sigma)); - blurProfile = textureProvider->createTexture(texDesc, SkBudgeted::kYes, profile.get(), 0); - if (blurProfile) { - textureProvider->assignUniqueKeyToTexture(key, blurProfile); + blurProfile.reset(textureProvider->createTexture(texDesc, SkBudgeted::kYes, + profile.get(), 0)); + if (!blurProfile) { + return nullptr; } + + textureProvider->assignUniqueKeyToTexture(key, blurProfile.get()); } - return blurProfile; + return GrSurfaceProxy::MakeWrapped(std::move(blurProfile)); } -GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture* blurProfile, +GrRectBlurEffect::GrRectBlurEffect(GrTextureProvider* textureProvider, + const SkRect& rect, float sigma, + sk_sp<GrTextureProxy> blurProfile, GrSLPrecision precision) : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag) , fRect(rect) , fSigma(sigma) - , fBlurProfileSampler(blurProfile) + , fBlurProfileSampler(textureProvider, std::move(blurProfile)) , fPrecision(precision) { this->initClassID<GrRectBlurEffect>(); this->addTextureSampler(&fBlurProfileSampler); @@ -1070,7 +1076,7 @@ public: float sigma, float xformedSigma, const SkRRect& srcRRect, const SkRRect& devRRect); - virtual ~GrRRectBlurEffect() {} + ~GrRRectBlurEffect() override {} const char* name() const override { return "GrRRectBlur"; } const SkRRect& getRRect() const { return fRRect; } @@ -1079,7 +1085,8 @@ public: private: GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; - GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture); + GrRRectBlurEffect(GrTextureProvider*, float sigma, const SkRRect&, + sk_sp<GrTextureProxy> profileProxy); virtual void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override; @@ -1095,10 +1102,11 @@ private: typedef GrFragmentProcessor INHERITED; }; -static sk_sp<GrTexture> find_or_create_rrect_blur_mask(GrContext* context, - const SkRRect& rrectToDraw, - const SkISize& size, - float xformedSigma) { +// MDB TODO (caching): This side-steps the issue of texture proxies with unique IDs +static sk_sp<GrTextureProxy> find_or_create_rrect_blur_mask(GrContext* context, + const SkRRect& rrectToDraw, + const SkISize& size, + float xformedSigma) { static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); GrUniqueKey key; GrUniqueKey::Builder builder(&key, kDomain, 9); @@ -1152,7 +1160,7 @@ static sk_sp<GrTexture> find_or_create_rrect_blur_mask(GrContext* context, context->textureProvider()->assignUniqueKeyToTexture(key, mask.get()); } - return mask; + return GrSurfaceProxy::MakeWrapped(std::move(mask)); } sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context, @@ -1186,21 +1194,25 @@ sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context, return nullptr; } - sk_sp<GrTexture> mask(find_or_create_rrect_blur_mask(context, rrectToDraw, size, xformedSigma)); + sk_sp<GrTextureProxy> mask(find_or_create_rrect_blur_mask(context, rrectToDraw, + size, xformedSigma)); if (!mask) { return nullptr; } - return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(xformedSigma, + return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(context->textureProvider(), + xformedSigma, devRRect, - mask.get())); + std::move(mask))); } -GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTexture* ninePatchTexture) +GrRRectBlurEffect::GrRRectBlurEffect(GrTextureProvider* textureProvider, + float sigma, const SkRRect& rrect, + sk_sp<GrTextureProxy> ninePatchProxy) : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag) , fRRect(rrect) , fSigma(sigma) - , fNinePatchSampler(ninePatchTexture) { + , fNinePatchSampler(textureProvider, std::move(ninePatchProxy)) { this->initClassID<GrRRectBlurEffect>(); this->addTextureSampler(&fNinePatchSampler); } diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp index 7b50d52332..375ee8ba13 100644 --- a/src/gpu/GrClipStackClip.cpp +++ b/src/gpu/GrClipStackClip.cpp @@ -85,10 +85,11 @@ void GrClipStackClip::getConservativeBounds(int width, int height, SkIRect* devR //////////////////////////////////////////////////////////////////////////////// // set up the draw state to enable the aa clipping mask. -static sk_sp<GrFragmentProcessor> create_fp_for_mask(GrTexture* result, +static sk_sp<GrFragmentProcessor> create_fp_for_mask(GrContext* context, + sk_sp<GrTextureProxy> mask, const SkIRect &devBound) { SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); - return GrDeviceSpaceTextureDecalFragmentProcessor::Make(result, domainTexels, + return GrDeviceSpaceTextureDecalFragmentProcessor::Make(context, std::move(mask), domainTexels, {devBound.fLeft, devBound.fTop}); } @@ -338,7 +339,7 @@ bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTar // If the stencil buffer is multisampled we can use it to do everything. if (!renderTargetContext->isStencilBufferMultisampled() && reducedClip.requiresAA()) { - sk_sp<GrTexture> result; + sk_sp<GrTextureProxy> result; if (UseSWOnlyPath(context, hasUserStencilSettings, renderTargetContext, reducedClip)) { // The clip geometry is complex enough that it will be more efficient to create it // entirely in software @@ -352,7 +353,7 @@ bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTar // clipSpace bounds. We determine the mask's position WRT to the render target here. SkIRect rtSpaceMaskBounds = reducedClip.ibounds(); rtSpaceMaskBounds.offset(-fOrigin); - out->addCoverageFP(create_fp_for_mask(result.get(), rtSpaceMaskBounds)); + out->addCoverageFP(create_fp_for_mask(context, std::move(result), rtSpaceMaskBounds)); return true; } // if alpha clip mask creation fails fall through to the non-AA code paths @@ -409,13 +410,16 @@ static void add_invalidate_on_pop_message(const SkClipStack& stack, int32_t clip SkDEBUGFAIL("Gen ID was not found in stack."); } -sk_sp<GrTexture> GrClipStackClip::createAlphaClipMask(GrContext* context, - const GrReducedClip& reducedClip) const { +// MDB TODO (caching): this side-steps the issue of texture proxies cached by unique ID +sk_sp<GrTextureProxy> GrClipStackClip::createAlphaClipMask(GrContext* context, + const GrReducedClip& reducedClip) const { GrResourceProvider* resourceProvider = context->resourceProvider(); GrUniqueKey key; create_clip_mask_key(reducedClip.elementsGenID(), reducedClip.ibounds(), &key); - if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)) { - return sk_sp<GrTexture>(texture); + + sk_sp<GrTexture> texture(resourceProvider->findAndRefTextureByUniqueKey(key)); + if (texture) { + return GrSurfaceProxy::MakeWrapped(std::move(texture)); } sk_sp<GrRenderTargetContext> rtc(context->makeRenderTargetContextWithFallback( @@ -432,22 +436,32 @@ sk_sp<GrTexture> GrClipStackClip::createAlphaClipMask(GrContext* context, return nullptr; } - sk_sp<GrTexture> texture(rtc->asTexture()); - if (!texture) { + sk_sp<GrTextureProxy> result(rtc->asTextureProxyRef()); + if (!result) { return nullptr; } - texture->resourcePriv().setUniqueKey(key); + GrTexture* tex = result->instantiate(context->textureProvider()); + if (!tex) { + return nullptr; + } + + tex->resourcePriv().setUniqueKey(key); add_invalidate_on_pop_message(*fStack, reducedClip.elementsGenID(), key); - return texture; + + return result; } -sk_sp<GrTexture> GrClipStackClip::createSoftwareClipMask(GrContext* context, - const GrReducedClip& reducedClip) const { +// MDB TODO (caching): This side-steps the caching of texture proxies by unique ID +sk_sp<GrTextureProxy> GrClipStackClip::createSoftwareClipMask( + GrContext* context, + const GrReducedClip& reducedClip) const { GrUniqueKey key; create_clip_mask_key(reducedClip.elementsGenID(), reducedClip.ibounds(), &key); - if (GrTexture* texture = context->textureProvider()->findAndRefTextureByUniqueKey(key)) { - return sk_sp<GrTexture>(texture); + + sk_sp<GrTexture> texture(context->textureProvider()->findAndRefTextureByUniqueKey(key)); + if (texture) { + return GrSurfaceProxy::MakeWrapped(std::move(texture)); } // The mask texture may be larger than necessary. We round out the clip space bounds and pin @@ -510,5 +524,5 @@ sk_sp<GrTexture> GrClipStackClip::createSoftwareClipMask(GrContext* context, tex->resourcePriv().setUniqueKey(key); add_invalidate_on_pop_message(*fStack, reducedClip.elementsGenID(), key); - return sk_ref_sp(tex); + return result; } diff --git a/src/gpu/GrClipStackClip.h b/src/gpu/GrClipStackClip.h index 1c4d40b173..b8c5d17286 100644 --- a/src/gpu/GrClipStackClip.h +++ b/src/gpu/GrClipStackClip.h @@ -12,9 +12,7 @@ #include "SkClipStack.h" class GrPathRenderer; -class GrTexture; -class GrTextureProvider; -class GrUniqueKey; +class GrTextureProxy; /** * GrClipStackClip can apply a generic SkClipStack to the draw state. It may need to generate an @@ -40,7 +38,7 @@ public: bool isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA* aa) const override; - sk_sp<GrTexture> testingOnly_createClipMask(GrContext*) const; + sk_sp<GrTextureProxy> testingOnly_createClipMask(GrContext*) const; static const char kMaskTestTag[]; private: @@ -54,10 +52,10 @@ private: // Creates an alpha mask of the clip. The mask is a rasterization of elements through the // rect specified by clipSpaceIBounds. - sk_sp<GrTexture> createAlphaClipMask(GrContext*, const GrReducedClip&) const; + sk_sp<GrTextureProxy> createAlphaClipMask(GrContext*, const GrReducedClip&) const; // Similar to createAlphaClipMask but it rasterizes in SW and uploads to the result texture. - sk_sp<GrTexture> createSoftwareClipMask(GrContext*, const GrReducedClip&) const; + sk_sp<GrTextureProxy> createSoftwareClipMask(GrContext*, const GrReducedClip&) const; static bool UseSWOnlyPath(GrContext*, bool hasUserStencilSettings, diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index 45f6e6eb92..fe7e98c8d9 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -269,8 +269,8 @@ GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap, nullptr, scaleAdjust); } -// For better or for worse, this method currently sidesteps the issue of caching an uninstantiated -// proxy via a key. +// MDB TODO (caching): For better or for worse, this method currently side-steps the issue of +// caching an uninstantiated proxy via a key. sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrContext* context, const SkBitmap& bitmap) { GrUniqueKey originalKey; diff --git a/tests/ClipStackTest.cpp b/tests/ClipStackTest.cpp index 744ef18d17..e3980504f2 100644 --- a/tests/ClipStackTest.cpp +++ b/tests/ClipStackTest.cpp @@ -1413,7 +1413,7 @@ DEF_TEST(ClipStack, reporter) { ////////////////////////////////////////////////////////////////////////////// #if SK_SUPPORT_GPU -sk_sp<GrTexture> GrClipStackClip::testingOnly_createClipMask(GrContext* context) const { +sk_sp<GrTextureProxy> GrClipStackClip::testingOnly_createClipMask(GrContext* context) const { const GrReducedClip reducedClip(*fStack, SkRect::MakeWH(512, 512), 0); return this->createSoftwareClipMask(context, reducedClip); } @@ -1440,8 +1440,9 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ClipMaskCache, reporter, ctxInfo) { m.setTranslate(0.5, 0.5); stack.save(); stack.clipPath(path, m, SkClipOp::kIntersect, true); - auto mask = GrClipStackClip(&stack).testingOnly_createClipMask(context); - REPORTER_ASSERT(reporter, 0 == strcmp(mask->getUniqueKey().tag(), kTag)); + sk_sp<GrTextureProxy> mask = GrClipStackClip(&stack).testingOnly_createClipMask(context); + GrTexture* tex = mask->instantiate(context->textureProvider()); + REPORTER_ASSERT(reporter, 0 == strcmp(tex->getUniqueKey().tag(), kTag)); // Make sure mask isn't pinned in cache. mask.reset(nullptr); context->flush(); |