Allow ~Layer() to happen after onGLContextDestroyed

Bug: 19146354
Change-Id: I9e885936168bd541bfbed4064ad67ab524f58e32
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 4bbe6ed..cdf8150 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -273,7 +273,7 @@
             layerCache.getSize(), layerCache.getMaxSize(), layerCache.getCount());
     if (mRenderState) {
         int memused = 0;
-        for (std::set<const Layer*>::iterator it = mRenderState->mActiveLayers.begin();
+        for (std::set<Layer*>::iterator it = mRenderState->mActiveLayers.begin();
                 it != mRenderState->mActiveLayers.end(); it++) {
             const Layer* layer = *it;
             log.appendFormat("    Layer size %dx%d; isTextureLayer()=%d; texid=%u fbo=%u; refs=%d\n",
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 9aa29ca..05259ff 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -69,17 +69,25 @@
 }
 
 Layer::~Layer() {
-    renderState.requireGLContext();
     renderState.unregisterLayer(this);
     SkSafeUnref(colorFilter);
-    removeFbo();
-    deleteTexture();
+
+    if (stencil || fbo || texture.id) {
+        renderState.requireGLContext();
+        removeFbo();
+        deleteTexture();
+    }
 
     delete[] mesh;
     delete deferredList;
     delete renderer;
 }
 
+void Layer::onGlContextLost() {
+    removeFbo();
+    deleteTexture();
+}
+
 uint32_t Layer::computeIdealWidth(uint32_t layerWidth) {
     return uint32_t(ceilf(layerWidth / float(LAYER_SIZE)) * LAYER_SIZE);
 }
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 64d1d12..e196cb1 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -286,6 +286,12 @@
     void postDecStrong();
 
     /**
+     * Lost the GL context but the layer is still around, mark it invalid internally
+     * so the dtor knows not to do any GL work
+     */
+    void onGlContextLost();
+
+    /**
      * Bounds of the layer.
      */
     Rect layer;
diff --git a/libs/hwui/RenderState.cpp b/libs/hwui/RenderState.cpp
index d1f5f4e..ca640e5 100644
--- a/libs/hwui/RenderState.cpp
+++ b/libs/hwui/RenderState.cpp
@@ -41,6 +41,10 @@
     mCaches->textureCache.setAssetAtlas(&mAssetAtlas);
 }
 
+static void layerLostGlContext(Layer* layer) {
+    layer->onGlContextLost();
+}
+
 void RenderState::onGLContextDestroyed() {
 /*
     size_t size = mActiveLayers.size();
@@ -73,6 +77,7 @@
         LOG_ALWAYS_FATAL("%d layers have survived gl context destruction", size);
     }
 */
+    std::for_each(mActiveLayers.begin(), mActiveLayers.end(), layerLostGlContext);
     mAssetAtlas.terminate();
 }
 
diff --git a/libs/hwui/RenderState.h b/libs/hwui/RenderState.h
index 1ecfb1c..9ac9356 100644
--- a/libs/hwui/RenderState.h
+++ b/libs/hwui/RenderState.h
@@ -53,10 +53,10 @@
 
     void debugOverdraw(bool enable, bool clear);
 
-    void registerLayer(const Layer* layer) {
+    void registerLayer(Layer* layer) {
         mActiveLayers.insert(layer);
     }
-    void unregisterLayer(const Layer* layer) {
+    void unregisterLayer(Layer* layer) {
         mActiveLayers.erase(layer);
     }
 
@@ -90,7 +90,7 @@
     renderthread::RenderThread& mRenderThread;
     Caches* mCaches;
     AssetAtlas mAssetAtlas;
-    std::set<const Layer*> mActiveLayers;
+    std::set<Layer*> mActiveLayers;
     std::set<renderthread::CanvasContext*> mRegisteredContexts;
 
     GLsizei mViewportWidth;