make GLConsumer's debug texture static

this is so that we don't burn a gralloc handle and a bit
of memory per GLConsumer.

Change-Id: I30c3e7ec45d7f1b5426aca8e06c7716870877706
diff --git a/include/gui/GLConsumer.h b/include/gui/GLConsumer.h
index 4c9aa87..742e8d1 100644
--- a/include/gui/GLConsumer.h
+++ b/include/gui/GLConsumer.h
@@ -297,6 +297,9 @@
     // binding the buffer without touching the EglSlots.
     status_t bindUnslottedBufferLocked(EGLDisplay dpy);
 
+    // returns a graphic buffer used when the texture image has been released
+    static sp<GraphicBuffer> getDebugTexImageBuffer();
+
     // The default consumer usage flags that GLConsumer always sets on its
     // BufferQueue instance; these will be OR:d with any additional flags passed
     // from the GLConsumer user. In particular, GLConsumer will always
@@ -414,9 +417,12 @@
     // attachToContext.
     bool mAttached;
 
+    // protects static initialization
+    static Mutex sStaticInitLock;
+
     // mReleasedTexImageBuffer is a dummy buffer used when in single buffer
     // mode and releaseTexImage() has been called
-    sp<GraphicBuffer> mReleasedTexImageBuffer;
+    static sp<GraphicBuffer> sReleasedTexImageBuffer;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index 0f7057d..a757bc4 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -86,6 +86,8 @@
 
 static void mtxMul(float out[16], const float a[16], const float b[16]);
 
+Mutex GLConsumer::sStaticInitLock;
+sp<GraphicBuffer> GLConsumer::sReleasedTexImageBuffer;
 
 GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, GLuint tex,
         GLenum texTarget, bool useFenceSync, bool isControlledByApp) :
@@ -212,29 +214,8 @@
             return err;
         }
 
-        if (CC_UNLIKELY(mReleasedTexImageBuffer == NULL)) {
-            // The first time, create the debug texture in case the application
-            // continues to use it.
-            sp<GraphicBuffer> buffer = new GraphicBuffer(
-                    kDebugData.width, kDebugData.height, PIXEL_FORMAT_RGBA_8888,
-                    GraphicBuffer::USAGE_SW_WRITE_RARELY);
-            uint32_t* bits;
-            buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&bits));
-            size_t w = buffer->getStride();
-            size_t h = buffer->getHeight();
-            memset(bits, 0, w*h*4);
-            for (size_t y=0 ; y<kDebugData.height ; y++) {
-                for (size_t x=0 ; x<kDebugData.width ; x++) {
-                    bits[x] = (kDebugData.bits[y*kDebugData.width+x] == 'X') ? 0xFF000000 : 0xFFFFFFFF;
-                }
-                bits += w;
-            }
-            buffer->unlock();
-            mReleasedTexImageBuffer = buffer;
-        }
-
         mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT;
-        mCurrentTextureBuf = mReleasedTexImageBuffer;
+        mCurrentTextureBuf = getDebugTexImageBuffer();
         mCurrentCrop.makeInvalid();
         mCurrentTransform = 0;
         mCurrentScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
@@ -249,6 +230,31 @@
     return NO_ERROR;
 }
 
+sp<GraphicBuffer> GLConsumer::getDebugTexImageBuffer() {
+    Mutex::Autolock _l(sStaticInitLock);
+    if (CC_UNLIKELY(sReleasedTexImageBuffer == NULL)) {
+        // The first time, create the debug texture in case the application
+        // continues to use it.
+        sp<GraphicBuffer> buffer = new GraphicBuffer(
+                kDebugData.width, kDebugData.height, PIXEL_FORMAT_RGBA_8888,
+                GraphicBuffer::USAGE_SW_WRITE_RARELY);
+        uint32_t* bits;
+        buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&bits));
+        size_t w = buffer->getStride();
+        size_t h = buffer->getHeight();
+        memset(bits, 0, w*h*4);
+        for (size_t y=0 ; y<kDebugData.height ; y++) {
+            for (size_t x=0 ; x<kDebugData.width ; x++) {
+                bits[x] = (kDebugData.bits[y*kDebugData.width+x] == 'X') ? 0xFF000000 : 0xFFFFFFFF;
+            }
+            bits += w;
+        }
+        buffer->unlock();
+        sReleasedTexImageBuffer = buffer;
+    }
+    return sReleasedTexImageBuffer;
+}
+
 status_t GLConsumer::acquireBufferLocked(BufferQueue::BufferItem *item,
         nsecs_t presentWhen) {
     status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen);