diff options
author | Chris Dalton <csmartdalton@google.com> | 2018-06-22 12:44:19 -0600 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-06-22 19:10:57 +0000 |
commit | afde18f93035a30e1aeb0984c841611e69b14ee2 (patch) | |
tree | a520b80e0452faf9ec66ee3cf1b48fa420f67b31 /src | |
parent | 593693dbed85abc23a969c59abdfc2ad2c382873 (diff) |
ccpr: Recycle the stashed atlas's texture explicitly
This solution is more future-proof.
Bug: skia:
Change-Id: Ifa437a511336282d73befddea2656f3fcdb3f2ef
Reviewed-on: https://skia-review.googlesource.com/136964
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/ccpr/GrCCAtlas.cpp | 24 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCAtlas.h | 13 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPerFlushResources.cpp | 15 |
3 files changed, 37 insertions, 15 deletions
diff --git a/src/gpu/ccpr/GrCCAtlas.cpp b/src/gpu/ccpr/GrCCAtlas.cpp index 4eeddea9cb..b336e8c58f 100644 --- a/src/gpu/ccpr/GrCCAtlas.cpp +++ b/src/gpu/ccpr/GrCCAtlas.cpp @@ -77,12 +77,15 @@ GrCCAtlas::GrCCAtlas(GrPixelConfig pixelConfig, const Specs& specs, const GrCaps if (!resourceProvider) { return sk_sp<GrTexture>(); } - GrSurfaceDesc desc; - desc.fFlags = kRenderTarget_GrSurfaceFlag; - desc.fWidth = fWidth; - desc.fHeight = fHeight; - desc.fConfig = pixelConfig; - return resourceProvider->createTexture(desc, SkBudgeted::kYes); + if (!fBackingTexture) { + GrSurfaceDesc desc; + desc.fFlags = kRenderTarget_GrSurfaceFlag; + desc.fWidth = fWidth; + desc.fHeight = fHeight; + desc.fConfig = pixelConfig; + fBackingTexture = resourceProvider->createTexture(desc, SkBudgeted::kYes); + } + return fBackingTexture; }, GrProxyProvider::Renderable::kYes, kTextureOrigin, pixelConfig, caps); } @@ -165,13 +168,20 @@ sk_sp<GrCCAtlas::CachedAtlasInfo> GrCCAtlas::refOrMakeCachedAtlasInfo() { } sk_sp<GrRenderTargetContext> GrCCAtlas::makeRenderTargetContext( - GrOnFlushResourceProvider* onFlushRP) { + GrOnFlushResourceProvider* onFlushRP, sk_sp<GrTexture> backingTexture) { SkASSERT(!fTextureProxy->priv().isInstantiated()); // This method should only be called once. // Caller should have cropped any paths to the destination render target instead of asking for // an atlas larger than maxRenderTargetSize. SkASSERT(SkTMax(fHeight, fWidth) <= fMaxTextureSize); SkASSERT(fMaxTextureSize <= onFlushRP->caps()->maxRenderTargetSize()); + if (backingTexture) { + SkASSERT(backingTexture->config() == kAlpha_half_GrPixelConfig); + SkASSERT(backingTexture->width() == fWidth); + SkASSERT(backingTexture->height() == fHeight); + fBackingTexture = std::move(backingTexture); + } + sk_sp<GrRenderTargetContext> rtc = onFlushRP->makeRenderTargetContext(fTextureProxy, nullptr, nullptr); if (!rtc) { diff --git a/src/gpu/ccpr/GrCCAtlas.h b/src/gpu/ccpr/GrCCAtlas.h index 76d2a986e1..1a7ba1fb0a 100644 --- a/src/gpu/ccpr/GrCCAtlas.h +++ b/src/gpu/ccpr/GrCCAtlas.h @@ -11,8 +11,7 @@ #include "GrAllocator.h" #include "GrNonAtomicRef.h" #include "GrResourceKey.h" -#include "GrTypes.h" -#include "GrTypesPriv.h" +#include "GrTexture.h" #include "SkRefCnt.h" #include "SkSize.h" @@ -50,6 +49,8 @@ public: ~GrCCAtlas(); GrTextureProxy* textureProxy() const { return fTextureProxy.get(); } + int currentWidth() const { return fWidth; } + int currentHeight() const { return fHeight; } // Attempts to add a rect to the atlas. If successful, returns the integer offset from // device-space pixels where the path will be drawn, to atlas pixels where its mask resides. @@ -80,7 +81,12 @@ public: // Instantiates our texture proxy for the atlas and returns a pre-cleared GrRenderTargetContext // that the caller may use to render the content. After this call, it is no longer valid to call // addRect(), setUserBatchID(), or this method again. - sk_sp<GrRenderTargetContext> makeRenderTargetContext(GrOnFlushResourceProvider*); + // + // 'backingTexture', if provided, is a renderable texture with which to instantiate our proxy. + // If null then we will create a texture using the resource provider. The purpose of this param + // is to provide a guaranteed way to recycle a stashed atlas texture from a previous flush. + sk_sp<GrRenderTargetContext> makeRenderTargetContext(GrOnFlushResourceProvider*, + sk_sp<GrTexture> backingTexture = nullptr); private: class Node; @@ -100,6 +106,7 @@ private: sk_sp<CachedAtlasInfo> fCachedAtlasInfo; sk_sp<GrTextureProxy> fTextureProxy; + sk_sp<GrTexture> fBackingTexture; }; /** diff --git a/src/gpu/ccpr/GrCCPerFlushResources.cpp b/src/gpu/ccpr/GrCCPerFlushResources.cpp index a1cecb3f88..362ae77d79 100644 --- a/src/gpu/ccpr/GrCCPerFlushResources.cpp +++ b/src/gpu/ccpr/GrCCPerFlushResources.cpp @@ -279,13 +279,18 @@ bool GrCCPerFlushResources::finalize(GrOnFlushResourceProvider* onFlushRP, baseCopyInstance = endCopyInstance; } - // Release the stashed atlas before creating new one(s). This allows us to recycle the same - // underlying texture with the upcoming rendered atlases. - stashedAtlasProxy = nullptr; - // Render the coverage count atlas(es). for (GrCCAtlasStack::Iter atlas(fRenderedAtlasStack); atlas.next();) { - if (auto rtc = atlas->makeRenderTargetContext(onFlushRP)) { + // Copies will be finished by the time we get to this atlas. See if we can recycle the + // stashed atlas texture instead of creating a new one. + sk_sp<GrTexture> backingTexture; + if (stashedAtlasProxy && atlas->currentWidth() == stashedAtlasProxy->width() && + atlas->currentHeight() == stashedAtlasProxy->height()) { + backingTexture = sk_ref_sp(stashedAtlasProxy->priv().peekTexture()); + stashedAtlasProxy = nullptr; + } + + if (auto rtc = atlas->makeRenderTargetContext(onFlushRP, std::move(backingTexture))) { auto op = RenderAtlasOp::Make(rtc->surfPriv().getContext(), sk_ref_sp(this), atlas->getUserBatchID(), atlas->drawBounds()); rtc->addDrawOp(GrNoClip(), std::move(op)); |