Change BufferQueue into producer/consumer wrapper

Now that BufferQueue has been split into core + producer + consumer,
rewrite BufferQueue to be a thin layer over a producer and consumer
interface. Eventually, this layer will be deprecated in favor of
only using either the producer or consumer interface, as applicable.

Change-Id: I340ae5f5b633b244fb594615ff52ba50b9e2f7e4
diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h
index 15dc645..7eaf842 100644
--- a/include/gui/BufferQueue.h
+++ b/include/gui/BufferQueue.h
@@ -17,23 +17,16 @@
 #ifndef ANDROID_GUI_BUFFERQUEUE_H
 #define ANDROID_GUI_BUFFERQUEUE_H
 
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
+#include <gui/BufferQueueProducer.h>
+#include <gui/BufferQueueConsumer.h>
+#include <gui/IConsumerListener.h>
+
+// These are only required to keep other parts of the framework with incomplete
+// dependencies building successfully
+#include <gui/IGraphicBufferAlloc.h>
 
 #include <binder/IBinder.h>
 
-#include <gui/IConsumerListener.h>
-#include <gui/IGraphicBufferAlloc.h>
-#include <gui/IGraphicBufferProducer.h>
-#include <gui/IGraphicBufferConsumer.h>
-
-#include <ui/Fence.h>
-#include <ui/GraphicBuffer.h>
-
-#include <utils/String8.h>
-#include <utils/Vector.h>
-#include <utils/threads.h>
-
 namespace android {
 // ----------------------------------------------------------------------------
 
@@ -317,264 +310,8 @@
     virtual void dump(String8& result, const char* prefix) const;
 
 private:
-    // The default API number used to indicate no producer client is connected.
-    enum { NO_CONNECTED_API = 0 };
-
-    // Aliases for using enums from <IGraphicBufferConsumer.h>
-    enum { STALE_BUFFER_SLOT = IGraphicBufferConsumer::STALE_BUFFER_SLOT };
-
-    // freeBufferLocked frees the GraphicBuffer and sync resources for the
-    // given slot.
-    void freeBufferLocked(int index);
-
-    // freeAllBuffersLocked frees the GraphicBuffer and sync resources for
-    // all slots.
-    void freeAllBuffersLocked();
-
-    // setDefaultMaxBufferCountLocked sets the maximum number of buffer slots
-    // that will be used if the producer does not override the buffer slot
-    // count.  The count must be between 2 and NUM_BUFFER_SLOTS, inclusive.
-    // The initial default is 2.
-    status_t setDefaultMaxBufferCountLocked(int count);
-
-    // getMinUndequeuedBufferCount returns the minimum number of buffers
-    // that must remain in a state other than DEQUEUED.
-    // The async parameter tells whether we're in asynchronous mode.
-    int getMinUndequeuedBufferCount(bool async) const;
-
-    // getMinBufferCountLocked returns the minimum number of buffers allowed
-    // given the current BufferQueue state.
-    // The async parameter tells whether we're in asynchronous mode.
-    int getMinMaxBufferCountLocked(bool async) const;
-
-    // getMaxBufferCountLocked returns the maximum number of buffers that can
-    // be allocated at once.  This value depends upon the following member
-    // variables:
-    //
-    //      mDequeueBufferCannotBlock
-    //      mMaxAcquiredBufferCount
-    //      mDefaultMaxBufferCount
-    //      mOverrideMaxBufferCount
-    //      async parameter
-    //
-    // Any time one of these member variables is changed while a producer is
-    // connected, mDequeueCondition must be broadcast.
-    int getMaxBufferCountLocked(bool async) const;
-
-    // stillTracking returns true iff the buffer item is still being tracked
-    // in one of the slots.
-    bool stillTracking(const BufferItem *item) const;
-
-    struct BufferSlot {
-
-        BufferSlot()
-        : mEglDisplay(EGL_NO_DISPLAY),
-          mBufferState(BufferSlot::FREE),
-          mRequestBufferCalled(false),
-          mFrameNumber(0),
-          mEglFence(EGL_NO_SYNC_KHR),
-          mAcquireCalled(false),
-          mNeedsCleanupOnRelease(false) {
-        }
-
-        // mGraphicBuffer points to the buffer allocated for this slot or is NULL
-        // if no buffer has been allocated.
-        sp<GraphicBuffer> mGraphicBuffer;
-
-        // mEglDisplay is the EGLDisplay used to create EGLSyncKHR objects.
-        EGLDisplay mEglDisplay;
-
-        // BufferState represents the different states in which a buffer slot
-        // can be.  All slots are initially FREE.
-        enum BufferState {
-            // FREE indicates that the buffer is available to be dequeued
-            // by the producer.  The buffer may be in use by the consumer for
-            // a finite time, so the buffer must not be modified until the
-            // associated fence is signaled.
-            //
-            // The slot is "owned" by BufferQueue.  It transitions to DEQUEUED
-            // when dequeueBuffer is called.
-            FREE = 0,
-
-            // DEQUEUED indicates that the buffer has been dequeued by the
-            // producer, but has not yet been queued or canceled.  The
-            // producer may modify the buffer's contents as soon as the
-            // associated ready fence is signaled.
-            //
-            // The slot is "owned" by the producer.  It can transition to
-            // QUEUED (via queueBuffer) or back to FREE (via cancelBuffer).
-            DEQUEUED = 1,
-
-            // QUEUED indicates that the buffer has been filled by the
-            // producer and queued for use by the consumer.  The buffer
-            // contents may continue to be modified for a finite time, so
-            // the contents must not be accessed until the associated fence
-            // is signaled.
-            //
-            // The slot is "owned" by BufferQueue.  It can transition to
-            // ACQUIRED (via acquireBuffer) or to FREE (if another buffer is
-            // queued in asynchronous mode).
-            QUEUED = 2,
-
-            // ACQUIRED indicates that the buffer has been acquired by the
-            // consumer.  As with QUEUED, the contents must not be accessed
-            // by the consumer until the fence is signaled.
-            //
-            // The slot is "owned" by the consumer.  It transitions to FREE
-            // when releaseBuffer is called.
-            ACQUIRED = 3
-        };
-
-        // mBufferState is the current state of this buffer slot.
-        BufferState mBufferState;
-
-        // mRequestBufferCalled is used for validating that the producer did
-        // call requestBuffer() when told to do so. Technically this is not
-        // needed but useful for debugging and catching producer bugs.
-        bool mRequestBufferCalled;
-
-        // mFrameNumber is the number of the queued frame for this slot.  This
-        // is used to dequeue buffers in LRU order (useful because buffers
-        // may be released before their release fence is signaled).
-        uint64_t mFrameNumber;
-
-        // mEglFence is the EGL sync object that must signal before the buffer
-        // associated with this buffer slot may be dequeued. It is initialized
-        // to EGL_NO_SYNC_KHR when the buffer is created and may be set to a
-        // new sync object in releaseBuffer.  (This is deprecated in favor of
-        // mFence, below.)
-        EGLSyncKHR mEglFence;
-
-        // mFence is a fence which will signal when work initiated by the
-        // previous owner of the buffer is finished. When the buffer is FREE,
-        // the fence indicates when the consumer has finished reading
-        // from the buffer, or when the producer has finished writing if it
-        // called cancelBuffer after queueing some writes. When the buffer is
-        // QUEUED, it indicates when the producer has finished filling the
-        // buffer. When the buffer is DEQUEUED or ACQUIRED, the fence has been
-        // passed to the consumer or producer along with ownership of the
-        // buffer, and mFence is set to NO_FENCE.
-        sp<Fence> mFence;
-
-        // Indicates whether this buffer has been seen by a consumer yet
-        bool mAcquireCalled;
-
-        // Indicates whether this buffer needs to be cleaned up by the
-        // consumer.  This is set when a buffer in ACQUIRED state is freed.
-        // It causes releaseBuffer to return STALE_BUFFER_SLOT.
-        bool mNeedsCleanupOnRelease;
-    };
-
-    // mSlots is the array of buffer slots that must be mirrored on the
-    // producer side. This allows buffer ownership to be transferred between
-    // the producer and consumer without sending a GraphicBuffer over binder.
-    // The entire array is initialized to NULL at construction time, and
-    // buffers are allocated for a slot when requestBuffer is called with
-    // that slot's index.
-    BufferSlot mSlots[NUM_BUFFER_SLOTS];
-
-    // mDefaultWidth holds the default width of allocated buffers. It is used
-    // in dequeueBuffer() if a width and height of zero is specified.
-    uint32_t mDefaultWidth;
-
-    // mDefaultHeight holds the default height of allocated buffers. It is used
-    // in dequeueBuffer() if a width and height of zero is specified.
-    uint32_t mDefaultHeight;
-
-    // mMaxAcquiredBufferCount is the number of buffers that the consumer may
-    // acquire at one time.  It defaults to 1 and can be changed by the
-    // consumer via the setMaxAcquiredBufferCount method, but this may only be
-    // done when no producer is connected to the BufferQueue.
-    //
-    // This value is used to derive the value returned for the
-    // MIN_UNDEQUEUED_BUFFERS query by the producer.
-    int mMaxAcquiredBufferCount;
-
-    // mDefaultMaxBufferCount is the default limit on the number of buffers
-    // that will be allocated at one time.  This default limit is set by the
-    // consumer.  The limit (as opposed to the default limit) may be
-    // overridden by the producer.
-    int mDefaultMaxBufferCount;
-
-    // mOverrideMaxBufferCount is the limit on the number of buffers that will
-    // be allocated at one time. This value is set by the image producer by
-    // calling setBufferCount. The default is zero, which means the producer
-    // doesn't care about the number of buffers in the pool. In that case
-    // mDefaultMaxBufferCount is used as the limit.
-    int mOverrideMaxBufferCount;
-
-    // mGraphicBufferAlloc is the connection to SurfaceFlinger that is used to
-    // allocate new GraphicBuffer objects.
-    sp<IGraphicBufferAlloc> mGraphicBufferAlloc;
-
-    // mConsumerListener is used to notify the connected consumer of
-    // asynchronous events that it may wish to react to.  It is initially set
-    // to NULL and is written by consumerConnect and consumerDisconnect.
-    sp<IConsumerListener> mConsumerListener;
-
-    // mConsumerControlledByApp whether the connected consumer is controlled by the
-    // application.
-    bool mConsumerControlledByApp;
-
-    // mDequeueBufferCannotBlock whether dequeueBuffer() isn't allowed to block.
-    // this flag is set during connect() when both consumer and producer are controlled
-    // by the application.
-    bool mDequeueBufferCannotBlock;
-
-    // mUseAsyncBuffer whether an extra buffer is used in async mode to prevent
-    // dequeueBuffer() from ever blocking.
-    bool mUseAsyncBuffer;
-
-    // mConnectedApi indicates the producer API that is currently connected
-    // to this BufferQueue.  It defaults to NO_CONNECTED_API (= 0), and gets
-    // updated by the connect and disconnect methods.
-    int mConnectedApi;
-
-    // mDequeueCondition condition used for dequeueBuffer in synchronous mode
-    mutable Condition mDequeueCondition;
-
-    // mQueue is a FIFO of queued buffers used in synchronous mode
-    typedef Vector<BufferItem> Fifo;
-    Fifo mQueue;
-
-    // mAbandoned indicates that the BufferQueue will no longer be used to
-    // consume image buffers pushed to it using the IGraphicBufferProducer
-    // interface.  It is initialized to false, and set to true in the
-    // consumerDisconnect method.  A BufferQueue that has been abandoned will
-    // return the NO_INIT error from all IGraphicBufferProducer methods
-    // capable of returning an error.
-    bool mAbandoned;
-
-    // mConsumerName is a string used to identify the BufferQueue in log
-    // messages.  It is set by the setConsumerName method.
-    String8 mConsumerName;
-
-    // mMutex is the mutex used to prevent concurrent access to the member
-    // variables of BufferQueue objects. It must be locked whenever the
-    // member variables are accessed.
-    mutable Mutex mMutex;
-
-    // mFrameCounter is the free running counter, incremented on every
-    // successful queueBuffer call, and buffer allocation.
-    uint64_t mFrameCounter;
-
-    // mBufferHasBeenQueued is true once a buffer has been queued.  It is
-    // reset when something causes all buffers to be freed (e.g. changing the
-    // buffer count).
-    bool mBufferHasBeenQueued;
-
-    // mDefaultBufferFormat can be set so it will override
-    // the buffer format when it isn't specified in dequeueBuffer
-    uint32_t mDefaultBufferFormat;
-
-    // mConsumerUsageBits contains flags the consumer wants for GraphicBuffers
-    uint32_t mConsumerUsageBits;
-
-    // mTransformHint is used to optimize for screen rotations
-    uint32_t mTransformHint;
-
-    // mConnectedProducerToken is used to set a binder death notification on the producer
-    sp<IBinder> mConnectedProducerToken;
+    sp<BufferQueueProducer> mProducer;
+    sp<BufferQueueConsumer> mConsumer;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/gui/BufferQueueConsumer.h b/include/gui/BufferQueueConsumer.h
index 0980ebb..20db98c 100644
--- a/include/gui/BufferQueueConsumer.h
+++ b/include/gui/BufferQueueConsumer.h
@@ -20,7 +20,7 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
-#include <gui/BufferQueueCore.h>
+#include <gui/BufferQueueDefs.h>
 #include <gui/IGraphicBufferConsumer.h>
 
 namespace android {
@@ -136,10 +136,34 @@
     // dump our state in a String
     virtual void dump(String8& result, const char* prefix) const;
 
+    // Functions required for backwards compatibility.
+    // These will be modified/renamed in IGraphicBufferConsumer and will be
+    // removed from this class at that time. See b/13306289.
+
+    virtual status_t releaseBuffer(int buf, uint64_t frameNumber,
+            EGLDisplay display, EGLSyncKHR fence,
+            const sp<Fence>& releaseFence) {
+        return releaseBuffer(buf, frameNumber, releaseFence, display, fence);
+    }
+
+    virtual status_t consumerConnect(const sp<IConsumerListener>& consumer,
+            bool controlledByApp) {
+        return connect(consumer, controlledByApp);
+    }
+
+    virtual status_t consumerDisconnect() { return disconnect(); }
+
+    // End functions required for backwards compatibility
+
 private:
     sp<BufferQueueCore> mCore;
-    BufferQueueCore::SlotsType& mSlots;
-    String8 mConsumerName; // Cached from mCore. Updated on setConsumerName.
+
+    // This references mCore->mSlots. Lock mCore->mMutex while accessing.
+    BufferQueueDefs::SlotsType& mSlots;
+
+    // This is a cached copy of the name stored in the BufferQueueCore.
+    // It's updated during setConsumerName.
+    String8 mConsumerName;
 
 }; // class BufferQueueConsumer
 
diff --git a/include/gui/BufferQueueCore.h b/include/gui/BufferQueueCore.h
index ef11c61..f4341f8 100644
--- a/include/gui/BufferQueueCore.h
+++ b/include/gui/BufferQueueCore.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_GUI_BUFFERQUEUECORE_H
 #define ANDROID_GUI_BUFFERQUEUECORE_H
 
+#include <gui/BufferQueueDefs.h>
 #include <gui/BufferSlot.h>
 
 #include <utils/Condition.h>
@@ -54,22 +55,17 @@
     friend class BufferQueueConsumer;
 
 public:
-    // BufferQueue will keep track of at most this value of buffers. Attempts
-    // at runtime to increase the number of buffers past this will fail.
-    enum { NUM_BUFFER_SLOTS = 32 };
-
     // Used as a placeholder slot number when the value isn't pointing to an
     // existing buffer.
     enum { INVALID_BUFFER_SLOT = -1 }; // TODO: Extract from IGBC::BufferItem
 
     // We reserve two slots in order to guarantee that the producer and
     // consumer can run asynchronously.
-    enum { MAX_MAX_ACQUIRED_BUFFERS = NUM_BUFFER_SLOTS - 2 };
+    enum { MAX_MAX_ACQUIRED_BUFFERS = BufferQueueDefs::NUM_BUFFER_SLOTS - 2 };
 
     // The default API number used to indicate that no producer is connected
     enum { NO_CONNECTED_API = 0 };
 
-    typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS];
     typedef Vector<BufferItem> Fifo;
 
     // BufferQueueCore manages a pool of gralloc memory slots to be used by
@@ -79,38 +75,159 @@
     virtual ~BufferQueueCore();
 
 private:
+    // Dump our state in a string
     void dump(String8& result, const char* prefix) const;
 
+    // getMinUndequeuedBufferCountLocked returns the minimum number of buffers
+    // that must remain in a state other than DEQUEUED. The async parameter
+    // tells whether we're in asynchronous mode.
     int getMinUndequeuedBufferCountLocked(bool async) const;
+
+    // getMinMaxBufferCountLocked returns the minimum number of buffers allowed
+    // given the current BufferQueue state. The async parameter tells whether
+    // we're in asynchonous mode.
     int getMinMaxBufferCountLocked(bool async) const;
+
+    // getMaxBufferCountLocked returns the maximum number of buffers that can be
+    // allocated at once. This value depends on the following member variables:
+    //
+    //     mDequeueBufferCannotBlock
+    //     mMaxAcquiredBufferCount
+    //     mDefaultMaxBufferCount
+    //     mOverrideMaxBufferCount
+    //     async parameter
+    //
+    // Any time one of these member variables is changed while a producer is
+    // connected, mDequeueCondition must be broadcast.
     int getMaxBufferCountLocked(bool async) const;
+
+    // setDefaultMaxBufferCountLocked sets the maximum number of buffer slots
+    // that will be used if the producer does not override the buffer slot
+    // count. The count must be between 2 and NUM_BUFFER_SLOTS, inclusive. The
+    // initial default is 2.
     status_t setDefaultMaxBufferCountLocked(int count);
+
+    // freeBufferLocked frees the GraphicBuffer and sync resources for the
+    // given slot.
     void freeBufferLocked(int slot);
+
+    // freeAllBuffersLocked frees the GraphicBuffer and sync resources for
+    // all slots.
     void freeAllBuffersLocked();
+
+    // stillTracking returns true iff the buffer item is still being tracked
+    // in one of the slots.
     bool stillTracking(const BufferItem* item) const;
 
-    const sp<IGraphicBufferAlloc>& mAllocator;
+    // mAllocator is the connection to SurfaceFlinger that is used to allocate
+    // new GraphicBuffer objects.
+    sp<IGraphicBufferAlloc> mAllocator;
+
+    // mMutex is the mutex used to prevent concurrent access to the member
+    // variables of BufferQueueCore objects. It must be locked whenever any
+    // member variable is accessed.
     mutable Mutex mMutex;
+
+    // mIsAbandoned indicates that the BufferQueue will no longer be used to
+    // consume image buffers pushed to it using the IGraphicBufferProducer
+    // interface. It is initialized to false, and set to true in the
+    // consumerDisconnect method. A BufferQueue that is abandoned will return
+    // the NO_INIT error from all IGraphicBufferProducer methods capable of
+    // returning an error.
     bool mIsAbandoned;
+
+    // mConsumerControlledByApp indicates whether the connected consumer is
+    // controlled by the application.
     bool mConsumerControlledByApp;
+
+    // mConsumerName is a string used to identify the BufferQueue in log
+    // messages. It is set by the IGraphicBufferConsumer::setConsumerName
+    // method.
     String8 mConsumerName;
+
+    // mConsumerListener is used to notify the connected consumer of
+    // asynchronous events that it may wish to react to. It is initially
+    // set to NULL and is written by consumerConnect and consumerDisconnect.
     sp<IConsumerListener> mConsumerListener;
+
+    // mConsumerUsageBits contains flags that the consumer wants for
+    // GraphicBuffers.
     uint32_t mConsumerUsageBits;
+
+    // mConnectedApi indicates the producer API that is currently connected
+    // to this BufferQueue. It defaults to NO_CONNECTED_API, and gets updated
+    // by the connect and disconnect methods.
     int mConnectedApi;
+
+    // mConnectedProducerToken is used to set a binder death notification on
+    // the producer.
     sp<IBinder> mConnectedProducerToken;
-    BufferSlot mSlots[NUM_BUFFER_SLOTS];
+
+    // mSlots is an array of buffer slots that must be mirrored on the producer
+    // side. This allows buffer ownership to be transferred between the producer
+    // and consumer without sending a GraphicBuffer over Binder. The entire
+    // array is initialized to NULL at construction time, and buffers are
+    // allocated for a slot when requestBuffer is called with that slot's index.
+    BufferQueueDefs::SlotsType mSlots;
+
+    // mQueue is a FIFO of queued buffers used in synchronous mode.
     Fifo mQueue;
+
+    // mOverrideMaxBufferCount is the limit on the number of buffers that will
+    // be allocated at one time. This value is set by the producer by calling
+    // setBufferCount. The default is 0, which means that the producer doesn't
+    // care about the number of buffers in the pool. In that case,
+    // mDefaultMaxBufferCount is used as the limit.
     int mOverrideMaxBufferCount;
+
+    // mDequeueCondition is a condition variable used for dequeueBuffer in
+    // synchronous mode.
     mutable Condition mDequeueCondition;
+
+    // mUseAsyncBuffer indicates whether an extra buffer is used in async mode
+    // to prevent dequeueBuffer from blocking.
     bool mUseAsyncBuffer;
+
+    // mDequeueBufferCannotBlock indicates whether dequeueBuffer is allowed to
+    // block. This flag is set during connect when both the producer and
+    // consumer are controlled by the application.
     bool mDequeueBufferCannotBlock;
+
+    // mDefaultBufferFormat can be set so it will override the buffer format
+    // when it isn't specified in dequeueBuffer.
     uint32_t mDefaultBufferFormat;
+
+    // mDefaultWidth holds the default width of allocated buffers. It is used
+    // in dequeueBuffer if a width and height of 0 are specified.
     int mDefaultWidth;
+
+    // mDefaultHeight holds the default height of allocated buffers. It is used
+    // in dequeueBuffer if a width and height of 0 are specified.
     int mDefaultHeight;
+
+    // mDefaultMaxBufferCount is the default limit on the number of buffers that
+    // will be allocated at one time. This default limit is set by the consumer.
+    // The limit (as opposed to the default limit) may be overriden by the
+    // producer.
     int mDefaultMaxBufferCount;
+
+    // mMaxAcquiredBufferCount is the number of buffers that the consumer may
+    // acquire at one time. It defaults to 1, and can be changed by the consumer
+    // via setMaxAcquiredBufferCount, but this may only be done while no
+    // producer is connected to the BufferQueue. This value is used to derive
+    // the value returned for the MIN_UNDEQUEUED_BUFFERS query to the producer.
     int mMaxAcquiredBufferCount;
+
+    // mBufferHasBeenQueued is true once a buffer has been queued. It is reset
+    // when something causes all buffers to be freed (e.g., changing the buffer
+    // count).
     bool mBufferHasBeenQueued;
+
+    // mFrameCounter is the free running counter, incremented on every
+    // successful queueBuffer call and buffer allocation.
     uint64_t mFrameCounter;
+
+    // mTransformHint is used to optimize for screen rotations.
     uint32_t mTransformHint;
 
 }; // class BufferQueueCore
diff --git a/include/gui/BufferQueueDefs.h b/include/gui/BufferQueueDefs.h
new file mode 100644
index 0000000..bccc881
--- /dev/null
+++ b/include/gui/BufferQueueDefs.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2014 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_BUFFERQUEUECOREDEFS_H
+#define ANDROID_GUI_BUFFERQUEUECOREDEFS_H
+
+#include <gui/BufferSlot.h>
+
+namespace android {
+    class BufferQueueCore;
+
+    namespace BufferQueueDefs {
+        // BufferQueue will keep track of at most this value of buffers.
+        // Attempts at runtime to increase the number of buffers past this
+        // will fail.
+        enum { NUM_BUFFER_SLOTS = 32 };
+
+        typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS];
+    } // namespace BufferQueueDefs
+} // namespace android
+
+#endif
diff --git a/include/gui/BufferQueueProducer.h b/include/gui/BufferQueueProducer.h
index 7f063aa..8912097 100644
--- a/include/gui/BufferQueueProducer.h
+++ b/include/gui/BufferQueueProducer.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_GUI_BUFFERQUEUEPRODUCER_H
 #define ANDROID_GUI_BUFFERQUEUEPRODUCER_H
 
-#include <gui/BufferQueueCore.h>
+#include <gui/BufferQueueDefs.h>
 #include <gui/IGraphicBufferProducer.h>
 
 namespace android {
@@ -26,8 +26,9 @@
 
 class BufferQueueProducer : public BnGraphicBufferProducer,
                             private IBinder::DeathRecipient {
-
 public:
+    friend class BufferQueue; // Needed to access binderDied
+
     BufferQueueProducer(const sp<BufferQueueCore>& core);
     virtual ~BufferQueueProducer();
 
@@ -151,7 +152,9 @@
     virtual void binderDied(const wp<IBinder>& who);
 
     sp<BufferQueueCore> mCore;
-    BufferQueueCore::SlotsType& mSlots;
+
+    // This references mCore->mSlots. Lock mCore->mMutex while accessing.
+    BufferQueueDefs::SlotsType& mSlots;
 
     // This is a cached copy of the name stored in the BufferQueueCore.
     // It's updated during connect and dequeueBuffer (which should catch