aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2016-04-01 11:54:31 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-04-01 11:54:31 -0700
commit6e2aad4e9f6280aa2b710e7324458fdc6d699ec5 (patch)
tree77bf09c049b5afe4aaccd66b7926050c53bbebff /src
parent895f3f0544ce38d35999771754cbb1d876c14b5a (diff)
Add GrContext::releaseAndAbandonContext()
Like abandonContext() this disconnects the GrContext from the underlying 3D API. However, unlike abandonContext it first frees all allocated GPU resources. BUG=skia:5142 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1852733002 Review URL: https://codereview.chromium.org/1852733002
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrContext.cpp21
-rw-r--r--src/gpu/GrGpu.cpp2
-rw-r--r--src/gpu/GrGpu.h16
-rw-r--r--src/gpu/gl/GrGLGpu.cpp52
-rw-r--r--src/gpu/gl/GrGLGpu.h2
-rw-r--r--src/gpu/gl/GrGLPathRendering.cpp5
-rw-r--r--src/gpu/gl/GrGLPathRendering.h6
7 files changed, 88 insertions, 16 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 1f6934d441..1d6bb32142 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -148,7 +148,26 @@ void GrContext::abandonContext() {
// don't try to free the resources in the API.
fResourceCache->abandonAll();
- fGpu->contextAbandoned();
+ fGpu->disconnect(GrGpu::DisconnectType::kAbandon);
+
+ fBatchFontCache->freeAll();
+ fLayerCache->freeAll();
+ fTextBlobCache->freeAll();
+}
+
+void GrContext::releaseResourcesAndAbandonContext() {
+ ASSERT_SINGLE_OWNER
+
+ fResourceProvider->abandon();
+
+ // Need to abandon the drawing manager first so all the render targets
+ // will be released/forgotten before they too are abandoned.
+ fDrawingManager->abandon();
+
+ // Release all resources in the backend 3D API.
+ fResourceCache->releaseAll();
+
+ fGpu->disconnect(GrGpu::DisconnectType::kCleanup);
fBatchFontCache->freeAll();
fLayerCache->freeAll();
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 960526635e..bc11b4b9c6 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -51,7 +51,7 @@ GrGpu::GrGpu(GrContext* context)
GrGpu::~GrGpu() {}
-void GrGpu::contextAbandoned() {}
+void GrGpu::disconnect(DisconnectType) {}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 0da1aa6399..b3251dc14f 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -61,11 +61,17 @@ public:
GrPathRendering* pathRendering() { return fPathRendering.get(); }
- // Called by GrContext when the underlying backend context has been destroyed.
- // GrGpu should use this to ensure that no backend API calls will be made from
- // here onward, including in its destructor. Subclasses should call
- // INHERITED::contextAbandoned() if they override this.
- virtual void contextAbandoned();
+ enum class DisconnectType {
+ // No cleanup should be attempted, immediately cease making backend API calls
+ kAbandon,
+ // Free allocated resources (not known by GrResourceCache) before returning and
+ // ensure no backend backend 3D API calls will be made after disconnect() returns.
+ kCleanup,
+ };
+
+ // Called by GrContext when the underlying backend context is already or will be destroyed
+ // before GrContext.
+ virtual void disconnect(DisconnectType);
/**
* The GrGpu object normally assumes that no outsider is setting state
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 34223f1cc8..c8c12a388d 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -386,9 +386,51 @@ void GrGLGpu::createPLSSetupProgram() {
GR_GL_STATIC_DRAW));
}
-void GrGLGpu::contextAbandoned() {
- INHERITED::contextAbandoned();
- fProgramCache->abandon();
+void GrGLGpu::disconnect(DisconnectType type) {
+ INHERITED::disconnect(type);
+ if (DisconnectType::kCleanup == type) {
+ if (fHWProgramID) {
+ GL_CALL(UseProgram(0));
+ }
+ if (fTempSrcFBOID) {
+ GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID));
+ }
+ if (fTempDstFBOID) {
+ GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID));
+ }
+ if (fStencilClearFBOID) {
+ GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID));
+ }
+ if (fCopyProgramArrayBuffer) {
+ GL_CALL(DeleteBuffers(1, &fCopyProgramArrayBuffer));
+ }
+ for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
+ if (fCopyPrograms[i].fProgram) {
+ GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram));
+ }
+ }
+ if (fWireRectProgram.fProgram) {
+ GL_CALL(DeleteProgram(fWireRectProgram.fProgram));
+ }
+ if (fWireRectArrayBuffer) {
+ GL_CALL(DeleteBuffers(1, &fWireRectArrayBuffer));
+ }
+
+ if (fPLSSetupProgram.fProgram) {
+ GL_CALL(DeleteProgram(fPLSSetupProgram.fProgram));
+ }
+ if (fPLSSetupProgram.fArrayBuffer) {
+ GL_CALL(DeleteBuffers(1, &fPLSSetupProgram.fArrayBuffer));
+ }
+ } else {
+ if (fProgramCache) {
+ fProgramCache->abandon();
+ }
+ }
+
+ delete fProgramCache;
+ fProgramCache = nullptr;
+
fHWProgramID = 0;
fTempSrcFBOID = 0;
fTempDstFBOID = 0;
@@ -399,8 +441,10 @@ void GrGLGpu::contextAbandoned() {
}
fWireRectProgram.fProgram = 0;
fWireRectArrayBuffer = 0;
+ fPLSSetupProgram.fProgram = 0;
+ fPLSSetupProgram.fArrayBuffer = 0;
if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
- this->glPathRendering()->abandonGpuResources();
+ this->glPathRendering()->disconnect(type);
}
}
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 6d851ee1dd..c77076fc51 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -38,7 +38,7 @@ public:
GrContext* context);
~GrGLGpu() override;
- void contextAbandoned() override;
+ void disconnect(DisconnectType) override;
const GrGLContext& glContext() const { return *fGLContext; }
diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp
index 47274f9d69..0ecf58a8e1 100644
--- a/src/gpu/gl/GrGLPathRendering.cpp
+++ b/src/gpu/gl/GrGLPathRendering.cpp
@@ -91,7 +91,10 @@ GrGLPathRendering::~GrGLPathRendering() {
}
}
-void GrGLPathRendering::abandonGpuResources() {
+void GrGLPathRendering::disconnect(GrGpu::DisconnectType type) {
+ if (GrGpu::DisconnectType::kCleanup == type) {
+ this->deletePaths(fFirstPreallocatedPathID, fPreallocatedPathCount);
+ };
fPreallocatedPathCount = 0;
}
diff --git a/src/gpu/gl/GrGLPathRendering.h b/src/gpu/gl/GrGLPathRendering.h
index cd4668fc88..b39c866c6f 100644
--- a/src/gpu/gl/GrGLPathRendering.h
+++ b/src/gpu/gl/GrGLPathRendering.h
@@ -41,10 +41,10 @@ public:
void resetContext();
/**
- * Called when the GPU resources have been lost and need to be abandoned
- * (for example after a context loss).
+ * Called when the context either is about to be lost or is lost. DisconnectType indicates
+ * whether GPU resources should be cleaned up or abandoned when this is called.
*/
- void abandonGpuResources();
+ void disconnect(GrGpu::DisconnectType);
bool shouldBindFragmentInputs() const {
return fCaps.bindFragmentInputSupport;