Fix remote GraphicBuffer allocation in SurfaceFlinger.

This change fixes a horrible hack that I did to allow application
processes to create GraphicBuffer objects by making a binder call to
SurfaceFlinger.  This change introduces a new binder interface
specifically for doing this, and does it in such a way that
SurfaceFlinger will maintain a reference to the buffers until the app is
done with them.

Change-Id: Icb240397c6c206d7f69124c1497a829f051cb49b
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index 09cf2a2..002e48b 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -26,12 +26,15 @@
 #include <ui/GraphicBuffer.h>
 
 #include <utils/threads.h>
+#include <utils/Vector.h>
 
 #define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture"
 
 namespace android {
 // ----------------------------------------------------------------------------
 
+class IGraphicBufferAlloc;
+
 class SurfaceTexture : public BnSurfaceTexture {
 public:
     enum { MIN_BUFFER_SLOTS = 3 };
@@ -140,6 +143,12 @@
     // reset mCurrentTexture to INVALID_BUFFER_SLOT.
     int mCurrentTexture;
 
+    // mCurrentTextureBuf is the graphic buffer of the current texture. It's
+    // possible that this buffer is not associated with any buffer slot, so we
+    // must track it separately in order to properly use
+    // IGraphicBufferAlloc::freeAllGraphicBuffersExcept.
+    sp<GraphicBuffer> mCurrentTextureBuf;
+
     // mCurrentCrop is the crop rectangle that applies to the current texture.
     // It gets set to mLastQueuedCrop each time updateTexImage is called.
     Rect mCurrentCrop;
@@ -176,6 +185,16 @@
     // changed with a call to setTexName.
     const GLuint mTexName;
 
+    // mGraphicBufferAlloc is the connection to SurfaceFlinger that is used to
+    // allocate new GraphicBuffer objects.
+    sp<IGraphicBufferAlloc> mGraphicBufferAlloc;
+
+    // mAllocdBuffers is mirror of the list of buffers that SurfaceFlinger is
+    // referencing. This is kept so that gralloc implementations do not need to
+    // properly handle the case where SurfaceFlinger no longer holds a reference
+    // to a buffer, but other processes do.
+    Vector<sp<GraphicBuffer> > mAllocdBuffers;
+
     // mMutex is the mutex used to prevent concurrent access to the member
     // variables of SurfaceTexture objects. It must be locked whenever the
     // member variables are accessed.
diff --git a/include/surfaceflinger/IGraphicBufferAlloc.h b/include/surfaceflinger/IGraphicBufferAlloc.h
new file mode 100644
index 0000000..d996af7
--- /dev/null
+++ b/include/surfaceflinger/IGraphicBufferAlloc.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H
+#define ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/RefBase.h>
+
+#include <binder/IInterface.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class IGraphicBufferAlloc : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(GraphicBufferAlloc);
+
+    /* Create a new GraphicBuffer for the client to use.  The server will
+     * maintain a reference to the newly created GraphicBuffer until
+     * freeAllGraphicBuffers is called.
+     */
+    virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
+            PixelFormat format, uint32_t usage) = 0;
+
+    /* Free all but one of the GraphicBuffer objects that the server is
+     * currently referencing. If bufIndex is not a valid index of the buffers
+     * the server is referencing, then all buffers are freed.
+     */
+    virtual void freeAllGraphicBuffersExcept(int bufIndex) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnGraphicBufferAlloc : public BnInterface<IGraphicBufferAlloc>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
index 1bab7d7..56ed3a4 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -28,6 +28,7 @@
 #include <ui/PixelFormat.h>
 
 #include <surfaceflinger/ISurfaceComposerClient.h>
+#include <surfaceflinger/IGraphicBufferAlloc.h>
 
 namespace android {
 // ----------------------------------------------------------------------------
@@ -96,6 +97,10 @@
      */
     virtual sp<ISurfaceComposerClient> createClientConnection() = 0;
 
+    /* create a graphic buffer allocator
+     */
+    virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc() = 0;
+
     /* retrieve the control block */
     virtual sp<IMemoryHeap> getCblk() const = 0;
 
@@ -131,13 +136,6 @@
      * This is an ASYNCHRONOUS call.
      */
     virtual void signal() const = 0;
-
-    /* Create a new GraphicBuffer for the client to use.  SurfaceFlinger will
-     * not maintain a reference to the GraphicBuffer, so the underlying native
-     * handle will be freed once the client references are released.
-     */
-    virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
-            PixelFormat format, uint32_t usage) const = 0;
 };
 
 // ----------------------------------------------------------------------------
@@ -151,7 +149,7 @@
         BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
         CREATE_CONNECTION,
         CREATE_CLIENT_CONNECTION,
-        CREATE_GRAPHIC_BUFFER,
+        CREATE_GRAPHIC_BUFFER_ALLOC,
         GET_CBLK,
         OPEN_GLOBAL_TRANSACTION,
         CLOSE_GLOBAL_TRANSACTION,