Plumb abandonment throughout GrContext hierarchy
When the GrImageContext & GrRecordingContext are actually GrDirectContexts it is useful for them to report the abandonment state of the GrDirectContext.
When the GrImageContext & GrRecordingContext are actually GrImageCreationContext or GrDDLContexts then they will just never be abandoned.
This CL also strips the GrProxyProvider and GrDrawingManager of their tracking on abandonment and centralizes it in the GrImageContext.
ImageContext
can't abandon
can only check abandonment privately
RecordingContext
can't abandon
can only check abandonment privately
DirectContext (aka GrContext)
can abandon publicly
can check abandonment publicly
Note that abandoning the DirectContext won't alter the abandonment status of any of
the other contexts in its group (e.g., DDL contexts that may be being used to record).
Change-Id: Ib790f74d90ab18da58a127fed2aad20e2477bd21
Reviewed-on: https://skia-review.googlesource.com/c/190669
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index fc8c7f5..1acb131 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -39,9 +39,9 @@
#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this)
#define ASSERT_SINGLE_OWNER \
SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
-#define RETURN_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return; }
-#define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return false; }
-#define RETURN_NULL_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return nullptr; }
+#define RETURN_IF_ABANDONED if (this->abandoned()) { return; }
+#define RETURN_FALSE_IF_ABANDONED if (this->abandoned()) { return false; }
+#define RETURN_NULL_IF_ABANDONED if (this->abandoned()) { return nullptr; }
////////////////////////////////////////////////////////////////////////////////
@@ -146,14 +146,17 @@
//////////////////////////////////////////////////////////////////////////////
void GrContext::abandonContext() {
- ASSERT_SINGLE_OWNER
+ if (this->abandoned()) {
+ return;
+ }
- this->proxyProvider()->abandon();
+ INHERITED::abandonContext();
+
fResourceProvider->abandon();
- // Need to abandon the drawing manager first so all the render targets
+ // Need to cleanup the drawing manager first so all the render targets
// will be released/forgotten before they too are abandoned.
- fDrawingManager->abandon();
+ fDrawingManager->cleanup();
// abandon first to so destructors
// don't try to free the resources in the API.
@@ -163,26 +166,21 @@
fGlyphCache->freeAll();
fTextBlobCache->freeAll();
-}
-bool GrContext::abandoned() const {
- ASSERT_SINGLE_OWNER
- // If called from ~GrContext(), the drawing manager may already be gone.
- return !fDrawingManager || fDrawingManager->wasAbandoned();
}
void GrContext::releaseResourcesAndAbandonContext() {
- ASSERT_SINGLE_OWNER
-
if (this->abandoned()) {
return;
}
- this->proxyProvider()->abandon();
+
+ INHERITED::abandonContext();
+
fResourceProvider->abandon();
- // Need to abandon the drawing manager first so all the render targets
+ // Need to cleanup the drawing manager first so all the render targets
// will be released/forgotten before they too are abandoned.
- fDrawingManager->abandon();
+ fDrawingManager->cleanup();
// Release all resources in the backend 3D API.
fResourceCache->releaseAll();
@@ -298,7 +296,9 @@
GrSemaphoresSubmitted GrContext::flushAndSignalSemaphores(int numSemaphores,
GrBackendSemaphore signalSemaphores[]) {
ASSERT_SINGLE_OWNER
- if (fDrawingManager->wasAbandoned()) { return GrSemaphoresSubmitted::kNo; }
+ if (this->abandoned()) {
+ return GrSemaphoresSubmitted::kNo;
+ }
return fDrawingManager->flush(nullptr, numSemaphores, signalSemaphores);
}
diff --git a/src/gpu/GrContextPriv.cpp b/src/gpu/GrContextPriv.cpp
index d9d969c..81e9533 100644
--- a/src/gpu/GrContextPriv.cpp
+++ b/src/gpu/GrContextPriv.cpp
@@ -28,8 +28,8 @@
SkASSERT(!(P) || !((P)->peekTexture()) || (P)->peekTexture()->getContext() == fContext)
#define ASSERT_SINGLE_OWNER_PRIV \
SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fContext->singleOwner());)
-#define RETURN_IF_ABANDONED_PRIV if (fContext->fDrawingManager->wasAbandoned()) { return; }
-#define RETURN_FALSE_IF_ABANDONED_PRIV if (fContext->fDrawingManager->wasAbandoned()) { return false; }
+#define RETURN_IF_ABANDONED_PRIV if (fContext->abandoned()) { return; }
+#define RETURN_FALSE_IF_ABANDONED_PRIV if (fContext->abandoned()) { return false; }
sk_sp<const GrCaps> GrContextPriv::refCaps() const {
return fContext->refCaps();
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index f63c7e8..9db2864 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -156,7 +156,6 @@
, fOptionsForPathRendererChain(optionsForPathRendererChain)
, fOptionsForTextContext(optionsForTextContext)
, fSingleOwner(singleOwner)
- , fAbandoned(false)
, fDAG(explicitlyAllocating, sortOpLists)
, fTextContext(nullptr)
, fPathRendererChain(nullptr)
@@ -186,9 +185,8 @@
this->cleanup();
}
-void GrDrawingManager::abandon() {
- fAbandoned = true;
- this->cleanup();
+bool GrDrawingManager::wasAbandoned() const {
+ return fContext->abandoned();
}
void GrDrawingManager::freeGpuResources() {
diff --git a/src/gpu/GrDrawingManager.h b/src/gpu/GrDrawingManager.h
index e543ed7..793a97c 100644
--- a/src/gpu/GrDrawingManager.h
+++ b/src/gpu/GrDrawingManager.h
@@ -38,7 +38,6 @@
public:
~GrDrawingManager();
- bool wasAbandoned() const { return fAbandoned; }
void freeGpuResources();
sk_sp<GrRenderTargetContext> makeRenderTargetContext(sk_sp<GrSurfaceProxy>,
@@ -140,7 +139,8 @@
bool explicitlyAllocating, GrContextOptions::Enable sortRenderTargets,
GrContextOptions::Enable reduceOpListSplitting);
- void abandon();
+ bool wasAbandoned() const;
+
void cleanup();
// return true if any opLists were actually executed; false otherwise
@@ -168,7 +168,6 @@
// In debug builds we guard against improper thread handling
GrSingleOwner* fSingleOwner;
- bool fAbandoned;
OpListDAG fDAG;
GrOpList* fActiveOpList = nullptr;
// These are the IDs of the opLists currently being flushed (in internalFlush)
diff --git a/src/gpu/GrImageContext.cpp b/src/gpu/GrImageContext.cpp
index 0d38379..91e81bc 100644
--- a/src/gpu/GrImageContext.cpp
+++ b/src/gpu/GrImageContext.cpp
@@ -12,6 +12,10 @@
#include "GrProxyProvider.h"
#include "GrSkSLFPFactoryCache.h"
+#define ASSERT_SINGLE_OWNER \
+ SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
GrImageContext::GrImageContext(GrBackendApi backend,
const GrContextOptions& options,
uint32_t contextID)
@@ -21,6 +25,18 @@
GrImageContext::~GrImageContext() {}
+void GrImageContext::abandonContext() {
+ ASSERT_SINGLE_OWNER
+
+ fAbandoned = true;
+}
+
+bool GrImageContext::abandoned() const {
+ ASSERT_SINGLE_OWNER
+
+ return fAbandoned;
+}
+
///////////////////////////////////////////////////////////////////////////////////////////////////
sk_sp<const GrCaps> GrImageContextPriv::refCaps() const {
return fContext->refCaps();
diff --git a/src/gpu/GrImageContextPriv.h b/src/gpu/GrImageContextPriv.h
index b499ed7..c1fca60 100644
--- a/src/gpu/GrImageContextPriv.h
+++ b/src/gpu/GrImageContextPriv.h
@@ -35,6 +35,8 @@
GrProxyProvider* proxyProvider() { return fContext->proxyProvider(); }
const GrProxyProvider* proxyProvider() const { return fContext->proxyProvider(); }
+ bool abandoned() const { return fContext->abandoned(); }
+
/** This is only useful for debug purposes */
SkDEBUGCODE(GrSingleOwner* singleOwner() const { return fContext->singleOwner(); } )
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index a108569..a7b7213 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -34,10 +34,7 @@
#define ASSERT_SINGLE_OWNER \
SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fImageContext->priv().singleOwner());)
-GrProxyProvider::GrProxyProvider(GrImageContext* imageContext)
- : fImageContext(imageContext)
- , fAbandoned(false) {
-}
+GrProxyProvider::GrProxyProvider(GrImageContext* imageContext) : fImageContext(imageContext) {}
GrProxyProvider::~GrProxyProvider() {
if (this->renderingDirectly()) {
@@ -837,6 +834,10 @@
return fImageContext->priv().refCaps();
}
+bool GrProxyProvider::isAbandoned() const {
+ return fImageContext->priv().abandoned();
+}
+
void GrProxyProvider::orphanAllUniqueKeys() {
UniquelyKeyedProxyHash::Iter iter(&fUniquelyKeyedProxies);
for (UniquelyKeyedProxyHash::Iter iter(&fUniquelyKeyedProxies); !iter.done(); ++iter) {
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index 385d055..8f3007d 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -216,12 +216,6 @@
const GrCaps* caps() const;
sk_sp<const GrCaps> refCaps() const;
- void abandon() {
- fAbandoned = true;
- }
-
- bool isAbandoned() const { return fAbandoned; }
-
int numUniqueKeyProxies_TestOnly() const;
// This is called on a DDL's proxyprovider when the DDL is finished. The uniquely keyed
@@ -250,6 +244,8 @@
friend class GrAHardwareBufferImageGenerator; // for createWrapped
friend class GrResourceProvider; // for createWrapped
+ bool isAbandoned() const;
+
sk_sp<GrTextureProxy> createWrapped(sk_sp<GrTexture> tex, GrSurfaceOrigin origin);
struct UniquelyKeyedProxyHashTraits {
@@ -264,7 +260,6 @@
UniquelyKeyedProxyHash fUniquelyKeyedProxies;
GrImageContext* fImageContext;
- bool fAbandoned;
};
#endif
diff --git a/src/gpu/GrRecordingContext.cpp b/src/gpu/GrRecordingContext.cpp
index 6edfd65..c719101 100644
--- a/src/gpu/GrRecordingContext.cpp
+++ b/src/gpu/GrRecordingContext.cpp
@@ -20,6 +20,10 @@
GrRecordingContext::~GrRecordingContext() { }
+void GrRecordingContext::abandonContext() {
+ INHERITED::abandonContext();
+}
+
sk_sp<GrOpMemoryPool> GrRecordingContext::refOpMemoryPool() {
if (!fOpMemoryPool) {
// DDL TODO: should the size of the memory pool be decreased in DDL mode? CPU-side memory
diff --git a/src/gpu/GrRecordingContextPriv.h b/src/gpu/GrRecordingContextPriv.h
index c264eaa..b0f2d32 100644
--- a/src/gpu/GrRecordingContextPriv.h
+++ b/src/gpu/GrRecordingContextPriv.h
@@ -35,6 +35,8 @@
GrProxyProvider* proxyProvider() { return fContext->proxyProvider(); }
const GrProxyProvider* proxyProvider() const { return fContext->proxyProvider(); }
+ bool abandoned() const { return fContext->abandoned(); }
+
/** This is only useful for debug purposes */
SkDEBUGCODE(GrSingleOwner* singleOwner() const { return fContext->singleOwner(); } )
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 2e20901..e6975ab 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -106,11 +106,11 @@
SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
#define ASSERT_SINGLE_OWNER_PRIV \
SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fRenderTargetContext->singleOwner());)
-#define RETURN_IF_ABANDONED if (this->drawingManager()->wasAbandoned()) { return; }
-#define RETURN_IF_ABANDONED_PRIV if (fRenderTargetContext->drawingManager()->wasAbandoned()) { return; }
-#define RETURN_FALSE_IF_ABANDONED if (this->drawingManager()->wasAbandoned()) { return false; }
-#define RETURN_FALSE_IF_ABANDONED_PRIV if (fRenderTargetContext->drawingManager()->wasAbandoned()) { return false; }
-#define RETURN_NULL_IF_ABANDONED if (this->drawingManager()->wasAbandoned()) { return nullptr; }
+#define RETURN_IF_ABANDONED if (fContext->abandoned()) { return; }
+#define RETURN_IF_ABANDONED_PRIV if (fRenderTargetContext->fContext->abandoned()) { return; }
+#define RETURN_FALSE_IF_ABANDONED if (fContext->abandoned()) { return false; }
+#define RETURN_FALSE_IF_ABANDONED_PRIV if (fRenderTargetContext->fContext->abandoned()) { return false; }
+#define RETURN_NULL_IF_ABANDONED if (fContext->abandoned()) { return nullptr; }
//////////////////////////////////////////////////////////////////////////////
@@ -150,10 +150,6 @@
GrDrawingManager* fDrawingManager;
};
-bool GrRenderTargetContext::wasAbandoned() const {
- return this->drawingManager()->wasAbandoned();
-}
-
// In MDB mode the reffing of the 'getLastOpList' call's result allows in-progress
// GrOpLists to be picked up and added to by renderTargetContexts lower in the call
// stack. When this occurs with a closed GrOpList, a new one will be allocated
@@ -1153,7 +1149,7 @@
const SkPath& path,
const SkDrawShadowRec& rec) {
ASSERT_SINGLE_OWNER
- if (this->drawingManager()->wasAbandoned()) {
+ if (fContext->abandoned()) {
return true;
}
SkDEBUGCODE(this->validate();)
@@ -1623,7 +1619,9 @@
GrSemaphoresSubmitted GrRenderTargetContext::prepareForExternalIO(
int numSemaphores, GrBackendSemaphore backendSemaphores[]) {
ASSERT_SINGLE_OWNER
- if (this->drawingManager()->wasAbandoned()) { return GrSemaphoresSubmitted::kNo; }
+ if (fContext->abandoned()) {
+ return GrSemaphoresSubmitted::kNo;
+ }
SkDEBUGCODE(this->validate();)
GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "prepareForExternalIO", fContext);
@@ -1807,7 +1805,7 @@
SkBudgeted GrRenderTargetContextPriv::isBudgeted() const {
ASSERT_SINGLE_OWNER_PRIV
- if (fRenderTargetContext->wasAbandoned()) {
+ if (fRenderTargetContext->fContext->abandoned()) {
return SkBudgeted::kNo;
}
@@ -1933,7 +1931,7 @@
void GrRenderTargetContext::addDrawOp(const GrClip& clip, std::unique_ptr<GrDrawOp> op,
const std::function<WillAddOpFn>& willAddFn) {
ASSERT_SINGLE_OWNER
- if (this->drawingManager()->wasAbandoned()) {
+ if (fContext->abandoned()) {
fContext->priv().opMemoryPool()->release(std::move(op));
return;
}
diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index f1e45bd..a4b329e 100644
--- a/src/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -388,8 +388,6 @@
bool wrapsVkSecondaryCB() const { return fRenderTargetProxy->wrapsVkSecondaryCB(); }
GrMipMapped mipMapped() const;
- bool wasAbandoned() const;
-
void setNeedsStencil() { fRenderTargetProxy->setNeedsStencil(); }
GrRenderTarget* accessRenderTarget() {
diff --git a/src/gpu/GrSurfaceContext.cpp b/src/gpu/GrSurfaceContext.cpp
index 75059d4..1b5a54cd 100644
--- a/src/gpu/GrSurfaceContext.cpp
+++ b/src/gpu/GrSurfaceContext.cpp
@@ -14,7 +14,7 @@
#define ASSERT_SINGLE_OWNER \
SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
-#define RETURN_FALSE_IF_ABANDONED if (this->drawingManager()->wasAbandoned()) { return false; }
+#define RETURN_FALSE_IF_ABANDONED if (this->fContext->abandoned()) { return false; }
// In MDB mode the reffing of the 'getLastOpList' call's result allows in-progress
// GrOpLists to be picked up and added to by renderTargetContexts lower in the call
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index dc467e3..151ef28 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -87,7 +87,7 @@
sk_sp<GrRenderTargetContext> renderTargetContext,
int width, int height,
InitContents init) {
- if (!renderTargetContext || renderTargetContext->wasAbandoned()) {
+ if (!renderTargetContext || context->abandoned()) {
return nullptr;
}
unsigned flags;
@@ -268,7 +268,7 @@
SkASSERT(newRTC->asSurfaceProxy()->priv().isExact());
if (shouldRetainContent) {
- if (fRenderTargetContext->wasAbandoned()) {
+ if (this->context()->abandoned()) {
return;
}
newRTC->copy(fRenderTargetContext->asSurfaceProxy());