diff options
author | Greg Daniel <egdaniel@google.com> | 2018-02-08 15:05:44 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-02-08 20:33:40 +0000 |
commit | 457469c7a0c879b9d8ff8ed9fabe3f3dcab06097 (patch) | |
tree | 92ef5dcb793bbe9406730b1576c51bcc6042b86c | |
parent | 5635631c8887db678e6123c191ae68456b60d2a7 (diff) |
Make non-ddl lazy proxys clean-up and delete their callbacks immediately after instanstation.
This makes sure resources are released and free'd as soon as possible if we
no longer need them.
Bug: skia:
Change-Id: Ic216987649c54183f8cbbff90a633860a97754b3
Reviewed-on: https://skia-review.googlesource.com/105721
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
-rw-r--r-- | include/private/GrRenderTargetProxy.h | 4 | ||||
-rw-r--r-- | include/private/GrSurfaceProxy.h | 19 | ||||
-rw-r--r-- | include/private/GrTextureProxy.h | 4 | ||||
-rw-r--r-- | src/gpu/GrProxyProvider.cpp | 26 | ||||
-rw-r--r-- | src/gpu/GrProxyProvider.h | 1 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetProxy.cpp | 3 | ||||
-rw-r--r-- | src/gpu/GrSurfaceProxy.cpp | 11 | ||||
-rw-r--r-- | src/gpu/GrSurfaceProxyPriv.h | 8 | ||||
-rw-r--r-- | src/gpu/GrTextureProxy.cpp | 8 | ||||
-rw-r--r-- | src/gpu/GrTextureRenderTargetProxy.cpp | 7 | ||||
-rw-r--r-- | src/gpu/GrTextureRenderTargetProxy.h | 5 | ||||
-rw-r--r-- | tests/LazyProxyTest.cpp | 51 |
12 files changed, 100 insertions, 47 deletions
diff --git a/include/private/GrRenderTargetProxy.h b/include/private/GrRenderTargetProxy.h index b0018a7ad8..1672fd9357 100644 --- a/include/private/GrRenderTargetProxy.h +++ b/include/private/GrRenderTargetProxy.h @@ -77,8 +77,8 @@ protected: // // The minimal knowledge version is used for CCPR where we are generating an atlas but we do not // know the final size until flush time. - GrRenderTargetProxy(LazyInstantiateCallback&&, const GrSurfaceDesc&, SkBackingFit, SkBudgeted, - uint32_t flags); + GrRenderTargetProxy(LazyInstantiateCallback&&, LazyInstantiationType lazyType, + const GrSurfaceDesc&, SkBackingFit, SkBudgeted, uint32_t flags); // Wrapped version GrRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceOrigin); diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h index 84353eee12..6bfb700a0f 100644 --- a/include/private/GrSurfaceProxy.h +++ b/include/private/GrSurfaceProxy.h @@ -182,6 +182,11 @@ private: class GrSurfaceProxy : public GrIORefProxy { public: + enum class LazyInstantiationType { + kSingleUse, // Instantiation callback is allowed to be called only once + kMultipleUse, // Instantiation callback can be called multiple times. + }; + enum class LazyState { kNot, // The proxy is instantiated or does not have a lazy callback kPartially, // The proxy has a lazy callback but knows basic information about itself. @@ -351,7 +356,8 @@ public: protected: // Deferred version GrSurfaceProxy(const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted, uint32_t flags) - : GrSurfaceProxy(nullptr, desc, fit, budgeted, flags) { + : GrSurfaceProxy(nullptr, LazyInstantiationType::kSingleUse, + desc, fit, budgeted, flags) { // Note: this ctor pulls a new uniqueID from the same pool at the GrGpuResources } @@ -359,8 +365,9 @@ protected: GrSurfaceOrigin* outOrigin)>; // Lazy-callback version - GrSurfaceProxy(LazyInstantiateCallback&& callback, const GrSurfaceDesc& desc, - SkBackingFit fit, SkBudgeted budgeted, uint32_t flags); + GrSurfaceProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType, + const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted, + uint32_t flags); // Wrapped version GrSurfaceProxy(sk_sp<GrSurface> surface, GrSurfaceOrigin origin, SkBackingFit fit); @@ -408,6 +415,12 @@ private: const UniqueID fUniqueID; // set from the backing resource for wrapped resources LazyInstantiateCallback fLazyInstantiateCallback; + // If this is set to kSingleuse, then after one call to fLazyInstantiateCallback we will cleanup + // the lazy callback and then delete it. This will allow for any refs and resources being held + // by the standard function to be released. This is specifically useful in non-dll cases where + // we make lazy proxies and instantiate them immediately. + // Note: This is ignored if fLazyInstantiateCallback is null. + LazyInstantiationType fLazyInstantiationType; SkDEBUGCODE(virtual void validateLazySurface(const GrSurface*) = 0;) static const size_t kInvalidGpuMemorySize = ~static_cast<size_t>(0); diff --git a/include/private/GrTextureProxy.h b/include/private/GrTextureProxy.h index 3aee3de361..3adfa58b74 100644 --- a/include/private/GrTextureProxy.h +++ b/include/private/GrTextureProxy.h @@ -80,8 +80,8 @@ protected: // // The minimal knowledge version is used for CCPR where we are generating an atlas but we do not // know the final size until flush time. - GrTextureProxy(LazyInstantiateCallback&&, const GrSurfaceDesc& desc, GrMipMapped, - SkBackingFit fit, SkBudgeted budgeted, uint32_t flags); + GrTextureProxy(LazyInstantiateCallback&&, LazyInstantiationType, const GrSurfaceDesc& desc, + GrMipMapped, SkBackingFit fit, SkBudgeted budgeted, uint32_t flags); // Wrapped version GrTextureProxy(sk_sp<GrSurface>, GrSurfaceOrigin); diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp index 0076a1a82d..dd2a1b7e13 100644 --- a/src/gpu/GrProxyProvider.cpp +++ b/src/gpu/GrProxyProvider.cpp @@ -537,11 +537,17 @@ sk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) || (desc.fWidth > 0 && desc.fHeight > 0)); uint32_t flags = GrResourceProvider::kNoPendingIO_Flag; + + using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType; + // For non-ddl draws always make lazy proxy's single use. + LazyInstantiationType lazyType = fResourceProvider ? LazyInstantiationType::kSingleUse + : LazyInstantiationType::kMultipleUse; + return sk_sp<GrTextureProxy>(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags) ? - new GrTextureRenderTargetProxy(std::move(callback), desc, + new GrTextureRenderTargetProxy(std::move(callback), lazyType, desc, mipMapped, fit, budgeted, flags) : - new GrTextureProxy(std::move(callback), desc, mipMapped, fit, - budgeted, flags)); + new GrTextureProxy(std::move(callback), lazyType, desc, mipMapped, + fit, budgeted, flags)); } sk_sp<GrRenderTargetProxy> GrProxyProvider::createLazyRenderTargetProxy( @@ -553,13 +559,19 @@ sk_sp<GrRenderTargetProxy> GrProxyProvider::createLazyRenderTargetProxy( SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) || (desc.fWidth > 0 && desc.fHeight > 0)); uint32_t flags = GrResourceProvider::kNoPendingIO_Flag; + + using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType; + // For non-ddl draws always make lazy proxy's single use. + LazyInstantiationType lazyType = fResourceProvider ? LazyInstantiationType::kSingleUse + : LazyInstantiationType::kMultipleUse; + if (Textureable::kYes == textureable) { - return sk_sp<GrRenderTargetProxy>(new GrTextureRenderTargetProxy(std::move(callback), desc, - mipMapped, fit, budgeted, - flags)); + return sk_sp<GrRenderTargetProxy>(new GrTextureRenderTargetProxy(std::move(callback), + lazyType, desc, mipMapped, + fit, budgeted, flags)); } - return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(std::move(callback), desc, + return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(std::move(callback), lazyType, desc, fit, budgeted, flags)); } diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h index af661c1f4d..0147485558 100644 --- a/src/gpu/GrProxyProvider.h +++ b/src/gpu/GrProxyProvider.h @@ -156,7 +156,6 @@ public: using LazyInstantiateCallback = std::function<sk_sp<GrSurface>(GrResourceProvider*, GrSurfaceOrigin* outOrigin)>; - enum class Textureable : bool { kNo = false, kYes = true diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp index 59dcd73a3e..914ade538e 100644 --- a/src/gpu/GrRenderTargetProxy.cpp +++ b/src/gpu/GrRenderTargetProxy.cpp @@ -36,10 +36,11 @@ GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, const GrSurfaceDesc // Lazy-callback version GrRenderTargetProxy::GrRenderTargetProxy(LazyInstantiateCallback&& callback, + LazyInstantiationType lazyType, const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted, uint32_t flags) - : INHERITED(std::move(callback), desc, fit, budgeted, flags) + : INHERITED(std::move(callback), lazyType, desc, fit, budgeted, flags) , fSampleCnt(desc.fSampleCnt) , fNeedsStencil(false) , fRenderTargetFlags(GrRenderTargetFlags::kNone) { diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp index c9cf535879..5026d0e1d0 100644 --- a/src/gpu/GrSurfaceProxy.cpp +++ b/src/gpu/GrSurfaceProxy.cpp @@ -44,8 +44,9 @@ static bool is_valid_non_lazy(const GrSurfaceDesc& desc) { #endif // Lazy-callback version -GrSurfaceProxy::GrSurfaceProxy(LazyInstantiateCallback&& callback, const GrSurfaceDesc& desc, - SkBackingFit fit, SkBudgeted budgeted, uint32_t flags) +GrSurfaceProxy::GrSurfaceProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType, + const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted, + uint32_t flags) : fConfig(desc.fConfig) , fWidth(desc.fWidth) , fHeight(desc.fHeight) @@ -54,6 +55,7 @@ GrSurfaceProxy::GrSurfaceProxy(LazyInstantiateCallback&& callback, const GrSurfa , fBudgeted(budgeted) , fFlags(flags) , fLazyInstantiateCallback(std::move(callback)) + , fLazyInstantiationType(lazyType) , fNeedsClear(SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag)) , fGpuMemorySize(kInvalidGpuMemorySize) , fLastOpList(nullptr) { @@ -63,7 +65,6 @@ GrSurfaceProxy::GrSurfaceProxy(LazyInstantiateCallback&& callback, const GrSurfa } else { SkASSERT(is_valid_non_lazy(desc)); } - } // Wrapped version @@ -361,6 +362,10 @@ bool GrSurfaceProxyPriv::doLazyInstantiation(GrResourceProvider* resourceProvide } sk_sp<GrSurface> surface = fProxy->fLazyInstantiateCallback(resourceProvider, outOrigin); + if (GrSurfaceProxy::LazyInstantiationType::kSingleUse == fProxy->fLazyInstantiationType) { + fProxy->fLazyInstantiateCallback(nullptr, nullptr); + fProxy->fLazyInstantiateCallback = nullptr; + } if (!surface) { fProxy->fWidth = 0; fProxy->fHeight = 0; diff --git a/src/gpu/GrSurfaceProxyPriv.h b/src/gpu/GrSurfaceProxyPriv.h index 2de820d625..e5d1f906a2 100644 --- a/src/gpu/GrSurfaceProxyPriv.h +++ b/src/gpu/GrSurfaceProxyPriv.h @@ -70,6 +70,14 @@ public: bool doLazyInstantiation(GrResourceProvider*); + GrSurfaceProxy::LazyInstantiationType lazyInstantiationType() const { + return fProxy->fLazyInstantiationType; + } + + void testingOnly_setLazyInstantiationType(GrSurfaceProxy::LazyInstantiationType lazyType) { + fProxy->fLazyInstantiationType = lazyType; + } + static bool AttachStencilIfNeeded(GrResourceProvider*, GrSurface*, bool needsStencil); private: diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp index 3362ec81d4..72b810620d 100644 --- a/src/gpu/GrTextureProxy.cpp +++ b/src/gpu/GrTextureProxy.cpp @@ -26,10 +26,10 @@ GrTextureProxy::GrTextureProxy(const GrSurfaceDesc& srcDesc, SkBackingFit fit, S } // Lazy-callback version -GrTextureProxy::GrTextureProxy(LazyInstantiateCallback&& callback, const GrSurfaceDesc& desc, - GrMipMapped mipMapped, SkBackingFit fit, SkBudgeted budgeted, - uint32_t flags) - : INHERITED(std::move(callback), desc, fit, budgeted, flags) +GrTextureProxy::GrTextureProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType, + const GrSurfaceDesc& desc, GrMipMapped mipMapped, SkBackingFit fit, + SkBudgeted budgeted, uint32_t flags) + : INHERITED(std::move(callback), lazyType, desc, fit, budgeted, flags) , fMipMapped(mipMapped) , fMipColorMode(SkDestinationSurfaceColorMode::kLegacy) , fProxyProvider(nullptr) diff --git a/src/gpu/GrTextureRenderTargetProxy.cpp b/src/gpu/GrTextureRenderTargetProxy.cpp index 3312077236..b4889faa57 100644 --- a/src/gpu/GrTextureRenderTargetProxy.cpp +++ b/src/gpu/GrTextureRenderTargetProxy.cpp @@ -29,16 +29,17 @@ GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(const GrCaps& caps, // Lazy-callback version GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(LazyInstantiateCallback&& callback, + LazyInstantiationType lazyType, const GrSurfaceDesc& desc, GrMipMapped mipMapped, SkBackingFit fit, SkBudgeted budgeted, uint32_t flags) - : GrSurfaceProxy(std::move(callback), desc, fit, budgeted, flags) + : GrSurfaceProxy(std::move(callback), lazyType, desc, fit, budgeted, flags) // Since we have virtual inheritance, we initialize GrSurfaceProxy directly. Send null // callbacks to the texture and RT proxies simply to route to the appropriate constructors. - , GrTextureProxy(LazyInstantiateCallback(), desc, mipMapped, fit, budgeted, flags) - , GrRenderTargetProxy(LazyInstantiateCallback(), desc, fit, budgeted, flags) { + , GrTextureProxy(LazyInstantiateCallback(), lazyType, desc, mipMapped, fit, budgeted, flags) + , GrRenderTargetProxy(LazyInstantiateCallback(), lazyType, desc, fit, budgeted, flags) { } // Wrapped version diff --git a/src/gpu/GrTextureRenderTargetProxy.h b/src/gpu/GrTextureRenderTargetProxy.h index 2947dd42c7..178185d77b 100644 --- a/src/gpu/GrTextureRenderTargetProxy.h +++ b/src/gpu/GrTextureRenderTargetProxy.h @@ -32,8 +32,9 @@ private: SkBackingFit, SkBudgeted, uint32_t flags); // Lazy-callback version - GrTextureRenderTargetProxy(LazyInstantiateCallback&&, const GrSurfaceDesc& desc, GrMipMapped, - SkBackingFit, SkBudgeted, uint32_t flags); + GrTextureRenderTargetProxy(LazyInstantiateCallback&&, LazyInstantiationType, + const GrSurfaceDesc& desc, GrMipMapped, SkBackingFit, SkBudgeted, + uint32_t flags); // Wrapped version GrTextureRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceOrigin); diff --git a/tests/LazyProxyTest.cpp b/tests/LazyProxyTest.cpp index 1994eeb5c9..5a0211d717 100644 --- a/tests/LazyProxyTest.cpp +++ b/tests/LazyProxyTest.cpp @@ -213,29 +213,42 @@ DEF_GPUTEST(LazyProxyReleaseTest, reporter, /* options */) { desc.fHeight = kSize; desc.fConfig = kRGBA_8888_GrPixelConfig; + using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType; for (bool doInstantiate : {true, false}) { - int testCount = 0; - int* testCountPtr = &testCount; - sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy( - [testCountPtr](GrResourceProvider* resourceProvider, GrSurfaceOrigin* outOrigin) { - if (!resourceProvider) { - *testCountPtr = -1; + for (auto lazyType : {LazyInstantiationType::kSingleUse, + LazyInstantiationType::kMultipleUse}) { + int testCount = 0; + int* testCountPtr = &testCount; + sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy( + [testCountPtr](GrResourceProvider* resourceProvider, + GrSurfaceOrigin* /*outOrigin*/) { + if (!resourceProvider) { + *testCountPtr = -1; + return sk_sp<GrTexture>(); + } + *testCountPtr = 1; return sk_sp<GrTexture>(); - } - *testCountPtr = 1; - return sk_sp<GrTexture>(); - }, desc, GrMipMapped::kNo, SkBackingFit::kExact, SkBudgeted::kNo); + }, desc, GrMipMapped::kNo, SkBackingFit::kExact, SkBudgeted::kNo); - REPORTER_ASSERT(reporter, 0 == testCount); + proxy->priv().testingOnly_setLazyInstantiationType(lazyType); - if (doInstantiate) { - proxy->priv().doLazyInstantiation(ctx->contextPriv().resourceProvider()); - REPORTER_ASSERT(reporter, 1 == testCount); - proxy.reset(); - REPORTER_ASSERT(reporter, -1 == testCount); - } else { - proxy.reset(); - REPORTER_ASSERT(reporter, -1 == testCount); + REPORTER_ASSERT(reporter, 0 == testCount); + + if (doInstantiate) { + proxy->priv().doLazyInstantiation(ctx->contextPriv().resourceProvider()); + if (LazyInstantiationType::kSingleUse == proxy->priv().lazyInstantiationType()) { + // In SingleUse we will call the cleanup and delete the callback in the + // doLazyInstantiationCall. + REPORTER_ASSERT(reporter, -1 == testCount); + } else { + REPORTER_ASSERT(reporter, 1 == testCount); + } + proxy.reset(); + REPORTER_ASSERT(reporter, -1 == testCount); + } else { + proxy.reset(); + REPORTER_ASSERT(reporter, -1 == testCount); + } } } } |