aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2018-02-08 15:05:44 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-02-08 20:33:40 +0000
commit457469c7a0c879b9d8ff8ed9fabe3f3dcab06097 (patch)
tree92ef5dcb793bbe9406730b1576c51bcc6042b86c
parent5635631c8887db678e6123c191ae68456b60d2a7 (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.h4
-rw-r--r--include/private/GrSurfaceProxy.h19
-rw-r--r--include/private/GrTextureProxy.h4
-rw-r--r--src/gpu/GrProxyProvider.cpp26
-rw-r--r--src/gpu/GrProxyProvider.h1
-rw-r--r--src/gpu/GrRenderTargetProxy.cpp3
-rw-r--r--src/gpu/GrSurfaceProxy.cpp11
-rw-r--r--src/gpu/GrSurfaceProxyPriv.h8
-rw-r--r--src/gpu/GrTextureProxy.cpp8
-rw-r--r--src/gpu/GrTextureRenderTargetProxy.cpp7
-rw-r--r--src/gpu/GrTextureRenderTargetProxy.h5
-rw-r--r--tests/LazyProxyTest.cpp51
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);
+ }
}
}
}