surfaceflinger: refactor FrambufferSurface

This change refactors the FramebufferSurface class to inherit from the new
ConsumerBase class.

Bug: 6620200
Change-Id: I46ec942ddb019658e3c5e79465548b171b2261f2
diff --git a/include/gui/ConsumerBase.h b/include/gui/ConsumerBase.h
new file mode 100644
index 0000000..d2bf0f6
--- /dev/null
+++ b/include/gui/ConsumerBase.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2010 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_GUI_CONSUMERBASE_H
+#define ANDROID_GUI_CONSUMERBASE_H
+
+#include <gui/BufferQueue.h>
+
+#include <ui/GraphicBuffer.h>
+
+#include <utils/String8.h>
+#include <utils/Vector.h>
+#include <utils/threads.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class String8;
+
+// ConsumerBase is a base class for BufferQueue consumer end-points. It
+// handles common tasks like management of the connection to the BufferQueue
+// and the buffer pool.
+class ConsumerBase : public virtual RefBase,
+        protected BufferQueue::ConsumerListener {
+public:
+    struct FrameAvailableListener : public virtual RefBase {
+        // onFrameAvailable() is called each time an additional frame becomes
+        // available for consumption. This means that frames that are queued
+        // while in asynchronous mode only trigger the callback if no previous
+        // frames are pending. Frames queued while in synchronous mode always
+        // trigger the callback.
+        //
+        // This is called without any lock held and can be called concurrently
+        // by multiple threads.
+        virtual void onFrameAvailable() = 0;
+    };
+
+    virtual ~ConsumerBase();
+
+    // abandon frees all the buffers and puts the ConsumerBase into the
+    // 'abandoned' state.  Once put in this state the ConsumerBase can never
+    // leave it.  When in the 'abandoned' state, all methods of the
+    // ISurfaceTexture interface will fail with the NO_INIT error.
+    //
+    // Note that while calling this method causes all the buffers to be freed
+    // from the perspective of the the ConsumerBase, if there are additional
+    // references on the buffers (e.g. if a buffer is referenced by a client
+    // or by OpenGL ES as a texture) then those buffer will remain allocated.
+    void abandon();
+
+    // set the name of the ConsumerBase that will be used to identify it in
+    // log messages.
+    void setName(const String8& name);
+
+    // getBufferQueue returns the BufferQueue object to which this
+    // ConsumerBase is connected.
+    sp<BufferQueue> getBufferQueue() const;
+
+    // dump writes the current state to a string.  These methods should NOT be
+    // overridden by child classes.  Instead they should override the
+    // dumpLocked method, which is called by these methods after locking the
+    // mutex.
+    void dump(String8& result) const;
+    void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const;
+
+    // setFrameAvailableListener sets the listener object that will be notified
+    // when a new frame becomes available.
+    void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
+
+private:
+    ConsumerBase(const ConsumerBase&);
+    void operator=(const ConsumerBase&);
+
+protected:
+
+    // TODO: Fix this comment
+    // ConsumerBase constructs a new ConsumerBase object. tex indicates the
+    // name of the OpenGL ES texture to which images are to be streamed.
+    // allowSynchronousMode specifies whether or not synchronous mode can be
+    // enabled. texTarget specifies the OpenGL ES texture target to which the
+    // texture will be bound in updateTexImage. useFenceSync specifies whether
+    // fences should be used to synchronize access to buffers if that behavior
+    // is enabled at compile-time. A custom bufferQueue can be specified
+    // if behavior for queue/dequeue/connect etc needs to be customized.
+    // Otherwise a default BufferQueue will be created and used.
+    //
+    // For legacy reasons, the ConsumerBase is created in a state where it is
+    // considered attached to an OpenGL ES context for the purposes of the
+    // attachToContext and detachFromContext methods. However, despite being
+    // considered "attached" to a context, the specific OpenGL ES context
+    // doesn't get latched until the first call to updateTexImage. After that
+    // point, all calls to updateTexImage must be made with the same OpenGL ES
+    // context current.
+    //
+    // A ConsumerBase may be detached from one OpenGL ES context and then
+    // attached to a different context using the detachFromContext and
+    // attachToContext methods, respectively. The intention of these methods is
+    // purely to allow a ConsumerBase to be transferred from one consumer
+    // context to another. If such a transfer is not needed there is no
+    // requirement that either of these methods be called.
+    ConsumerBase(const sp<BufferQueue> &bufferQueue);
+
+    // Implementation of the BufferQueue::ConsumerListener interface.  These
+    // calls are used to notify the ConsumerBase of asynchronous events in the
+    // BufferQueue.
+    virtual void onFrameAvailable();
+    virtual void onBuffersReleased();
+
+    // freeBufferLocked frees up the given buffer slot.  If the slot has been
+    // initialized this will release the reference to the GraphicBuffer in that
+    // slot and destroy the EGLImage in that slot.  Otherwise it has no effect.
+    //
+    // This method must be called with mMutex locked.
+    virtual void freeBufferLocked(int slotIndex);
+
+    // abandonLocked puts the BufferQueue into the abandoned state, causing
+    // all future operations on it to fail. This method rather than the public
+    // abandon method should be overridden by child classes to add abandon-
+    // time behavior.
+    //
+    // This method must be called with mMutex locked.
+    virtual void abandonLocked();
+
+    virtual void dumpLocked(String8& result, const char* prefix, char* buffer,
+            size_t SIZE) const;
+
+    // acquireBufferLocked fetches the next buffer from the BufferQueue and
+    // updates the buffer slot for the buffer returned.
+    virtual status_t acquireBufferLocked(BufferQueue::BufferItem *item);
+
+    // releaseBufferLocked relinquishes control over a buffer, returning that
+    // control to the BufferQueue.
+    virtual status_t releaseBufferLocked(int buf, EGLDisplay display,
+           EGLSyncKHR eglFence, const sp<Fence>& fence);
+
+    // Slot contains the information and object references that
+    // ConsumerBase maintains about a BufferQueue buffer slot.
+    struct Slot {
+        // mGraphicBuffer is the Gralloc buffer store in the slot or NULL if
+        // no Gralloc buffer is in the slot.
+        sp<GraphicBuffer> mGraphicBuffer;
+
+        // mFence is a fence which will signal when the buffer associated with
+        // this buffer slot is no longer being used by the consumer and can be
+        // overwritten. The buffer can be dequeued before the fence signals;
+        // the producer is responsible for delaying writes until it signals.
+        sp<Fence> mFence;
+    };
+
+    // mSlots stores the buffers that have been allocated by the BufferQueue
+    // for each buffer slot.  It is initialized to null pointers, and gets
+    // filled in with the result of BufferQueue::acquire when the
+    // client dequeues a buffer from a
+    // slot that has not yet been used. The buffer allocated to a slot will also
+    // be replaced if the requested buffer usage or geometry differs from that
+    // of the buffer allocated to a slot.
+    Slot mSlots[BufferQueue::NUM_BUFFER_SLOTS];
+
+    // mAbandoned indicates that the BufferQueue will no longer be used to
+    // consume images buffers pushed to it using the ISurfaceTexture
+    // interface. It is initialized to false, and set to true in the abandon
+    // method.  A BufferQueue that has been abandoned will return the NO_INIT
+    // error from all IConsumerBase methods capable of returning an error.
+    bool mAbandoned;
+
+    // mName is a string used to identify the ConsumerBase in log messages.
+    // It can be set by the setName method.
+    String8 mName;
+
+    // mFrameAvailableListener is the listener object that will be called when a
+    // new frame becomes available. If it is not NULL it will be called from
+    // queueBuffer.
+    sp<FrameAvailableListener> mFrameAvailableListener;
+
+    // The ConsumerBase has-a BufferQueue and is responsible for creating this object
+    // if none is supplied
+    sp<BufferQueue> mBufferQueue;
+
+    // mAttached indicates whether the ConsumerBase is currently attached to
+    // an OpenGL ES context.  For legacy reasons, this is initialized to true,
+    // indicating that the ConsumerBase is considered to be attached to
+    // whatever context is current at the time of the first updateTexImage call.
+    // It is set to false by detachFromContext, and then set to true again by
+    // attachToContext.
+    bool mAttached;
+
+    // mMutex is the mutex used to prevent concurrent access to the member
+    // variables of ConsumerBase objects. It must be locked whenever the
+    // member variables are accessed.
+    mutable Mutex mMutex;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_CONSUMERBASE_H