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>
This commit is contained in:
parent
5635631c88
commit
457469c7a0
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,6 @@ public:
|
||||
|
||||
using LazyInstantiateCallback = std::function<sk_sp<GrSurface>(GrResourceProvider*,
|
||||
GrSurfaceOrigin* outOrigin)>;
|
||||
|
||||
enum class Textureable : bool {
|
||||
kNo = false,
|
||||
kYes = true
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user