free gralloc buffers as soon as possible (when a surface is not visible any longer), client who have the buffers still mapped won't crash, btu may see garbage data
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index e74e000..c386681 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -1095,12 +1095,9 @@
 
 status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
 {
-    // First add the layer to the purgatory list, which makes sure it won't 
-    // go away, then remove it from the main list (through a transaction).
+    // remove the layer from the main list (through a transaction).
     ssize_t err = removeLayer_l(layerBase);
-    if (err >= 0) {
-        mLayerPurgatory.add(layerBase);
-    }
+
     // it's possible that we don't find a layer, because it might
     // have been destroyed already -- this is not technically an error
     // from the user because there is a race between BClient::destroySurface(),
@@ -1336,7 +1333,7 @@
 
 status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
 {
-    /* called by ~ISurface() when all references are gone */
+    // called by ~ISurface() when all references are gone
     
     class MessageDestroySurface : public MessageBase {
         SurfaceFlinger* flinger;
@@ -1349,33 +1346,21 @@
             sp<LayerBaseClient> l(layer);
             layer.clear(); // clear it outside of the lock;
             Mutex::Autolock _l(flinger->mStateLock);
-            // remove the layer from the current list -- chances are that it's 
-            // not in the list anyway, because it should have been removed 
-            // already upon request of the client (eg: window manager). 
-            // However, a buggy client could have not done that.
-            // Since we know we don't have any more clients, we don't need
-            // to use the purgatory.
+            /*
+             * remove the layer from the current list -- chances are that it's 
+             * not in the list anyway, because it should have been removed 
+             * already upon request of the client (eg: window manager). 
+             * However, a buggy client could have not done that.
+             * Since we know we don't have any more clients, we don't need
+             * to use the purgatory.
+             */
             status_t err = flinger->removeLayer_l(l);
-            if (err == NAME_NOT_FOUND) {
-                // The surface wasn't in the current list, which means it was
-                // removed already, which means it is in the purgatory, 
-                // and need to be removed from there.
-                // This needs to happen from the main thread since its dtor
-                // must run from there (b/c of OpenGL ES). Additionally, we
-                // can't really acquire our internal lock from 
-                // destroySurface() -- see postMessage() below.
-                ssize_t idx = flinger->mLayerPurgatory.remove(l);
-                LOGE_IF(idx < 0,
-                        "layer=%p is not in the purgatory list", l.get());
-            }
+            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
+                    "error removing layer=%p (%s)", l.get(), strerror(-err));
             return true;
         }
     };
 
-    // It's better to not acquire our internal lock here, because it's hard
-    // to predict that it's not going to be already taken when ~Surface()
-    // is called.
-
     mEventQueue.postMessage( new MessageDestroySurface(this, layer) );
     return NO_ERROR;
 }
@@ -1537,8 +1522,7 @@
                 mFreezeDisplay?"yes":"no", mFreezeCount,
                 mCurrentState.orientation, hw.canDraw());
         result.append(buffer);
-        snprintf(buffer, SIZE, "  purgatory size: %d, client count: %d\n",
-                mLayerPurgatory.size(), mClientsMap.size());
+        snprintf(buffer, SIZE, "  client count: %d\n", mClientsMap.size());
         result.append(buffer);
         const BufferAllocator& alloc(BufferAllocator::get());
         alloc.dump(result);