Additional layer logging

bug:17208461

Track layer's last known state.

Change-Id: Ic1799191f5839a1d6cc56f598f2ac2671dc27a6f
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index f853d1f..9b0025f 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -342,6 +342,7 @@
 
 void Caches::deleteLayerDeferred(Layer* layer) {
     Mutex::Autolock _l(mGarbageLock);
+    layer->state = Layer::kState_InGarbageList;
     mLayerGarbage.push(layer);
 }
 
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 91c4aee..b5089aa 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -30,7 +30,8 @@
 namespace uirenderer {
 
 Layer::Layer(Type layerType, RenderState& renderState, const uint32_t layerWidth, const uint32_t layerHeight)
-        : caches(Caches::getInstance())
+        : state(kState_Uncached)
+        , caches(Caches::getInstance())
         , renderState(renderState)
         , texture(caches)
         , type(layerType) {
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 36a4ed1..a8e1c26 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -59,6 +59,17 @@
         kType_DisplayList,
     };
 
+    // layer lifecycle, controlled from outside
+    enum State {
+        kState_Uncached = 0,
+        kState_InCache = 1,
+        kState_FailedToCache = 2,
+        kState_RemovedFromCache = 3,
+        kState_DeletedFromCache = 4,
+        kState_InGarbageList = 5,
+    };
+    State state; // public for logging/debugging purposes
+
     Layer(Type type, RenderState& renderState, const uint32_t layerWidth, const uint32_t layerHeight);
     ~Layer();
 
diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp
index d49daf6..833f64b 100644
--- a/libs/hwui/LayerCache.cpp
+++ b/libs/hwui/LayerCache.cpp
@@ -83,6 +83,7 @@
         LAYER_LOGD("Destroying layer %dx%d, fbo %d", layer->getWidth(), layer->getHeight(),
                 layer->getFbo());
         mSize -= layer->getWidth() * layer->getHeight() * 4;
+        layer->state = Layer::kState_DeletedFromCache;
         Caches::getInstance().resourceCache.decrementRefcount(layer);
     }
 }
@@ -106,6 +107,7 @@
         mCache.removeAt(index);
 
         layer = entry.mLayer;
+        layer->state = Layer::kState_RemovedFromCache;
         mSize -= layer->getWidth() * layer->getHeight() * 4;
 
         LAYER_LOGD("Reusing layer %dx%d", layer->getWidth(), layer->getHeight());
@@ -166,8 +168,11 @@
         mCache.add(entry);
         mSize += size;
 
+        layer->state = Layer::kState_InCache;
         return true;
     }
+
+    layer->state = Layer::kState_FailedToCache;
     return false;
 }
 
diff --git a/libs/hwui/RenderState.cpp b/libs/hwui/RenderState.cpp
index ec8307f..54af528 100644
--- a/libs/hwui/RenderState.cpp
+++ b/libs/hwui/RenderState.cpp
@@ -39,13 +39,16 @@
 
 void RenderState::onGLContextDestroyed() {
     AutoMutex _lock(mLayerLock);
-    if (CC_UNLIKELY(!mActiveLayers.empty())) {
+    size_t size = mActiveLayers.size();
+    if (CC_UNLIKELY(size != 0)) {
+        ALOGE("Crashing, have %d contexts and %d layers at context destruction. isempty %d",
+                mRegisteredContexts.size(), size, mActiveLayers.empty());
         mCaches->dumpMemoryUsage();
         for (std::set<renderthread::CanvasContext*>::iterator cit = mRegisteredContexts.begin();
                 cit != mRegisteredContexts.end(); cit++) {
             renderthread::CanvasContext* context = *cit;
-            ALOGD("Context: %p (root = %p)", context, context->mRootRenderNode.get());
-            ALOGD("  Prefeteched layers: %zu", context->mPrefetechedLayers.size());
+            ALOGE("Context: %p (root = %p)", context, context->mRootRenderNode.get());
+            ALOGE("  Prefeteched layers: %zu", context->mPrefetechedLayers.size());
             for (std::set<RenderNode*>::iterator pit = context->mPrefetechedLayers.begin();
                     pit != context->mPrefetechedLayers.end(); pit++) {
                 (*pit)->debugDumpLayers("    ");
@@ -53,13 +56,17 @@
             context->mRootRenderNode->debugDumpLayers("  ");
         }
 
+
+        if (mActiveLayers.begin() == mActiveLayers.end()) {
+            ALOGE("set has become empty. wat.");
+        }
         for (std::set<const Layer*>::iterator lit = mActiveLayers.begin();
              lit != mActiveLayers.end(); lit++) {
             const Layer* layer = *(lit);
-            ALOGD("Layer %p, fbo %d, buildlayered %d",
-                    layer, layer->getFbo(), layer->wasBuildLayered);
+            ALOGE("Layer %p, state %d, texlayer %d, fbo %d, buildlayered %d",
+                    layer, layer->state, layer->isTextureLayer(), layer->getFbo(), layer->wasBuildLayered);
         }
-        LOG_ALWAYS_FATAL("layers have survived gl context destruction");
+        LOG_ALWAYS_FATAL("%d layers have survived gl context destruction", size);
     }
 }