diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index c14c950..0a77317 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -5,8 +5,13 @@
 	IGraphicBufferConsumer.cpp \
 	IConsumerListener.cpp \
 	BitTube.cpp \
+	BufferItem.cpp \
 	BufferItemConsumer.cpp \
 	BufferQueue.cpp \
+	BufferQueueConsumer.cpp \
+	BufferQueueCore.cpp \
+	BufferQueueProducer.cpp \
+	BufferSlot.cpp \
 	ConsumerBase.cpp \
 	CpuConsumer.cpp \
 	DisplayEventReceiver.cpp \
diff --git a/libs/gui/BufferItem.cpp b/libs/gui/BufferItem.cpp
new file mode 100644
index 0000000..cccb38e
--- /dev/null
+++ b/libs/gui/BufferItem.cpp
@@ -0,0 +1,190 @@
+/*
+ * 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.
+ */
+
+#include <gui/BufferItem.h>
+
+#include <ui/Fence.h>
+#include <ui/GraphicBuffer.h>
+
+#include <system/window.h>
+
+namespace android {
+
+BufferItem::BufferItem() :
+    mTransform(0),
+    mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
+    mTimestamp(0),
+    mIsAutoTimestamp(false),
+    mFrameNumber(0),
+    mSlot(INVALID_BUFFER_SLOT),
+    mIsDroppable(false),
+    mAcquireCalled(false),
+    mTransformToDisplayInverse(false) {
+    mCrop.makeInvalid();
+}
+
+BufferItem::operator IGraphicBufferConsumer::BufferItem() const {
+    IGraphicBufferConsumer::BufferItem bufferItem;
+    bufferItem.mTransform = mTransform;
+    bufferItem.mScalingMode = mScalingMode;
+    bufferItem.mTimestamp = mTimestamp;
+    bufferItem.mIsAutoTimestamp = mIsAutoTimestamp;
+    bufferItem.mFrameNumber = mFrameNumber;
+    bufferItem.mBuf = mSlot;
+    bufferItem.mIsDroppable = mIsDroppable;
+    bufferItem.mAcquireCalled = mAcquireCalled;
+    bufferItem.mTransformToDisplayInverse = mTransformToDisplayInverse;
+    bufferItem.mCrop = mCrop;
+    return bufferItem;
+}
+
+size_t BufferItem::getPodSize() const {
+    size_t c =  sizeof(mCrop) +
+            sizeof(mTransform) +
+            sizeof(mScalingMode) +
+            sizeof(mTimestamp) +
+            sizeof(mIsAutoTimestamp) +
+            sizeof(mFrameNumber) +
+            sizeof(mSlot) +
+            sizeof(mIsDroppable) +
+            sizeof(mAcquireCalled) +
+            sizeof(mTransformToDisplayInverse);
+    return c;
+}
+
+size_t BufferItem::getFlattenedSize() const {
+    size_t c = 0;
+    if (mGraphicBuffer != 0) {
+        c += mGraphicBuffer->getFlattenedSize();
+        FlattenableUtils::align<4>(c);
+    }
+    if (mFence != 0) {
+        c += mFence->getFlattenedSize();
+        FlattenableUtils::align<4>(c);
+    }
+    return sizeof(int32_t) + c + getPodSize();
+}
+
+size_t BufferItem::getFdCount() const {
+    size_t c = 0;
+    if (mGraphicBuffer != 0) {
+        c += mGraphicBuffer->getFdCount();
+    }
+    if (mFence != 0) {
+        c += mFence->getFdCount();
+    }
+    return c;
+}
+
+status_t BufferItem::flatten(
+        void*& buffer, size_t& size, int*& fds, size_t& count) const {
+
+    // make sure we have enough space
+    if (count < BufferItem::getFlattenedSize()) {
+        return NO_MEMORY;
+    }
+
+    // content flags are stored first
+    uint32_t& flags = *static_cast<uint32_t*>(buffer);
+
+    // advance the pointer
+    FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
+
+    flags = 0;
+    if (mGraphicBuffer != 0) {
+        status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
+        if (err) return err;
+        size -= FlattenableUtils::align<4>(buffer);
+        flags |= 1;
+    }
+    if (mFence != 0) {
+        status_t err = mFence->flatten(buffer, size, fds, count);
+        if (err) return err;
+        size -= FlattenableUtils::align<4>(buffer);
+        flags |= 2;
+    }
+
+    // check we have enough space (in case flattening the fence/graphicbuffer lied to us)
+    if (size < getPodSize()) {
+        return NO_MEMORY;
+    }
+
+    FlattenableUtils::write(buffer, size, mCrop);
+    FlattenableUtils::write(buffer, size, mTransform);
+    FlattenableUtils::write(buffer, size, mScalingMode);
+    FlattenableUtils::write(buffer, size, mTimestamp);
+    FlattenableUtils::write(buffer, size, mIsAutoTimestamp);
+    FlattenableUtils::write(buffer, size, mFrameNumber);
+    FlattenableUtils::write(buffer, size, mSlot);
+    FlattenableUtils::write(buffer, size, mIsDroppable);
+    FlattenableUtils::write(buffer, size, mAcquireCalled);
+    FlattenableUtils::write(buffer, size, mTransformToDisplayInverse);
+
+    return NO_ERROR;
+}
+
+status_t BufferItem::unflatten(
+        void const*& buffer, size_t& size, int const*& fds, size_t& count) {
+
+    if (size < sizeof(uint32_t))
+        return NO_MEMORY;
+
+    uint32_t flags = 0;
+    FlattenableUtils::read(buffer, size, flags);
+
+    if (flags & 1) {
+        mGraphicBuffer = new GraphicBuffer();
+        status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
+        if (err) return err;
+        size -= FlattenableUtils::align<4>(buffer);
+    }
+
+    if (flags & 2) {
+        mFence = new Fence();
+        status_t err = mFence->unflatten(buffer, size, fds, count);
+        if (err) return err;
+        size -= FlattenableUtils::align<4>(buffer);
+    }
+
+    // check we have enough space
+    if (size < getPodSize()) {
+        return NO_MEMORY;
+    }
+
+    FlattenableUtils::read(buffer, size, mCrop);
+    FlattenableUtils::read(buffer, size, mTransform);
+    FlattenableUtils::read(buffer, size, mScalingMode);
+    FlattenableUtils::read(buffer, size, mTimestamp);
+    FlattenableUtils::read(buffer, size, mIsAutoTimestamp);
+    FlattenableUtils::read(buffer, size, mFrameNumber);
+    FlattenableUtils::read(buffer, size, mSlot);
+    FlattenableUtils::read(buffer, size, mIsDroppable);
+    FlattenableUtils::read(buffer, size, mAcquireCalled);
+    FlattenableUtils::read(buffer, size, mTransformToDisplayInverse);
+
+    return NO_ERROR;
+}
+
+const char* BufferItem::scalingModeName(uint32_t scalingMode) {
+    switch (scalingMode) {
+        case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE";
+        case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW";
+        case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP";
+        default: return "Unknown";
+    }
+}
+
+} // namespace android
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
new file mode 100644
index 0000000..7b70df1
--- /dev/null
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -0,0 +1,398 @@
+/*
+ * 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.
+ */
+
+#include <gui/BufferItem.h>
+#include <gui/BufferQueueConsumer.h>
+#include <gui/BufferQueueCore.h>
+#include <gui/IConsumerListener.h>
+
+namespace android {
+
+BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
+    mCore(core),
+    mSlots(core->mSlots),
+    mConsumerName() {}
+
+BufferQueueConsumer::~BufferQueueConsumer() {}
+
+status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
+        nsecs_t expectedPresent) {
+    ATRACE_CALL();
+    Mutex::Autolock lock(mCore->mMutex);
+
+    // Check that the consumer doesn't currently have the maximum number of
+    // buffers acquired. We allow the max buffer count to be exceeded by one
+    // buffer so that the consumer can successfully set up the newly acquired
+    // buffer before releasing the old one.
+    int numAcquiredBuffers = 0;
+    for (int s = 0; s < BufferQueueCore::NUM_BUFFER_SLOTS; ++s) {
+        if (mSlots[s].mBufferState == BufferSlot::ACQUIRED) {
+            ++numAcquiredBuffers;
+        }
+    }
+    if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
+        BQ_LOGE("acquireBuffer: max acquired buffer count reached: %d (max %d)",
+                numAcquiredBuffers, mCore->mMaxAcquiredBufferCount);
+        return INVALID_OPERATION;
+    }
+
+    // Check if the queue is empty.
+    // In asynchronous mode the list is guaranteed to be one buffer deep,
+    // while in synchronous mode we use the oldest buffer.
+    if (mCore->mQueue.empty()) {
+        return NO_BUFFER_AVAILABLE;
+    }
+
+    BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
+
+    // If expectedPresent is specified, we may not want to return a buffer yet.
+    // If it's specified and there's more than one buffer queued, we may want
+    // to drop a buffer.
+    if (expectedPresent != 0) {
+        const int MAX_REASONABLE_NSEC = 1000000000ULL; // 1 second
+
+        // The 'expectedPresent' argument indicates when the buffer is expected
+        // to be presented on-screen. If the buffer's desired present time is
+        // earlier (less) than expectedPresent -- meaning it will be displayed
+        // on time or possibly late if we show it as soon as possible -- we
+        // acquire and return it. If we don't want to display it until after the
+        // expectedPresent time, we return PRESENT_LATER without acquiring it.
+        //
+        // To be safe, we don't defer acquisition if expectedPresent is more
+        // than one second in the future beyond the desired present time
+        // (i.e., we'd be holding the buffer for a long time).
+        //
+        // NOTE: Code assumes monotonic time values from the system clock
+        // are positive.
+
+        // Start by checking to see if we can drop frames. We skip this check if
+        // the timestamps are being auto-generated by Surface. If the app isn't
+        // generating timestamps explicitly, it probably doesn't want frames to
+        // be discarded based on them.
+        while (mCore->mQueue.size() > 1 && !mCore->mQueue[0].mIsAutoTimestamp) {
+            // If entry[1] is timely, drop entry[0] (and repeat). We apply an
+            // additional criterion here: we only drop the earlier buffer if our
+            // desiredPresent falls within +/- 1 second of the expected present.
+            // Otherwise, bogus desiredPresent times (e.g., 0 or a small
+            // relative timestamp), which normally mean "ignore the timestamp
+            // and acquire immediately", would cause us to drop frames.
+            //
+            // We may want to add an additional criterion: don't drop the
+            // earlier buffer if entry[1]'s fence hasn't signaled yet.
+            const BufferItem& bufferItem(mCore->mQueue[1]);
+            nsecs_t desiredPresent = bufferItem.mTimestamp;
+            if (desiredPresent < expectedPresent - MAX_REASONABLE_NSEC ||
+                    desiredPresent > expectedPresent) {
+                // This buffer is set to display in the near future, or
+                // desiredPresent is garbage. Either way we don't want to drop
+                // the previous buffer just to get this on the screen sooner.
+                BQ_LOGV("acquireBuffer: nodrop desire=%lld expect=%lld "
+                        "(%lld) now=%lld", desiredPresent, expectedPresent,
+                        desiredPresent - expectedPresent,
+                        systemTime(CLOCK_MONOTONIC));
+                break;
+            }
+
+            BQ_LOGV("acquireBuffer: drop desire=%lld expect=%lld size=%d",
+                    desiredPresent, expectedPresent, mCore->mQueue.size());
+            if (mCore->stillTracking(front)) {
+                // Front buffer is still in mSlots, so mark the slot as free
+                mSlots[front->mSlot].mBufferState = BufferSlot::FREE;
+            }
+            mCore->mQueue.erase(front);
+            front = mCore->mQueue.begin();
+        }
+
+        // See if the front buffer is due
+        nsecs_t desiredPresent = front->mTimestamp;
+        if (desiredPresent > expectedPresent &&
+                desiredPresent < expectedPresent + MAX_REASONABLE_NSEC) {
+            BQ_LOGV("acquireBuffer: defer desire=%lld expect=%lld "
+                    "(%lld) now=%lld", desiredPresent, expectedPresent,
+                    desiredPresent - expectedPresent,
+                    systemTime(CLOCK_MONOTONIC));
+            return PRESENT_LATER;
+        }
+
+        BQ_LOGV("acquireBuffer: accept desire=%lld expect=%lld "
+                "(%lld) now=%lld", desiredPresent, expectedPresent,
+                desiredPresent - expectedPresent,
+                systemTime(CLOCK_MONOTONIC));
+    }
+
+    int slot = front->mSlot;
+    *outBuffer = *front;
+    ATRACE_BUFFER_INDEX(slot);
+
+    BQ_LOGV("acquireBuffer: acquiring { slot=%d/%llu buffer=%p }",
+            slot, front->mFrameNumber, front->mGraphicBuffer->handle);
+    // If the front buffer is still being tracked, update its slot state
+    if (mCore->stillTracking(front)) {
+        mSlots[slot].mAcquireCalled = true;
+        mSlots[slot].mNeedsCleanupOnRelease = false;
+        mSlots[slot].mBufferState = BufferSlot::ACQUIRED;
+        mSlots[slot].mFence = Fence::NO_FENCE;
+    }
+
+    // If the buffer has previously been acquired by the consumer, set
+    // mGraphicBuffer to NULL to avoid unnecessarily remapping this buffer
+    // on the consumer side
+    if (outBuffer->mAcquireCalled) {
+        outBuffer->mGraphicBuffer = NULL;
+    }
+
+    mCore->mQueue.erase(front);
+    // TODO: Should this call be after we free a slot while dropping buffers?
+    // Simply acquiring the next buffer doesn't enable a producer to dequeue.
+    mCore->mDequeueCondition.broadcast();
+
+    ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
+
+    return NO_ERROR;
+}
+
+status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
+        const sp<Fence>& releaseFence, EGLDisplay eglDisplay,
+        EGLSyncKHR eglFence) {
+    ATRACE_CALL();
+    ATRACE_BUFFER_INDEX(slot);
+
+    if (slot == BufferQueueCore::INVALID_BUFFER_SLOT || releaseFence == NULL) {
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock lock(mCore->mMutex);
+
+    // If the frame number has changed because the buffer has been reallocated,
+    // we can ignore this releaseBuffer for the old buffer
+    if (frameNumber != mSlots[slot].mFrameNumber) {
+        return STALE_BUFFER_SLOT;
+    }
+
+    // Make sure this buffer hasn't been queued while acquired by the consumer
+    BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
+    while (current != mCore->mQueue.end()) {
+        if (current->mSlot == slot) {
+            BQ_LOGE("releaseBuffer: buffer slot %d pending release is "
+                    "currently queued", slot);
+            return -EINVAL;
+        }
+        ++current;
+    }
+
+    if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) {
+        mSlots[slot].mEglDisplay = eglDisplay;
+        mSlots[slot].mEglFence = eglFence;
+        mSlots[slot].mFence = releaseFence;
+        mSlots[slot].mBufferState = BufferSlot::FREE;
+    } else if (mSlots[slot].mNeedsCleanupOnRelease) {
+        BQ_LOGV("releaseBuffer: releasing a stale buffer slot %d "
+                "(state = %d)", slot, mSlots[slot].mBufferState);
+        mSlots[slot].mNeedsCleanupOnRelease = false;
+        return STALE_BUFFER_SLOT;
+    } else {
+        BQ_LOGV("releaseBuffer: attempted to release buffer slot %d "
+                "but its state was %d", slot, mSlots[slot].mBufferState);
+        return -EINVAL;
+    }
+
+    mCore->mDequeueCondition.broadcast();
+
+    return NO_ERROR;
+}
+
+status_t BufferQueueConsumer::connect(
+        const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
+    ATRACE_CALL();
+
+    if (consumerListener == NULL) {
+        BQ_LOGE("connect(C): consumerListener may not be NULL");
+        return BAD_VALUE;
+    }
+
+    BQ_LOGV("connect(C): controlledByApp=%s",
+            controlledByApp ? "true" : "false");
+
+    Mutex::Autolock lock(mCore->mMutex);
+
+    if (mCore->mIsAbandoned) {
+        BQ_LOGE("connect(C): BufferQueue has been abandoned");
+        return NO_INIT;
+    }
+
+    mCore->mConsumerListener = consumerListener;
+    mCore->mConsumerControlledByApp = controlledByApp;
+
+    return NO_ERROR;
+}
+
+status_t BufferQueueConsumer::disconnect() {
+    ATRACE_CALL();
+
+    BQ_LOGV("disconnect(C)");
+
+    Mutex::Autolock lock(mCore->mMutex);
+
+    if (mCore->mConsumerListener == NULL) {
+        BQ_LOGE("disconnect(C): no consumer is connected");
+        return -EINVAL;
+    }
+
+    mCore->mIsAbandoned = true;
+    mCore->mConsumerListener = NULL;
+    mCore->mQueue.clear();
+    mCore->freeAllBuffersLocked();
+    mCore->mDequeueCondition.broadcast();
+    return NO_ERROR;
+}
+
+status_t BufferQueueConsumer::getReleasedBuffers(uint32_t *outSlotMask) {
+    ATRACE_CALL();
+
+    if (outSlotMask == NULL) {
+        BQ_LOGE("getReleasedBuffers: outSlotMask may not be NULL");
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock lock(mCore->mMutex);
+
+    if (mCore->mIsAbandoned) {
+        BQ_LOGE("getReleasedBuffers: BufferQueue has been abandoned");
+        return NO_INIT;
+    }
+
+    uint32_t mask = 0;
+    for (int s = 0; s < BufferQueueCore::NUM_BUFFER_SLOTS; ++s) {
+        if (!mSlots[s].mAcquireCalled) {
+            mask |= (1u << s);
+        }
+    }
+
+    // Remove from the mask queued buffers for which acquire has been called,
+    // since the consumer will not receive their buffer addresses and so must
+    // retain their cached information
+    BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
+    while (current != mCore->mQueue.end()) {
+        if (current->mAcquireCalled) {
+            mask &= ~(1u << current->mSlot);
+        }
+        ++current;
+    }
+
+    BQ_LOGV("getReleasedBuffers: returning mask %#x", mask);
+    *outSlotMask = mask;
+    return NO_ERROR;
+}
+
+status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width,
+        uint32_t height) {
+    ATRACE_CALL();
+
+    if (width == 0 || height == 0) {
+        BQ_LOGV("setDefaultBufferSize: dimensions cannot be 0 (width=%u "
+                "height=%u)", width, height);
+        return BAD_VALUE;
+    }
+
+    BQ_LOGV("setDefaultBufferSize: width=%u height=%u", width, height);
+
+    Mutex::Autolock lock(mCore->mMutex);
+    mCore->mDefaultWidth = width;
+    mCore->mDefaultHeight = height;
+    return NO_ERROR;
+}
+
+status_t BufferQueueConsumer::setDefaultMaxBufferCount(int bufferCount) {
+    ATRACE_CALL();
+    Mutex::Autolock lock(mCore->mMutex);
+    return mCore->setDefaultMaxBufferCountLocked(bufferCount);
+}
+
+status_t BufferQueueConsumer::disableAsyncBuffer() {
+    ATRACE_CALL();
+
+    Mutex::Autolock lock(mCore->mMutex);
+
+    if (mCore->mConsumerListener != NULL) {
+        BQ_LOGE("disableAsyncBuffer: consumer already connected");
+        return INVALID_OPERATION;
+    }
+
+    BQ_LOGV("disableAsyncBuffer");
+    mCore->mUseAsyncBuffer = false;
+    return NO_ERROR;
+}
+
+status_t BufferQueueConsumer::setMaxAcquiredBufferCount(
+        int maxAcquiredBuffers) {
+    ATRACE_CALL();
+
+    if (maxAcquiredBuffers < 1 ||
+            maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) {
+        BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d",
+                maxAcquiredBuffers);
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock lock(mCore->mMutex);
+
+    if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
+        BQ_LOGE("setMaxAcquiredBufferCount: producer is already connected");
+        return INVALID_OPERATION;
+    }
+
+    BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers);
+    mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
+    return NO_ERROR;
+}
+
+void BufferQueueConsumer::setConsumerName(const String8& name) {
+    ATRACE_CALL();
+    BQ_LOGV("setConsumerName: '%s'", name.string());
+    Mutex::Autolock lock(mCore->mMutex);
+    mCore->mConsumerName = name;
+    mConsumerName = name;
+}
+
+status_t BufferQueueConsumer::setDefaultBufferFormat(uint32_t defaultFormat) {
+    ATRACE_CALL();
+    BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat);
+    Mutex::Autolock lock(mCore->mMutex);
+    mCore->mDefaultBufferFormat = defaultFormat;
+    return NO_ERROR;
+}
+
+status_t BufferQueueConsumer::setConsumerUsageBits(uint32_t usage) {
+    ATRACE_CALL();
+    BQ_LOGV("setConsumerUsageBits: %#x", usage);
+    Mutex::Autolock lock(mCore->mMutex);
+    mCore->mConsumerUsageBits = usage;
+    return NO_ERROR;
+}
+
+status_t BufferQueueConsumer::setTransformHint(uint32_t hint) {
+    ATRACE_CALL();
+    BQ_LOGV("setTransformHint: %#x", hint);
+    Mutex::Autolock lock(mCore->mMutex);
+    mCore->mTransformHint = hint;
+    return NO_ERROR;
+}
+
+void BufferQueueConsumer::dump(String8& result, const char* prefix) const {
+    mCore->dump(result, prefix);
+}
+
+} // namespace android
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
new file mode 100644
index 0000000..edce3e0
--- /dev/null
+++ b/libs/gui/BufferQueueCore.cpp
@@ -0,0 +1,209 @@
+/*
+ * 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.
+ */
+
+#define EGL_EGLEXT_PROTOTYPES
+
+#include <gui/BufferItem.h>
+#include <gui/BufferQueueCore.h>
+#include <gui/IConsumerListener.h>
+
+template <typename T>
+static inline T max(T a, T b) { return a > b ? a : b; }
+
+namespace android {
+
+static String8 getUniqueName() {
+    static volatile int32_t counter = 0;
+    return String8::format("unnamed-%d-%d", getpid(),
+            android_atomic_inc(&counter));
+}
+
+BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) :
+    mAllocator(allocator),
+    mMutex(),
+    mIsAbandoned(false),
+    mConsumerControlledByApp(false),
+    mConsumerName(getUniqueName()),
+    mConsumerListener(),
+    mConsumerUsageBits(0),
+    mConnectedApi(NO_CONNECTED_API),
+    mConnectedProducerToken(),
+    mSlots(),
+    mQueue(),
+    mOverrideMaxBufferCount(0),
+    mDequeueCondition(),
+    mUseAsyncBuffer(true),
+    mDequeueBufferCannotBlock(false),
+    mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),
+    mDefaultWidth(1),
+    mDefaultHeight(1),
+    mDefaultMaxBufferCount(2),
+    mMaxAcquiredBufferCount(1),
+    mBufferHasBeenQueued(false),
+    mFrameCounter(0),
+    mTransformHint(0) {}
+
+BufferQueueCore::~BufferQueueCore() {}
+
+void BufferQueueCore::dump(String8& result, const char* prefix) const {
+    Mutex::Autolock lock(mMutex);
+
+    String8 fifo;
+    Fifo::const_iterator current(mQueue.begin());
+    while (current != mQueue.end()) {
+        fifo.appendFormat("%02d:%p crop=[%d,%d,%d,%d], "
+                "xform=0x%02x, time=%#llx, scale=%s\n",
+                current->mSlot, current->mGraphicBuffer.get(),
+                current->mCrop.left, current->mCrop.top, current->mCrop.right,
+                current->mCrop.bottom, current->mTransform, current->mTimestamp,
+                BufferItem::scalingModeName(current->mScalingMode));
+        ++current;
+    }
+
+    result.appendFormat("%s-BufferQueue mMaxAcquiredBufferCount=%d, "
+            "mDequeueBufferCannotBlock=%d, default-size=[%dx%d], "
+            "default-format=%d, transform-hint=%02x, FIFO(%d)={%s}\n",
+            prefix, mMaxAcquiredBufferCount, mDequeueBufferCannotBlock,
+            mDefaultWidth, mDefaultHeight, mDefaultBufferFormat, mTransformHint,
+            mQueue.size(), fifo.string());
+
+    // Trim the free buffers so as to not spam the dump
+    int maxBufferCount = 0;
+    for (int s = NUM_BUFFER_SLOTS - 1; s >= 0; --s) {
+        const BufferSlot& slot(mSlots[s]);
+        if (slot.mBufferState != BufferSlot::FREE ||
+                slot.mGraphicBuffer != NULL) {
+            maxBufferCount = s + 1;
+            break;
+        }
+    }
+
+    for (int s = 0; s < maxBufferCount; ++s) {
+        const BufferSlot& slot(mSlots[s]);
+        const sp<GraphicBuffer>& buffer(slot.mGraphicBuffer);
+        result.appendFormat("%s%s[%02d:%p] state=%-8s", prefix,
+                (slot.mBufferState == BufferSlot::ACQUIRED) ? ">" : " ",
+                s, buffer.get(),
+                BufferSlot::bufferStateName(slot.mBufferState));
+
+        if (buffer != NULL) {
+            result.appendFormat(", %p [%4ux%4u:%4u,%3X]", buffer->handle,
+                    buffer->width, buffer->height, buffer->stride,
+                    buffer->format);
+        }
+
+        result.append("\n");
+    }
+}
+
+int BufferQueueCore::getMinUndequeuedBufferCountLocked(bool async) const {
+    // If dequeueBuffer is allowed to error out, we don't have to add an
+    // extra buffer.
+    if (!mUseAsyncBuffer) {
+        return mMaxAcquiredBufferCount;
+    }
+
+    if (mDequeueBufferCannotBlock || async) {
+        return mMaxAcquiredBufferCount + 1;
+    }
+
+    return mMaxAcquiredBufferCount;
+}
+
+int BufferQueueCore::getMinMaxBufferCountLocked(bool async) const {
+    return getMinUndequeuedBufferCountLocked(async) + 1;
+}
+
+int BufferQueueCore::getMaxBufferCountLocked(bool async) const {
+    int minMaxBufferCount = getMinMaxBufferCountLocked(async);
+
+    int maxBufferCount = max(mDefaultMaxBufferCount, minMaxBufferCount);
+    if (mOverrideMaxBufferCount != 0) {
+        assert(mOverrideMaxBufferCount >= minMaxBufferCount);
+        maxBufferCount = mOverrideMaxBufferCount;
+    }
+
+    // Any buffers that are dequeued by the producer or sitting in the queue
+    // waiting to be consumed need to have their slots preserved. Such buffers
+    // will temporarily keep the max buffer count up until the slots no longer
+    // need to be preserved.
+    for (int s = maxBufferCount; s < NUM_BUFFER_SLOTS; ++s) {
+        BufferSlot::BufferState state = mSlots[s].mBufferState;
+        if (state == BufferSlot::QUEUED || state == BufferSlot::DEQUEUED) {
+            maxBufferCount = s + 1;
+        }
+    }
+
+    return maxBufferCount;
+}
+
+status_t BufferQueueCore::setDefaultMaxBufferCountLocked(int count) {
+    const int minBufferCount = mUseAsyncBuffer ? 2 : 1;
+    if (count < minBufferCount || count > NUM_BUFFER_SLOTS) {
+        BQ_LOGV("setDefaultMaxBufferCount: invalid count %d, should be in "
+                "[%d, %d]", minBufferCount, NUM_BUFFER_SLOTS);
+        return BAD_VALUE;
+    }
+
+    BQ_LOGV("setDefaultMaxBufferCount: setting count to %d", count);
+    mDefaultMaxBufferCount = count;
+    mDequeueCondition.broadcast();
+
+    return NO_ERROR;
+}
+
+void BufferQueueCore::freeBufferLocked(int slot) {
+    BQ_LOGV("freeBufferLocked: slot %d", slot);
+    mSlots[slot].mGraphicBuffer.clear();
+    if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) {
+        mSlots[slot].mNeedsCleanupOnRelease = true;
+    }
+    mSlots[slot].mBufferState = BufferSlot::FREE;
+    mSlots[slot].mFrameNumber = 0;
+    mSlots[slot].mAcquireCalled = false;
+
+    // Destroy fence as BufferQueue now takes ownership
+    if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) {
+        eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence);
+        mSlots[slot].mEglFence = EGL_NO_SYNC_KHR;
+    }
+    mSlots[slot].mFence = Fence::NO_FENCE;
+}
+
+void BufferQueueCore::freeAllBuffersLocked() {
+    mBufferHasBeenQueued = false;
+    for (int s = 0; s < NUM_BUFFER_SLOTS; ++s) {
+        freeBufferLocked(s);
+    }
+}
+
+bool BufferQueueCore::stillTracking(const BufferItem* item) const {
+    const BufferSlot& slot = mSlots[item->mSlot];
+
+    BQ_LOGV("stillTracking: item { slot=%d/%llu buffer=%p } "
+            "slot { slot=%d/%llu buffer=%p }",
+            item->mSlot, item->mFrameNumber,
+            (item->mGraphicBuffer.get() ? item->mGraphicBuffer->handle : 0),
+            item->mSlot, slot.mFrameNumber,
+            (slot.mGraphicBuffer.get() ? slot.mGraphicBuffer->handle : 0));
+
+    // Compare item with its original buffer slot. We can check the slot as
+    // the buffer would not be moved to a different slot by the producer.
+    return (slot.mGraphicBuffer != NULL) &&
+           (item->mGraphicBuffer->handle == slot.mGraphicBuffer->handle);
+}
+
+} // namespace android
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
new file mode 100644
index 0000000..9d569ad
--- /dev/null
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -0,0 +1,705 @@
+/*
+ * 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.
+ */
+
+#define EGL_EGLEXT_PROTOTYPES
+
+#include <gui/BufferItem.h>
+#include <gui/BufferQueueCore.h>
+#include <gui/BufferQueueProducer.h>
+#include <gui/IConsumerListener.h>
+#include <gui/IGraphicBufferAlloc.h>
+
+#include <utils/Log.h>
+#include <utils/Trace.h>
+
+namespace android {
+
+BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core) :
+    mCore(core),
+    mSlots(core->mSlots),
+    mConsumerName() {}
+
+BufferQueueProducer::~BufferQueueProducer() {}
+
+status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
+    ATRACE_CALL();
+    BQ_LOGV("requestBuffer: slot %d", slot);
+    Mutex::Autolock lock(mCore->mMutex);
+
+    if (mCore->mIsAbandoned) {
+        BQ_LOGE("requestBuffer: BufferQueue has been abandoned");
+        return NO_INIT;
+    }
+
+    if (slot < 0 || slot >= BufferQueueCore::NUM_BUFFER_SLOTS) {
+        BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)",
+                slot, BufferQueueCore::NUM_BUFFER_SLOTS);
+        return BAD_VALUE;
+    } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
+        BQ_LOGE("requestBuffer: slot %d is not owned by the producer "
+                "(state = %d)", slot, mSlots[slot].mBufferState);
+        return BAD_VALUE;
+    }
+
+    mSlots[slot].mRequestBufferCalled = true;
+    *buf = mSlots[slot].mGraphicBuffer;
+    return NO_ERROR;
+}
+
+status_t BufferQueueProducer::setBufferCount(int bufferCount) {
+    ATRACE_CALL();
+    BQ_LOGV("setBufferCount: count = %d", bufferCount);
+
+    sp<IConsumerListener> listener;
+    { // Autolock scope
+        Mutex::Autolock lock(mCore->mMutex);
+
+        if (mCore->mIsAbandoned) {
+            BQ_LOGE("setBufferCount: BufferQueue has been abandoned");
+            return NO_INIT;
+        }
+
+        if (bufferCount > BufferQueueCore::NUM_BUFFER_SLOTS) {
+            BQ_LOGE("setBufferCount: bufferCount %d too large (max %d)",
+                    bufferCount, BufferQueueCore::NUM_BUFFER_SLOTS);
+            return BAD_VALUE;
+        }
+
+        // There must be no dequeued buffers when changing the buffer count.
+        for (int s = 0; s < BufferQueueCore::NUM_BUFFER_SLOTS; ++s) {
+            if (mSlots[s].mBufferState == BufferSlot::DEQUEUED) {
+                BQ_LOGE("setBufferCount: buffer owned by producer");
+                return -EINVAL;
+            }
+        }
+
+        if (bufferCount == 0) {
+            mCore->mOverrideMaxBufferCount = 0;
+            mCore->mDequeueCondition.broadcast();
+            return NO_ERROR;
+        }
+
+        const int minBufferSlots = mCore->getMinMaxBufferCountLocked(false);
+        if (bufferCount < minBufferSlots) {
+            BQ_LOGE("setBufferCount: requested buffer count %d is less than "
+                    "minimum %d", bufferCount, minBufferSlots);
+            return BAD_VALUE;
+        }
+
+        // Here we are guaranteed that the producer doesn't have any dequeued
+        // buffers and will release all of its buffer references. We don't
+        // clear the queue, however, so that currently queued buffers still
+        // get displayed.
+        mCore->freeAllBuffersLocked();
+        mCore->mOverrideMaxBufferCount = bufferCount;
+        mCore->mDequeueCondition.broadcast();
+        listener = mCore->mConsumerListener;
+    } // Autolock scope
+
+    // Call back without lock held
+    if (listener != NULL) {
+        listener->onBuffersReleased();
+    }
+
+    return NO_ERROR;
+}
+
+status_t BufferQueueProducer::dequeueBuffer(int *outSlot,
+        sp<android::Fence> *outFence, bool async,
+        uint32_t width, uint32_t height, uint32_t format, uint32_t usage) {
+    ATRACE_CALL();
+    { // Autolock scope
+        Mutex::Autolock lock(mCore->mMutex);
+        mConsumerName = mCore->mConsumerName;
+    } // Autolock scope
+
+    BQ_LOGV("dequeueBuffer: async=%s w=%u h=%u format=%#x, usage=%#x",
+            async ? "true" : "false", width, height, format, usage);
+
+    if ((width && !height) || (!width && height)) {
+        BQ_LOGE("dequeueBuffer: invalid size: w=%u h=%u", width, height);
+        return BAD_VALUE;
+    }
+
+    status_t returnFlags = NO_ERROR;
+    EGLDisplay eglDisplay = EGL_NO_DISPLAY;
+    EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
+
+    { // Autolock scope
+        Mutex::Autolock lock(mCore->mMutex);
+
+        if (format == 0) {
+            format = mCore->mDefaultBufferFormat;
+        }
+
+        // Enable the usage bits the consumer requested
+        usage |= mCore->mConsumerUsageBits;
+
+        int found = -1;
+        bool tryAgain = true;
+        while (tryAgain) {
+            if (mCore->mIsAbandoned) {
+                BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
+                return NO_INIT;
+            }
+
+            const int maxBufferCount = mCore->getMaxBufferCountLocked(async);
+            if (async && mCore->mOverrideMaxBufferCount) {
+                // FIXME: Some drivers are manually setting the buffer count
+                // (which they shouldn't), so we do this extra test here to
+                // handle that case. This is TEMPORARY until we get this fixed.
+                if (mCore->mOverrideMaxBufferCount < maxBufferCount) {
+                    BQ_LOGE("dequeueBuffer: async mode is invalid with "
+                            "buffer count override");
+                    return BAD_VALUE;
+                }
+            }
+
+            // Free up any buffers that are in slots beyond the max buffer count
+            for (int s = maxBufferCount; s < BufferQueueCore::NUM_BUFFER_SLOTS; ++s) {
+                assert(mSlots[s].mBufferState == BufferSlot::FREE);
+                if (mSlots[s].mGraphicBuffer != NULL) {
+                    mCore->freeBufferLocked(s);
+                    returnFlags |= RELEASE_ALL_BUFFERS;
+                }
+            }
+
+            // Look for a free buffer to give to the client
+            found = BufferQueueCore::INVALID_BUFFER_SLOT;
+            int dequeuedCount = 0;
+            int acquiredCount = 0;
+            for (int s = 0; s < maxBufferCount; ++s) {
+                switch (mSlots[s].mBufferState) {
+                    case BufferSlot::DEQUEUED:
+                        ++dequeuedCount;
+                        break;
+                    case BufferSlot::ACQUIRED:
+                        ++acquiredCount;
+                        break;
+                    case BufferSlot::FREE:
+                        // We return the oldest of the free buffers to avoid
+                        // stalling the producer if possible, since the consumer
+                        // may still have pending reads of in-flight buffers
+                        if (found == BufferQueueCore::INVALID_BUFFER_SLOT ||
+                                mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) {
+                            found = s;
+                        }
+                        break;
+                    default:
+                        break;
+                }
+            }
+
+            // Producers are not allowed to dequeue more than one buffer if they
+            // did not set a buffer count
+            if (!mCore->mOverrideMaxBufferCount && dequeuedCount) {
+                BQ_LOGE("dequeueBuffer: can't dequeue multiple buffers "
+                        "without setting the buffer count");
+                return -EINVAL;
+            }
+
+            // See whether a buffer has been queued since the last
+            // setBufferCount so we know whether to perform the min undequeued
+            // buffers check below
+            if (mCore->mBufferHasBeenQueued) {
+                // Make sure the producer is not trying to dequeue more buffers
+                // than allowed
+                const int newUndequeuedCount =
+                        maxBufferCount - (dequeuedCount + 1);
+                const int minUndequeuedCount =
+                        mCore->getMinUndequeuedBufferCountLocked(async);
+                if (newUndequeuedCount < minUndequeuedCount) {
+                    BQ_LOGE("dequeueBuffer: min undequeued buffer count (%d) "
+                            "exceeded (dequeued=%d undequeued=%d)",
+                            minUndequeuedCount, dequeuedCount,
+                            newUndequeuedCount);
+                    return -EBUSY;
+                }
+            }
+
+            // If no buffer is found, wait for a buffer to be released or for
+            // the max buffer count to change
+            tryAgain = (found == BufferQueueCore::INVALID_BUFFER_SLOT);
+            if (tryAgain) {
+                // Return an error if we're in non-blocking mode (producer and
+                // consumer are controlled by the application).
+                // However, the consumer is allowed to briefly acquire an extra
+                // buffer (which could cause us to have to wait here), which is
+                // okay, since it is only used to implement an atomic acquire +
+                // release (e.g., in GLConsumer::updateTexImage())
+                if (mCore->mDequeueBufferCannotBlock &&
+                        (acquiredCount <= mCore->mMaxAcquiredBufferCount)) {
+                    return WOULD_BLOCK;
+                }
+                mCore->mDequeueCondition.wait(mCore->mMutex);
+            }
+        } // while (tryAgain)
+
+        // This should not happen
+        if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
+            BQ_LOGE("dequeueBuffer: no available buffer slots");
+            return -EBUSY;
+        }
+
+        *outSlot = found;
+        ATRACE_BUFFER_INDEX(found);
+
+        const bool useDefaultSize = !width && !height;
+        if (useDefaultSize) {
+            width = mCore->mDefaultWidth;
+            height = mCore->mDefaultHeight;
+        }
+
+        mSlots[found].mBufferState = BufferSlot::DEQUEUED;
+
+        const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
+        if ((buffer == NULL) ||
+                (static_cast<uint32_t>(buffer->width) != width) ||
+                (static_cast<uint32_t>(buffer->height) != height) ||
+                (static_cast<uint32_t>(buffer->format) != format) ||
+                ((static_cast<uint32_t>(buffer->usage) & usage) != usage))
+        {
+            mSlots[found].mAcquireCalled = false;
+            mSlots[found].mGraphicBuffer = NULL;
+            mSlots[found].mRequestBufferCalled = false;
+            mSlots[found].mEglDisplay = EGL_NO_DISPLAY;
+            mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
+            mSlots[found].mFence = Fence::NO_FENCE;
+
+            returnFlags |= BUFFER_NEEDS_REALLOCATION;
+        }
+
+        if (CC_UNLIKELY(mSlots[found].mFence == NULL)) {
+            BQ_LOGE("dequeueBuffer: about to return a NULL fence - "
+                    "slot=%d w=%d h=%d format=%u",
+                    found, buffer->width, buffer->height, buffer->format);
+        }
+
+        eglDisplay = mSlots[found].mEglDisplay;
+        eglFence = mSlots[found].mEglFence;
+        *outFence = mSlots[found].mFence;
+        mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
+        mSlots[found].mFence = Fence::NO_FENCE;
+    } // Autolock scope
+
+    if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
+        status_t error;
+        sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
+                    width, height, format, usage, &error));
+        if (graphicBuffer == NULL) {
+            BQ_LOGE("dequeueBuffer: createGraphicBuffer failed");
+            return error;
+        }
+
+        { // Autolock scope
+            Mutex::Autolock lock(mCore->mMutex);
+
+            if (mCore->mIsAbandoned) {
+                BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
+                return NO_INIT;
+            }
+
+            mSlots[*outSlot].mFrameNumber = ~0;
+            mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
+        } // Autolock scope
+    }
+
+    if (eglFence != EGL_NO_SYNC_KHR) {
+        EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0,
+                1000000000);
+        // If something goes wrong, log the error, but return the buffer without
+        // synchronizing access to it. It's too late at this point to abort the
+        // dequeue operation.
+        if (result == EGL_FALSE) {
+            BQ_LOGE("dequeueBuffer: error %#x waiting for fence",
+                    eglGetError());
+        } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
+            BQ_LOGE("dequeueBuffer: timeout waiting for fence");
+        }
+        eglDestroySyncKHR(eglDisplay, eglFence);
+    }
+
+    BQ_LOGV("dequeueBuffer: returning slot=%d/%llu buf=%p flags=%#x", *outSlot,
+            mSlots[*outSlot].mFrameNumber,
+            mSlots[*outSlot].mGraphicBuffer->handle, returnFlags);
+
+    return returnFlags;
+}
+
+status_t BufferQueueProducer::queueBuffer(int slot,
+        const QueueBufferInput &input, QueueBufferOutput *output) {
+    ATRACE_CALL();
+    ATRACE_BUFFER_INDEX(slot);
+
+    int64_t timestamp;
+    bool isAutoTimestamp;
+    Rect crop;
+    int scalingMode;
+    uint32_t transform;
+    bool async;
+    sp<Fence> fence;
+    input.deflate(&timestamp, &isAutoTimestamp, &crop, &scalingMode, &transform,
+            &async, &fence);
+
+    if (fence == NULL) {
+        BQ_LOGE("queueBuffer: fence is NULL");
+        return BAD_VALUE;
+    }
+
+    switch (scalingMode) {
+        case NATIVE_WINDOW_SCALING_MODE_FREEZE:
+        case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
+        case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
+        case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
+            break;
+        default:
+            BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode);
+            return -EINVAL;
+    }
+
+    sp<IConsumerListener> listener;
+    { // Autolock scope
+        Mutex::Autolock lock(mCore->mMutex);
+
+        if (mCore->mIsAbandoned) {
+            BQ_LOGE("queueBuffer: BufferQueue has been abandoned");
+            return NO_INIT;
+        }
+
+        const int maxBufferCount = mCore->getMaxBufferCountLocked(async);
+        if (async && mCore->mOverrideMaxBufferCount) {
+            // FIXME: Some drivers are manually setting the buffer count
+            // (which they shouldn't), so we do this extra test here to
+            // handle that case. This is TEMPORARY until we get this fixed.
+            if (mCore->mOverrideMaxBufferCount < maxBufferCount) {
+                BQ_LOGE("queueBuffer: async mode is invalid with "
+                        "buffer count override");
+                return BAD_VALUE;
+            }
+        }
+
+        if (slot < 0 || slot >= maxBufferCount) {
+            BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)",
+                    slot, maxBufferCount);
+            return -EINVAL;
+        } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
+            BQ_LOGE("queueBuffer: slot %d is not owned by the producer "
+                    "(state = %d)", slot, mSlots[slot].mBufferState);
+            return -EINVAL;
+        } else if (!mSlots[slot].mRequestBufferCalled) {
+            BQ_LOGE("queueBuffer: slot %d was queued without requesting "
+                    "a buffer", slot);
+            return -EINVAL;
+        }
+
+        BQ_LOGV("queueBuffer: slot=%d/%llu time=%llu crop=[%d,%d,%d,%d] "
+                "transform=%#x scale=%s",
+                slot, mCore->mFrameCounter + 1, timestamp,
+                crop.left, crop.top, crop.right, crop.bottom,
+                transform, BufferItem::scalingModeName(scalingMode));
+
+        const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
+        Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
+        Rect croppedRect;
+        crop.intersect(bufferRect, &croppedRect);
+        if (croppedRect != crop) {
+            BQ_LOGE("queueBuffer: crop rect is not contained within the "
+                    "buffer in slot %d", slot);
+            return -EINVAL;
+        }
+
+        mSlots[slot].mFence = fence;
+        mSlots[slot].mBufferState = BufferSlot::QUEUED;
+        ++mCore->mFrameCounter;
+        mSlots[slot].mFrameNumber = mCore->mFrameCounter;
+
+        BufferItem item;
+        item.mAcquireCalled = mSlots[slot].mAcquireCalled;
+        item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
+        item.mCrop = crop;
+        item.mTransform = transform & ~NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
+        item.mTransformToDisplayInverse =
+                bool(transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
+        item.mScalingMode = scalingMode;
+        item.mTimestamp = timestamp;
+        item.mIsAutoTimestamp = isAutoTimestamp;
+        item.mFrameNumber = mCore->mFrameCounter;
+        item.mSlot = slot;
+        item.mFence = fence;
+        item.mIsDroppable = mCore->mDequeueBufferCannotBlock || async;
+
+        if (mCore->mQueue.empty()) {
+            // When the queue is empty, we can ignore mDequeueBufferCannotBlock
+            // and simply queue this buffer
+            mCore->mQueue.push_back(item);
+            listener = mCore->mConsumerListener;
+        } else {
+            // When the queue is not empty, we need to look at the front buffer
+            // state to see if we need to replace it
+            BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
+            if (front->mIsDroppable) {
+                // If the front queued buffer is still being tracked, we first
+                // mark it as freed
+                if (mCore->stillTracking(front)) {
+                    mSlots[front->mSlot].mBufferState = BufferSlot::FREE;
+                    // Reset the frame number of the freed buffer so that it is
+                    // the first in line to be dequeued again
+                    mSlots[front->mSlot].mFrameNumber = 0;
+                }
+                // Overwrite the droppable buffer with the incoming one
+                *front = item;
+            } else {
+                mCore->mQueue.push_back(item);
+                listener = mCore->mConsumerListener;
+            }
+        }
+
+        mCore->mBufferHasBeenQueued = true;
+        mCore->mDequeueCondition.broadcast();
+
+        output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
+                mCore->mTransformHint, mCore->mQueue.size());
+
+        ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
+    } // Autolock scope
+
+    // Call back without lock held
+    if (listener != NULL) {
+        listener->onFrameAvailable();
+    }
+
+    return NO_ERROR;
+}
+
+void BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
+    ATRACE_CALL();
+    BQ_LOGV("cancelBuffer: slot %d", slot);
+    Mutex::Autolock lock(mCore->mMutex);
+
+    if (mCore->mIsAbandoned) {
+        BQ_LOGE("cancelBuffer: BufferQueue has been abandoned");
+        return;
+    }
+
+    if (slot < 0 || slot >= BufferQueueCore::NUM_BUFFER_SLOTS) {
+        BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)",
+                slot, BufferQueueCore::NUM_BUFFER_SLOTS);
+        return;
+    } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
+        BQ_LOGE("cancelBuffer: slot %d is not owned by the producer "
+                "(state = %d)", slot, mSlots[slot].mBufferState);
+        return;
+    } else if (fence == NULL) {
+        BQ_LOGE("cancelBuffer: fence is NULL");
+        return;
+    }
+
+    mSlots[slot].mBufferState = BufferSlot::FREE;
+    mSlots[slot].mFrameNumber = 0;
+    mSlots[slot].mFence = fence;
+    mCore->mDequeueCondition.broadcast();
+}
+
+int BufferQueueProducer::query(int what, int *outValue) {
+    ATRACE_CALL();
+    Mutex::Autolock lock(mCore->mMutex);
+
+    if (outValue == NULL) {
+        BQ_LOGE("query: outValue was NULL");
+        return BAD_VALUE;
+    }
+
+    if (mCore->mIsAbandoned) {
+        BQ_LOGE("query: BufferQueue has been abandoned");
+        return NO_INIT;
+    }
+
+    int value;
+    switch (what) {
+        case NATIVE_WINDOW_WIDTH:
+            value = mCore->mDefaultWidth;
+            break;
+        case NATIVE_WINDOW_HEIGHT:
+            value = mCore->mDefaultHeight;
+            break;
+        case NATIVE_WINDOW_FORMAT:
+            value = mCore->mDefaultBufferFormat;
+            break;
+        case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
+            value = mCore->getMinUndequeuedBufferCountLocked(false);
+            break;
+        case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
+            value = (mCore->mQueue.size() > 1);
+            break;
+        case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
+            value = mCore->mConsumerUsageBits;
+            break;
+        default:
+            return BAD_VALUE;
+    }
+
+    BQ_LOGV("query: %d? %d", what, value);
+    *outValue = value;
+    return NO_ERROR;
+}
+
+status_t BufferQueueProducer::connect(const sp<android::IBinder> &token,
+        int api, bool producerControlledByApp, QueueBufferOutput *output) {
+    ATRACE_CALL();
+    Mutex::Autolock lock(mCore->mMutex);
+    mConsumerName = mCore->mConsumerName;
+    BQ_LOGV("connect(P): api=%d producerControlledByApp=%s", api,
+            producerControlledByApp ? "true" : "false");
+
+    // If we disconnect and reconnect quickly, we can be in a state where our
+    // slots are empty but we have many buffers in the queue. This can cause us
+    // to run out of memory if we outrun the consumer. Wait here if it looks
+    // like we have too many buffers queued up.
+    while (true) {
+        if (mCore->mIsAbandoned) {
+            BQ_LOGE("connect(P): BufferQueue has been abandoned");
+            return NO_INIT;
+        }
+
+        if (mCore->mConsumerListener == NULL) {
+            BQ_LOGE("connect(P): BufferQueue has no consumer");
+            return NO_INIT;
+        }
+
+        if (output == NULL) {
+            BQ_LOGE("connect(P): output was NULL");
+            return BAD_VALUE;
+        }
+
+        if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
+            BQ_LOGE("connect(P): already connected (cur=%d req=%d)",
+                    mCore->mConnectedApi, api);
+            return BAD_VALUE;
+        }
+
+        size_t maxBufferCount = mCore->getMaxBufferCountLocked(false);
+        if (mCore->mQueue.size() <= maxBufferCount) {
+            // The queue size seems small enough to proceed
+            // TODO: Make this bound tighter?
+            break;
+        }
+
+        BQ_LOGV("connect(P): queue size is %d, waiting", mCore->mQueue.size());
+        mCore->mDequeueCondition.wait(mCore->mMutex);
+    }
+
+    int status = NO_ERROR;
+    switch (api) {
+        case NATIVE_WINDOW_API_EGL:
+        case NATIVE_WINDOW_API_CPU:
+        case NATIVE_WINDOW_API_MEDIA:
+        case NATIVE_WINDOW_API_CAMERA:
+            mCore->mConnectedApi = api;
+            output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
+                    mCore->mTransformHint, mCore->mQueue.size());
+
+            // Set up a death notification so that we can disconnect
+            // automatically if the remote producer dies
+            if (token != NULL && token->remoteBinder() != NULL) {
+                status = token->linkToDeath(
+                        static_cast<IBinder::DeathRecipient*>(this));
+                if (status == NO_ERROR) {
+                    mCore->mConnectedProducerToken = token;
+                } else {
+                    BQ_LOGE("connect(P): linkToDeath failed: %s (%d)",
+                            strerror(-status), status);
+                }
+            }
+            break;
+        default:
+            BQ_LOGE("connect(P): unknown API %d", api);
+            status = BAD_VALUE;
+            break;
+    }
+
+    mCore->mBufferHasBeenQueued = false;
+    mCore->mDequeueBufferCannotBlock =
+            mCore->mConsumerControlledByApp && producerControlledByApp;
+
+    return status;
+}
+
+status_t BufferQueueProducer::disconnect(int api) {
+    ATRACE_CALL();
+    BQ_LOGV("disconnect(P): api %d", api);
+
+    int status = NO_ERROR;
+    sp<IConsumerListener> listener;
+    { // Autolock scope
+        Mutex::Autolock lock(mCore->mMutex);
+
+        if (mCore->mIsAbandoned) {
+            // It's not really an error to disconnect after the surface has
+            // been abandoned; it should just be a no-op.
+            return NO_ERROR;
+        }
+
+        switch (api) {
+            case NATIVE_WINDOW_API_EGL:
+            case NATIVE_WINDOW_API_CPU:
+            case NATIVE_WINDOW_API_MEDIA:
+            case NATIVE_WINDOW_API_CAMERA:
+                if (mCore->mConnectedApi == api) {
+                    mCore->freeAllBuffersLocked();
+
+                    // Remove our death notification callback if we have one
+                    sp<IBinder> token = mCore->mConnectedProducerToken;
+                    if (token != NULL) {
+                        // This can fail if we're here because of the death
+                        // notification, but we just ignore it
+                        token->unlinkToDeath(
+                                static_cast<IBinder::DeathRecipient*>(this));
+                    }
+                    mCore->mConnectedProducerToken = NULL;
+                    mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
+                    mCore->mDequeueCondition.broadcast();
+                    listener = mCore->mConsumerListener;
+                } else {
+                    BQ_LOGE("disconnect(P): connected to another API "
+                            "(cur=%d req=%d)", mCore->mConnectedApi, api);
+                    status = -EINVAL;
+                }
+                break;
+            default:
+                BQ_LOGE("disconnect(P): unknown API %d", api);
+                status = -EINVAL;
+                break;
+        }
+    } // Autolock scope
+
+    // Call back without lock held
+    if (listener != NULL) {
+        listener->onBuffersReleased();
+    }
+
+    return status;
+}
+
+void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) {
+    // If we're here, it means that a producer we were connected to died.
+    // We're guaranteed that we are still connected to it because we remove
+    // this callback upon disconnect. It's therefore safe to read mConnectedApi
+    // without synchronization here.
+    int api = mCore->mConnectedApi;
+    disconnect(api);
+}
+
+} // namespace android
diff --git a/libs/gui/BufferSlot.cpp b/libs/gui/BufferSlot.cpp
new file mode 100644
index 0000000..6b5d77a
--- /dev/null
+++ b/libs/gui/BufferSlot.cpp
@@ -0,0 +1,15 @@
+#include <gui/BufferSlot.h>
+
+namespace android {
+
+const char* BufferSlot::bufferStateName(BufferState state) {
+    switch (state) {
+        case BufferSlot::DEQUEUED: return "DEQUEUED";
+        case BufferSlot::QUEUED: return "QUEUED";
+        case BufferSlot::FREE: return "FREE";
+        case BufferSlot::ACQUIRED: return "ACQUIRED";
+        default: return "Unknown";
+    }
+}
+
+} // namespace android
