summaryrefslogtreecommitdiffstats
path: root/widget/gonk/nativewindow/GonkBufferQueueLL
diff options
context:
space:
mode:
Diffstat (limited to 'widget/gonk/nativewindow/GonkBufferQueueLL')
-rw-r--r--widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferItem.cpp193
-rw-r--r--widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferItem.h101
-rw-r--r--widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueConsumer.cpp559
-rw-r--r--widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueConsumer.h173
-rw-r--r--widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueCore.cpp243
-rw-r--r--widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueCore.h251
-rw-r--r--widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueDefs.h36
-rw-r--r--widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueLL.cpp96
-rw-r--r--widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueLL.h94
-rw-r--r--widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.cpp886
-rw-r--r--widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.h216
-rw-r--r--widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferSlot.cpp32
-rw-r--r--widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferSlot.h132
13 files changed, 0 insertions, 3012 deletions
diff --git a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferItem.cpp b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferItem.cpp
deleted file mode 100644
index 7df72bf68..000000000
--- a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferItem.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- * Copyright (C) 2014 Mozilla Foundation
- *
- * 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 "GonkBufferItem.h"
-
-#include <ui/Fence.h>
-#include <ui/GraphicBuffer.h>
-
-#include <system/window.h>
-
-namespace android {
-
-GonkBufferItem::GonkBufferItem() :
- 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();
-}
-
-GonkBufferItem::operator IGonkGraphicBufferConsumer::BufferItem() const {
- IGonkGraphicBufferConsumer::BufferItem bufferItem;
- bufferItem.mGraphicBuffer = mGraphicBuffer;
- bufferItem.mFence = mFence;
- bufferItem.mCrop = mCrop;
- 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;
- return bufferItem;
-}
-
-size_t GonkBufferItem::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 GonkBufferItem::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 GonkBufferItem::getFdCount() const {
- size_t c = 0;
- if (mGraphicBuffer != 0) {
- c += mGraphicBuffer->getFdCount();
- }
- if (mFence != 0) {
- c += mFence->getFdCount();
- }
- return c;
-}
-
-status_t GonkBufferItem::flatten(
- void*& buffer, size_t& size, int*& fds, size_t& count) const {
-
- // make sure we have enough space
- if (count < GonkBufferItem::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 GonkBufferItem::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* GonkBufferItem::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/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferItem.h b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferItem.h
deleted file mode 100644
index b2d6d3068..000000000
--- a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferItem.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- * Copyright (C) 2014 Mozilla Foundation
- *
- * 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 NATIVEWINDOW_GONKBUFFERITEM_LL_H
-#define NATIVEWINDOW_GONKBUFFERITEM_LL_H
-
-#include "IGonkGraphicBufferConsumerLL.h"
-
-#include <ui/Rect.h>
-
-#include <utils/Flattenable.h>
-#include <utils/StrongPointer.h>
-
-namespace android {
-
-class Fence;
-class GraphicBuffer;
-
-class GonkBufferItem : public Flattenable<GonkBufferItem> {
- friend class Flattenable<GonkBufferItem>;
- size_t getPodSize() const;
- size_t getFlattenedSize() const;
- size_t getFdCount() const;
- status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;
- status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);
-
- public:
- // The default value of mBuf, used to indicate this doesn't correspond to a slot.
- enum { INVALID_BUFFER_SLOT = -1 };
- GonkBufferItem();
- operator IGonkGraphicBufferConsumer::BufferItem() const;
-
- static const char* scalingModeName(uint32_t scalingMode);
-
- // mGraphicBuffer points to the buffer allocated for this slot, or is NULL
- // if the buffer in this slot has been acquired in the past (see
- // BufferSlot.mAcquireCalled).
- sp<GraphicBuffer> mGraphicBuffer;
-
- // mFence is a fence that will signal when the buffer is idle.
- sp<Fence> mFence;
-
- // mCrop is the current crop rectangle for this buffer slot.
- Rect mCrop;
-
- // mTransform is the current transform flags for this buffer slot.
- // refer to NATIVE_WINDOW_TRANSFORM_* in <window.h>
- uint32_t mTransform;
-
- // mScalingMode is the current scaling mode for this buffer slot.
- // refer to NATIVE_WINDOW_SCALING_* in <window.h>
- uint32_t mScalingMode;
-
- // mTimestamp is the current timestamp for this buffer slot. This gets
- // to set by queueBuffer each time this slot is queued. This value
- // is guaranteed to be monotonically increasing for each newly
- // acquired buffer.
- int64_t mTimestamp;
-
- // mIsAutoTimestamp indicates whether mTimestamp was generated
- // automatically when the buffer was queued.
- bool mIsAutoTimestamp;
-
- // mFrameNumber is the number of the queued frame for this slot.
- uint64_t mFrameNumber;
-
- // mSlot is the slot index of this buffer (default INVALID_BUFFER_SLOT).
- int mSlot;
-
- // mIsDroppable whether this buffer was queued with the
- // property that it can be replaced by a new buffer for the purpose of
- // making sure dequeueBuffer() won't block.
- // i.e.: was the BufferQueue in "mDequeueBufferCannotBlock" when this buffer
- // was queued.
- bool mIsDroppable;
-
- // Indicates whether this buffer has been seen by a consumer yet
- bool mAcquireCalled;
-
- // Indicates this buffer must be transformed by the inverse transform of the screen
- // it is displayed onto. This is applied after mTransform.
- bool mTransformToDisplayInverse;
-};
-
-} // namespace android
-
-#endif
diff --git a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueConsumer.cpp b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueConsumer.cpp
deleted file mode 100644
index 1d7eb2702..000000000
--- a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueConsumer.cpp
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- * Copyright (C) 2014 Mozilla Foundation
- *
- * 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 <inttypes.h>
-
-#define LOG_TAG "GonkBufferQueueConsumer"
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-//#define LOG_NDEBUG 0
-
-#include "GonkBufferItem.h"
-#include "GonkBufferQueueConsumer.h"
-#include "GonkBufferQueueCore.h"
-#include <gui/IConsumerListener.h>
-#include <gui/IProducerListener.h>
-
-namespace android {
-
-GonkBufferQueueConsumer::GonkBufferQueueConsumer(const sp<GonkBufferQueueCore>& core) :
- mCore(core),
- mSlots(core->mSlots),
- mConsumerName() {}
-
-GonkBufferQueueConsumer::~GonkBufferQueueConsumer() {}
-
-status_t GonkBufferQueueConsumer::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 < GonkBufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
- if (mSlots[s].mBufferState == GonkBufferSlot::ACQUIRED) {
- ++numAcquiredBuffers;
- }
- }
- if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
- ALOGE("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;
- }
-
- GonkBufferQueueCore::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.
- ALOGV("acquireBuffer: nodrop desire=%" PRId64 " expect=%"
- PRId64 " (%" PRId64 ") now=%" PRId64,
- desiredPresent, expectedPresent,
- desiredPresent - expectedPresent,
- systemTime(CLOCK_MONOTONIC));
- break;
- }
-
- ALOGV("acquireBuffer: drop desire=%" PRId64 " expect=%" PRId64
- " size=%zu",
- 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 = GonkBufferSlot::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) {
- ALOGV("acquireBuffer: defer desire=%" PRId64 " expect=%" PRId64
- " (%" PRId64 ") now=%" PRId64,
- desiredPresent, expectedPresent,
- desiredPresent - expectedPresent,
- systemTime(CLOCK_MONOTONIC));
- return PRESENT_LATER;
- }
-
- ALOGV("acquireBuffer: accept desire=%" PRId64 " expect=%" PRId64 " "
- "(%" PRId64 ") now=%" PRId64, desiredPresent, expectedPresent,
- desiredPresent - expectedPresent,
- systemTime(CLOCK_MONOTONIC));
- }
-
- int slot = front->mSlot;
- //*outBuffer = *front;
- outBuffer->mGraphicBuffer = mSlots[slot].mGraphicBuffer;
- outBuffer->mFrameNumber = mSlots[slot].mFrameNumber;
- outBuffer->mBuf = slot;
- outBuffer->mFence = mSlots[slot].mFence;
-
- ATRACE_BUFFER_INDEX(slot);
-
- ALOGV("acquireBuffer: acquiring { slot=%d/%" PRIu64 " 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 = GonkBufferSlot::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);
-
- // We might have freed a slot while dropping old buffers, or the producer
- // may be blocked waiting for the number of buffers in the queue to
- // decrease.
- mCore->mDequeueCondition.broadcast();
-
- return NO_ERROR;
-}
-
-status_t GonkBufferQueueConsumer::detachBuffer(int slot) {
- ATRACE_CALL();
- ATRACE_BUFFER_INDEX(slot);
- ALOGV("detachBuffer(C): slot %d", slot);
- Mutex::Autolock lock(mCore->mMutex);
-
- if (mCore->mIsAbandoned) {
- ALOGE("detachBuffer(C): GonkBufferQueue has been abandoned");
- return NO_INIT;
- }
-
- if (slot < 0 || slot >= GonkBufferQueueDefs::NUM_BUFFER_SLOTS) {
- ALOGE("detachBuffer(C): slot index %d out of range [0, %d)",
- slot, GonkBufferQueueDefs::NUM_BUFFER_SLOTS);
- return BAD_VALUE;
- } else if (mSlots[slot].mBufferState != GonkBufferSlot::ACQUIRED) {
- ALOGE("detachBuffer(C): slot %d is not owned by the consumer "
- "(state = %d)", slot, mSlots[slot].mBufferState);
- return BAD_VALUE;
- }
-
- mCore->freeBufferLocked(slot);
- mCore->mDequeueCondition.broadcast();
-
- return NO_ERROR;
-}
-
-status_t GonkBufferQueueConsumer::attachBuffer(int* outSlot,
- const sp<android::GraphicBuffer>& buffer) {
- ATRACE_CALL();
-
- if (outSlot == NULL) {
- ALOGE("attachBuffer(P): outSlot must not be NULL");
- return BAD_VALUE;
- } else if (buffer == NULL) {
- ALOGE("attachBuffer(P): cannot attach NULL buffer");
- return BAD_VALUE;
- }
-
- Mutex::Autolock lock(mCore->mMutex);
-
- // Make sure we don't have too many acquired buffers and find a free slot
- // to put the buffer into (the oldest if there are multiple).
- int numAcquiredBuffers = 0;
- int found = GonkBufferQueueCore::INVALID_BUFFER_SLOT;
- for (int s = 0; s < GonkBufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
- if (mSlots[s].mBufferState == GonkBufferSlot::ACQUIRED) {
- ++numAcquiredBuffers;
- } else if (mSlots[s].mBufferState == GonkBufferSlot::FREE) {
- if (found == GonkBufferQueueCore::INVALID_BUFFER_SLOT ||
- mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) {
- found = s;
- }
- }
- }
-
- if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
- ALOGE("attachBuffer(P): max acquired buffer count reached: %d "
- "(max %d)", numAcquiredBuffers,
- mCore->mMaxAcquiredBufferCount);
- return INVALID_OPERATION;
- }
- if (found == GonkBufferQueueCore::INVALID_BUFFER_SLOT) {
- ALOGE("attachBuffer(P): could not find free buffer slot");
- return NO_MEMORY;
- }
-
- *outSlot = found;
- ATRACE_BUFFER_INDEX(*outSlot);
- ALOGV("attachBuffer(C): returning slot %d", *outSlot);
-
- mSlots[*outSlot].mGraphicBuffer = buffer;
- mSlots[*outSlot].mBufferState = GonkBufferSlot::ACQUIRED;
- mSlots[*outSlot].mAttachedByConsumer = true;
- mSlots[*outSlot].mNeedsCleanupOnRelease = false;
- mSlots[*outSlot].mFence = Fence::NO_FENCE;
- mSlots[*outSlot].mFrameNumber = 0;
-
- // mAcquireCalled tells GonkBufferQueue that it doesn't need to send a valid
- // GraphicBuffer pointer on the next acquireBuffer call, which decreases
- // Binder traffic by not un/flattening the GraphicBuffer. However, it
- // requires that the consumer maintain a cached copy of the slot <--> buffer
- // mappings, which is why the consumer doesn't need the valid pointer on
- // acquire.
- //
- // The StreamSplitter is one of the primary users of the attach/detach
- // logic, and while it is running, all buffers it acquires are immediately
- // detached, and all buffers it eventually releases are ones that were
- // attached (as opposed to having been obtained from acquireBuffer), so it
- // doesn't make sense to maintain the slot/buffer mappings, which would
- // become invalid for every buffer during detach/attach. By setting this to
- // false, the valid GraphicBuffer pointer will always be sent with acquire
- // for attached buffers.
- mSlots[*outSlot].mAcquireCalled = false;
-
- return NO_ERROR;
-}
-
-status_t GonkBufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
- const sp<Fence>& releaseFence) {
- ATRACE_CALL();
-
- if (slot < 0 || slot >= GonkBufferQueueDefs::NUM_BUFFER_SLOTS ||
- releaseFence == NULL) {
- return BAD_VALUE;
- }
-
- sp<IProducerListener> listener;
- { // Autolock scope
- 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
- GonkBufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
- while (current != mCore->mQueue.end()) {
- if (current->mSlot == slot) {
- ALOGE("releaseBuffer: buffer slot %d pending release is "
- "currently queued", slot);
- return BAD_VALUE;
- }
- ++current;
- }
-
- if (mSlots[slot].mBufferState == GonkBufferSlot::ACQUIRED) {
- mSlots[slot].mFence = releaseFence;
- mSlots[slot].mBufferState = GonkBufferSlot::FREE;
- listener = mCore->mConnectedProducerListener;
- ALOGV("releaseBuffer: releasing slot %d", slot);
- } else if (mSlots[slot].mNeedsCleanupOnRelease) {
- ALOGV("releaseBuffer: releasing a stale buffer slot %d "
- "(state = %d)", slot, mSlots[slot].mBufferState);
- mSlots[slot].mNeedsCleanupOnRelease = false;
- return STALE_BUFFER_SLOT;
- } else {
- ALOGV("releaseBuffer: attempted to release buffer slot %d "
- "but its state was %d", slot, mSlots[slot].mBufferState);
- return BAD_VALUE;
- }
-
- mCore->mDequeueCondition.broadcast();
- } // Autolock scope
-
- // Call back without lock held
- if (listener != NULL) {
- listener->onBufferReleased();
- }
-
- return NO_ERROR;
-}
-
-status_t GonkBufferQueueConsumer::connect(
- const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
- ATRACE_CALL();
-
- if (consumerListener == NULL) {
- ALOGE("connect(C): consumerListener may not be NULL");
- return BAD_VALUE;
- }
-
- ALOGV("connect(C): controlledByApp=%s",
- controlledByApp ? "true" : "false");
-
- Mutex::Autolock lock(mCore->mMutex);
-
- if (mCore->mIsAbandoned) {
- ALOGE("connect(C): GonkBufferQueue has been abandoned");
- return NO_INIT;
- }
-
- mCore->mConsumerListener = consumerListener;
- mCore->mConsumerControlledByApp = controlledByApp;
-
- return NO_ERROR;
-}
-
-status_t GonkBufferQueueConsumer::disconnect() {
- ATRACE_CALL();
-
- ALOGV("disconnect(C)");
-
- Mutex::Autolock lock(mCore->mMutex);
-
- if (mCore->mConsumerListener == NULL) {
- ALOGE("disconnect(C): no consumer is connected");
- return BAD_VALUE;
- }
-
- mCore->mIsAbandoned = true;
- mCore->mConsumerListener = NULL;
- mCore->mQueue.clear();
- mCore->freeAllBuffersLocked();
- mCore->mDequeueCondition.broadcast();
- return NO_ERROR;
-}
-
-status_t GonkBufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) {
- ATRACE_CALL();
-
- if (outSlotMask == NULL) {
- ALOGE("getReleasedBuffers: outSlotMask may not be NULL");
- return BAD_VALUE;
- }
-
- Mutex::Autolock lock(mCore->mMutex);
-
- if (mCore->mIsAbandoned) {
- ALOGE("getReleasedBuffers: GonkBufferQueue has been abandoned");
- return NO_INIT;
- }
-
- uint64_t mask = 0;
- for (int s = 0; s < GonkBufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
- if (!mSlots[s].mAcquireCalled) {
- mask |= (1ULL << 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
- GonkBufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
- while (current != mCore->mQueue.end()) {
- if (current->mAcquireCalled) {
- mask &= ~(1ULL << current->mSlot);
- }
- ++current;
- }
-
- ALOGV("getReleasedBuffers: returning mask %#" PRIx64, mask);
- *outSlotMask = mask;
- return NO_ERROR;
-}
-
-status_t GonkBufferQueueConsumer::setDefaultBufferSize(uint32_t width,
- uint32_t height) {
- ATRACE_CALL();
-
- if (width == 0 || height == 0) {
- ALOGV("setDefaultBufferSize: dimensions cannot be 0 (width=%u "
- "height=%u)", width, height);
- return BAD_VALUE;
- }
-
- ALOGV("setDefaultBufferSize: width=%u height=%u", width, height);
-
- Mutex::Autolock lock(mCore->mMutex);
- mCore->mDefaultWidth = width;
- mCore->mDefaultHeight = height;
- return NO_ERROR;
-}
-
-status_t GonkBufferQueueConsumer::setDefaultMaxBufferCount(int bufferCount) {
- ATRACE_CALL();
- Mutex::Autolock lock(mCore->mMutex);
- return mCore->setDefaultMaxBufferCountLocked(bufferCount);
-}
-
-status_t GonkBufferQueueConsumer::disableAsyncBuffer() {
- ATRACE_CALL();
-
- Mutex::Autolock lock(mCore->mMutex);
-
- if (mCore->mConsumerListener != NULL) {
- ALOGE("disableAsyncBuffer: consumer already connected");
- return INVALID_OPERATION;
- }
-
- ALOGV("disableAsyncBuffer");
- mCore->mUseAsyncBuffer = false;
- return NO_ERROR;
-}
-
-status_t GonkBufferQueueConsumer::setMaxAcquiredBufferCount(
- int maxAcquiredBuffers) {
- ATRACE_CALL();
-
- if (maxAcquiredBuffers < 1 ||
- maxAcquiredBuffers > GonkBufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) {
- ALOGE("setMaxAcquiredBufferCount: invalid count %d",
- maxAcquiredBuffers);
- return BAD_VALUE;
- }
-
- Mutex::Autolock lock(mCore->mMutex);
-
- if (mCore->mConnectedApi != GonkBufferQueueCore::NO_CONNECTED_API) {
- ALOGE("setMaxAcquiredBufferCount: producer is already connected");
- return INVALID_OPERATION;
- }
-
- ALOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers);
- mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
- return NO_ERROR;
-}
-
-void GonkBufferQueueConsumer::setConsumerName(const String8& name) {
- ATRACE_CALL();
- ALOGV("setConsumerName: '%s'", name.string());
- Mutex::Autolock lock(mCore->mMutex);
- mCore->mConsumerName = name;
- mConsumerName = name;
-}
-
-status_t GonkBufferQueueConsumer::setDefaultBufferFormat(uint32_t defaultFormat) {
- ATRACE_CALL();
- ALOGV("setDefaultBufferFormat: %u", defaultFormat);
- Mutex::Autolock lock(mCore->mMutex);
- mCore->mDefaultBufferFormat = defaultFormat;
- return NO_ERROR;
-}
-
-status_t GonkBufferQueueConsumer::setConsumerUsageBits(uint32_t usage) {
- ATRACE_CALL();
- ALOGV("setConsumerUsageBits: %#x", usage);
- Mutex::Autolock lock(mCore->mMutex);
- mCore->mConsumerUsageBits = usage;
- return NO_ERROR;
-}
-
-status_t GonkBufferQueueConsumer::setTransformHint(uint32_t hint) {
- ATRACE_CALL();
- ALOGV("setTransformHint: %#x", hint);
- Mutex::Autolock lock(mCore->mMutex);
- mCore->mTransformHint = hint;
- return NO_ERROR;
-}
-
-sp<NativeHandle> GonkBufferQueueConsumer::getSidebandStream() const {
- return mCore->mSidebandStream;
-}
-
-void GonkBufferQueueConsumer::dumpToString(String8& result, const char* prefix) const {
- mCore->dump(result, prefix);
-}
-
-already_AddRefed<GonkBufferSlot::TextureClient>
-GonkBufferQueueConsumer::getTextureClientFromBuffer(ANativeWindowBuffer* buffer)
-{
- Mutex::Autolock _l(mCore->mMutex);
- if (buffer == NULL) {
- ALOGE("getSlotFromBufferLocked: encountered NULL buffer");
- return nullptr;
- }
-
- for (int i = 0; i < GonkBufferQueueDefs::NUM_BUFFER_SLOTS; i++) {
- if (mSlots[i].mGraphicBuffer != NULL && mSlots[i].mGraphicBuffer->handle == buffer->handle) {
- RefPtr<TextureClient> client(mSlots[i].mTextureClient);
- return client.forget();
- }
- }
- ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle);
- return nullptr;
-}
-
-int
-GonkBufferQueueConsumer::getSlotFromTextureClientLocked(GonkBufferSlot::TextureClient* client) const
-{
- if (client == NULL) {
- ALOGE("getSlotFromBufferLocked: encountered NULL buffer");
- return BAD_VALUE;
- }
-
- for (int i = 0; i < GonkBufferQueueDefs::NUM_BUFFER_SLOTS; i++) {
- if (mSlots[i].mTextureClient == client) {
- return i;
- }
- }
- ALOGE("getSlotFromBufferLocked: unknown TextureClient: %p", client);
- return BAD_VALUE;
-}
-
-} // namespace android
diff --git a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueConsumer.h b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueConsumer.h
deleted file mode 100644
index a97cfab42..000000000
--- a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueConsumer.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- * Copyright (C) 2014 Mozilla Foundation
- *
- * 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 NATIVEWINDOW_GONKBUFFERQUEUECONSUMER_LL_H
-#define NATIVEWINDOW_GONKBUFFERQUEUECONSUMER_LL_H
-
-#include "GonkBufferQueueDefs.h"
-#include "IGonkGraphicBufferConsumerLL.h"
-
-namespace android {
-
-class GonkBufferQueueCore;
-
-class GonkBufferQueueConsumer : public BnGonkGraphicBufferConsumer {
-
-public:
- GonkBufferQueueConsumer(const sp<GonkBufferQueueCore>& core);
- virtual ~GonkBufferQueueConsumer();
-
- // acquireBuffer attempts to acquire ownership of the next pending buffer in
- // the GonkBufferQueue. If no buffer is pending then it returns
- // NO_BUFFER_AVAILABLE. If a buffer is successfully acquired, the
- // information about the buffer is returned in BufferItem. If the buffer
- // returned had previously been acquired then the BufferItem::mGraphicBuffer
- // field of buffer is set to NULL and it is assumed that the consumer still
- // holds a reference to the buffer.
- //
- // If expectedPresent is nonzero, it indicates the time when the buffer
- // will be displayed on screen. If the buffer's timestamp is farther in the
- // future, the buffer won't be acquired, and PRESENT_LATER will be
- // returned. The presentation time is in nanoseconds, and the time base
- // is CLOCK_MONOTONIC.
- virtual status_t acquireBuffer(BufferItem* outBuffer,
- nsecs_t expectedPresent);
-
- // See IGonkGraphicBufferConsumer::detachBuffer
- virtual status_t detachBuffer(int slot);
-
- // See IGonkGraphicBufferConsumer::attachBuffer
- virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer);
-
- // releaseBuffer releases a buffer slot from the consumer back to the
- // GonkBufferQueue. This may be done while the buffer's contents are still
- // being accessed. The fence will signal when the buffer is no longer
- // in use. frameNumber is used to indentify the exact buffer returned.
- //
- // If releaseBuffer returns STALE_BUFFER_SLOT, then the consumer must free
- // any references to the just-released buffer that it might have, as if it
- // had received a onBuffersReleased() call with a mask set for the released
- // buffer.
- virtual status_t releaseBuffer(int slot, uint64_t frameNumber,
- const sp<Fence>& releaseFence);
-
- // connect connects a consumer to the GonkBufferQueue. Only one
- // consumer may be connected, and when that consumer disconnects the
- // GonkBufferQueue is placed into the "abandoned" state, causing most
- // interactions with the GonkBufferQueue by the producer to fail.
- // controlledByApp indicates whether the consumer is controlled by
- // the application.
- //
- // consumerListener may not be NULL.
- virtual status_t connect(const sp<IConsumerListener>& consumerListener,
- bool controlledByApp);
-
- // disconnect disconnects a consumer from the GonkBufferQueue. All
- // buffers will be freed and the GonkBufferQueue is placed in the "abandoned"
- // state, causing most interactions with the GonkBufferQueue by the producer to
- // fail.
- virtual status_t disconnect();
-
- // getReleasedBuffers sets the value pointed to by outSlotMask to a bit mask
- // indicating which buffer slots have been released by the GonkBufferQueue
- // but have not yet been released by the consumer.
- //
- // This should be called from the onBuffersReleased() callback.
- virtual status_t getReleasedBuffers(uint64_t* outSlotMask);
-
- // setDefaultBufferSize is used to set the size of buffers returned by
- // dequeueBuffer when a width and height of zero is requested. Default
- // is 1x1.
- virtual status_t setDefaultBufferSize(uint32_t width, uint32_t height);
-
- // setDefaultMaxBufferCount sets the default value for the maximum buffer
- // count (the initial default is 2). If the producer has requested a
- // buffer count using setBufferCount, the default buffer count will only
- // take effect if the producer sets the count back to zero.
- //
- // The count must be between 2 and NUM_BUFFER_SLOTS, inclusive.
- virtual status_t setDefaultMaxBufferCount(int bufferCount);
-
- // disableAsyncBuffer disables the extra buffer used in async mode
- // (when both producer and consumer have set their "isControlledByApp"
- // flag) and has dequeueBuffer() return WOULD_BLOCK instead.
- //
- // This can only be called before connect().
- virtual status_t disableAsyncBuffer();
-
- // setMaxAcquiredBufferCount sets the maximum number of buffers that can
- // be acquired by the consumer at one time (default 1). This call will
- // fail if a producer is connected to the GonkBufferQueue.
- virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers);
-
- // setConsumerName sets the name used in logging
- virtual void setConsumerName(const String8& name);
-
- // setDefaultBufferFormat allows the GonkBufferQueue to create
- // GraphicBuffers of a defaultFormat if no format is specified
- // in dequeueBuffer. Formats are enumerated in graphics.h; the
- // initial default is HAL_PIXEL_FORMAT_RGBA_8888.
- virtual status_t setDefaultBufferFormat(uint32_t defaultFormat);
-
- // setConsumerUsageBits will turn on additional usage bits for dequeueBuffer.
- // These are merged with the bits passed to dequeueBuffer. The values are
- // enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER; the default is 0.
- virtual status_t setConsumerUsageBits(uint32_t usage);
-
- // setTransformHint bakes in rotation to buffers so overlays can be used.
- // The values are enumerated in window.h, e.g.
- // NATIVE_WINDOW_TRANSFORM_ROT_90. The default is 0 (no transform).
- virtual status_t setTransformHint(uint32_t hint);
-
- // Retrieve the sideband buffer stream, if any.
- virtual sp<NativeHandle> getSidebandStream() const;
-
- // dump our state in a String
- virtual void dumpToString(String8& result, const char* prefix) const;
-
- // Added by mozilla
- virtual already_AddRefed<GonkBufferSlot::TextureClient> getTextureClientFromBuffer(ANativeWindowBuffer* buffer);
-
- virtual int getSlotFromTextureClientLocked(GonkBufferSlot::TextureClient* client) const;
-
- // Functions required for backwards compatibility.
- // These will be modified/renamed in IGonkGraphicBufferConsumer and will be
- // removed from this class at that time. See b/13306289.
- 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<GonkBufferQueueCore> mCore;
-
- // This references mCore->mSlots. Lock mCore->mMutex while accessing.
- GonkBufferQueueDefs::SlotsType& mSlots;
-
- // This is a cached copy of the name stored in the GonkBufferQueueCore.
- // It's updated during setConsumerName.
- String8 mConsumerName;
-
-}; // class GonkBufferQueueConsumer
-
-} // namespace android
-
-#endif
diff --git a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueCore.cpp b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueCore.cpp
deleted file mode 100644
index 9e8e337f6..000000000
--- a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueCore.cpp
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- * Copyright (C) 2014 Mozilla Foundation
- *
- * 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 LOG_TAG "GonkBufferQueueCore"
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-//#define LOG_NDEBUG 0
-
-#include <inttypes.h>
-
-#include "GonkBufferItem.h"
-#include "GonkBufferQueueCore.h"
-#include <gui/IConsumerListener.h>
-#include <gui/IGraphicBufferAlloc.h>
-#include <gui/IProducerListener.h>
-#include <gui/ISurfaceComposer.h>
-#include <private/gui/ComposerService.h>
-
-#include <cutils/compiler.h>
-#include "mozilla/layers/GrallocTextureClient.h"
-#include "mozilla/layers/ImageBridgeChild.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));
-}
-
-GonkBufferQueueCore::GonkBufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) :
- mAllocator(allocator),
- mMutex(),
- mIsAbandoned(false),
- mConsumerControlledByApp(false),
- mConsumerName(getUniqueName()),
- mConsumerListener(),
- mConsumerUsageBits(0),
- mConnectedApi(NO_CONNECTED_API),
- mConnectedProducerListener(),
- 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),
- mIsAllocating(false),
- mIsAllocatingCondition()
-{
- ALOGV("GonkBufferQueueCore");
-}
-
-GonkBufferQueueCore::~GonkBufferQueueCore() {}
-
-void GonkBufferQueueCore::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=%#" PRIx64 ", scale=%s\n",
- current->mSlot, current->mGraphicBuffer.get(),
- current->mCrop.left, current->mCrop.top, current->mCrop.right,
- current->mCrop.bottom, current->mTransform, current->mTimestamp,
- GonkBufferItem::scalingModeName(current->mScalingMode));
- ++current;
- }
-
- result.appendFormat("%s-GonkBufferQueue mMaxAcquiredBufferCount=%d, "
- "mDequeueBufferCannotBlock=%d, default-size=[%dx%d], "
- "default-format=%d, transform-hint=%02x, FIFO(%zu)={%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 = GonkBufferQueueDefs::NUM_BUFFER_SLOTS - 1; s >= 0; --s) {
- const GonkBufferSlot& slot(mSlots[s]);
- if (slot.mBufferState != GonkBufferSlot::FREE ||
- slot.mGraphicBuffer != NULL) {
- maxBufferCount = s + 1;
- break;
- }
- }
-
- for (int s = 0; s < maxBufferCount; ++s) {
- const GonkBufferSlot& slot(mSlots[s]);
- const sp<GraphicBuffer>& buffer(slot.mGraphicBuffer);
- result.appendFormat("%s%s[%02d:%p] state=%-8s", prefix,
- (slot.mBufferState == GonkBufferSlot::ACQUIRED) ? ">" : " ",
- s, buffer.get(),
- GonkBufferSlot::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 GonkBufferQueueCore::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 GonkBufferQueueCore::getMinMaxBufferCountLocked(bool async) const {
- return getMinUndequeuedBufferCountLocked(async) + 1;
-}
-
-int GonkBufferQueueCore::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 < GonkBufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
- GonkBufferSlot::BufferState state = mSlots[s].mBufferState;
- if (state == GonkBufferSlot::QUEUED || state == GonkBufferSlot::DEQUEUED) {
- maxBufferCount = s + 1;
- }
- }
-
- return maxBufferCount;
-}
-
-status_t GonkBufferQueueCore::setDefaultMaxBufferCountLocked(int count) {
- const int minBufferCount = 2;
- if (count < minBufferCount || count > GonkBufferQueueDefs::NUM_BUFFER_SLOTS) {
- ALOGV("setDefaultMaxBufferCount: invalid count %d, should be in "
- "[%d, %d]",
- count, minBufferCount, GonkBufferQueueDefs::NUM_BUFFER_SLOTS);
- return BAD_VALUE;
- }
-
- ALOGV("setDefaultMaxBufferCount: setting count to %d", count);
- mDefaultMaxBufferCount = count;
- mDequeueCondition.broadcast();
-
- return NO_ERROR;
-}
-
-void GonkBufferQueueCore::freeBufferLocked(int slot) {
- ALOGV("freeBufferLocked: slot %d", slot);
-
- if (mSlots[slot].mTextureClient) {
- mSlots[slot].mTextureClient->ClearRecycleCallback();
- // release TextureClient in ImageBridge thread
- RefPtr<TextureClientReleaseTask> task =
- MakeAndAddRef<TextureClientReleaseTask>(mSlots[slot].mTextureClient);
- mSlots[slot].mTextureClient = NULL;
- ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask(task.forget());
- }
- mSlots[slot].mGraphicBuffer.clear();
- if (mSlots[slot].mBufferState == GonkBufferSlot::ACQUIRED) {
- mSlots[slot].mNeedsCleanupOnRelease = true;
- }
- mSlots[slot].mBufferState = GonkBufferSlot::FREE;
- mSlots[slot].mFrameNumber = UINT32_MAX;
- mSlots[slot].mAcquireCalled = false;
-
- // Destroy fence as GonkBufferQueue now takes ownership
- mSlots[slot].mFence = Fence::NO_FENCE;
-}
-
-void GonkBufferQueueCore::freeAllBuffersLocked() {
- ALOGW_IF(!mQueue.isEmpty(),
- "freeAllBuffersLocked called but mQueue is not empty");
- mQueue.clear();
- mBufferHasBeenQueued = false;
- for (int s = 0; s < GonkBufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
- freeBufferLocked(s);
- }
-}
-
-bool GonkBufferQueueCore::stillTracking(const GonkBufferItem* item) const {
- const GonkBufferSlot& slot = mSlots[item->mSlot];
-
- ALOGV("stillTracking: item { slot=%d/%" PRIu64 " buffer=%p } "
- "slot { slot=%d/%" PRIu64 " 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);
-}
-
-void GonkBufferQueueCore::waitWhileAllocatingLocked() const {
- ATRACE_CALL();
- while (mIsAllocating) {
- mIsAllocatingCondition.wait(mMutex);
- }
-}
-
-} // namespace android
diff --git a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueCore.h b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueCore.h
deleted file mode 100644
index 936e11686..000000000
--- a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueCore.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- * Copyright (C) 2014 Mozilla Foundation
- *
- * 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 NATIVEWINDOW_GONKBUFFERQUEUECORE_LL_H
-#define NATIVEWINDOW_GONKBUFFERQUEUECORE_LL_H
-
-#include "GonkBufferQueueDefs.h"
-#include "GonkBufferSlot.h"
-
-#include <utils/Condition.h>
-#include <utils/Mutex.h>
-#include <utils/NativeHandle.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/StrongPointer.h>
-#include <utils/Trace.h>
-#include <utils/Vector.h>
-
-#include "mozilla/layers/TextureClient.h"
-
-#define ATRACE_BUFFER_INDEX(index)
-
-using namespace mozilla;
-using namespace mozilla::gfx;
-using namespace mozilla::layers;
-
-namespace android {
-
-class GonkBufferItem;
-class IConsumerListener;
-class IGraphicBufferAlloc;
-class IProducerListener;
-
-class GonkBufferQueueCore : public virtual RefBase {
-
- friend class GonkBufferQueueProducer;
- friend class GonkBufferQueueConsumer;
-
-public:
- // 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 = GonkBufferQueueDefs::NUM_BUFFER_SLOTS - 2 };
-
- // The default API number used to indicate that no producer is connected
- enum { NO_CONNECTED_API = 0 };
-
- typedef Vector<GonkBufferItem> Fifo;
- typedef mozilla::layers::TextureClient TextureClient;
-
- // GonkBufferQueueCore manages a pool of gralloc memory slots to be used by
- // producers and consumers. allocator is used to allocate all the needed
- // gralloc buffers.
- GonkBufferQueueCore(const sp<IGraphicBufferAlloc>& allocator = NULL);
- virtual ~GonkBufferQueueCore();
-
-private:
- // Dump our state in a string
- void dump(String8& result, const char* prefix) const;
-
- int getSlotFromTextureClientLocked(TextureClient* client) 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 GonkBufferQueue 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 GonkBufferItem* item) const;
-
- // waitWhileAllocatingLocked blocks until mIsAllocating is false.
- void waitWhileAllocatingLocked() const;
-
- // 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 GonkBufferQueueCore objects. It must be locked whenever any
- // member variable is accessed.
- mutable Mutex mMutex;
-
- // mIsAbandoned indicates that the GonkBufferQueue 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 GonkBufferQueue 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 GonkBufferQueue 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 GonkBufferQueue. 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<IProducerListener> mConnectedProducerListener;
-
- // 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.
- GonkBufferQueueDefs::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 GonkBufferQueue. 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;
-
- // mSidebandStream is a handle to the sideband buffer stream, if any
- sp<NativeHandle> mSidebandStream;
-
- // mIsAllocating indicates whether a producer is currently trying to allocate buffers (which
- // releases mMutex while doing the allocation proper). Producers should not modify any of the
- // FREE slots while this is true. mIsAllocatingCondition is signaled when this value changes to
- // false.
- bool mIsAllocating;
-
- // mIsAllocatingCondition is a condition variable used by producers to wait until mIsAllocating
- // becomes false.
- mutable Condition mIsAllocatingCondition;
-}; // class GonkBufferQueueCore
-
-} // namespace android
-
-#endif
diff --git a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueDefs.h b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueDefs.h
deleted file mode 100644
index 60085706f..000000000
--- a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueDefs.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- * Copyright (C) 2014 Mozilla Foundation
- *
- * 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 NATIVEWINDOW_BUFFERQUEUECOREDEFS_H
-#define NATIVEWINDOW_BUFFERQUEUECOREDEFS_H
-
-#include "GonkBufferSlot.h"
-
-namespace android {
- class GonkBufferQueueCore;
-
- namespace GonkBufferQueueDefs {
- // GonkBufferQueue 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 = 64 };
-
- typedef GonkBufferSlot SlotsType[NUM_BUFFER_SLOTS];
- } // namespace GonkBufferQueueDefs
-} // namespace android
-
-#endif
diff --git a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueLL.cpp b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueLL.cpp
deleted file mode 100644
index 649d06bee..000000000
--- a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueLL.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- * Copyright (C) 2014 Mozilla Foundation
- *
- * 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 LOG_TAG "GonkBufferQueue"
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#define LOG_NDEBUG 0
-
-#include "GonkBufferQueue.h"
-#include "GonkBufferQueueConsumer.h"
-#include "GonkBufferQueueCore.h"
-#include "GonkBufferQueueProducer.h"
-
-namespace android {
-
-GonkBufferQueue::ProxyConsumerListener::ProxyConsumerListener(
- const wp<ConsumerListener>& consumerListener):
- mConsumerListener(consumerListener) {}
-
-GonkBufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {}
-
-#if ANDROID_VERSION == 21
-void GonkBufferQueue::ProxyConsumerListener::onFrameAvailable() {
- sp<ConsumerListener> listener(mConsumerListener.promote());
- if (listener != NULL) {
- listener->onFrameAvailable();
- }
-}
-#else
-void GonkBufferQueue::ProxyConsumerListener::onFrameAvailable(const ::android::BufferItem& item) {
- sp<ConsumerListener> listener(mConsumerListener.promote());
- if (listener != NULL) {
- listener->onFrameAvailable(item);
- }
-}
-
-void GonkBufferQueue::ProxyConsumerListener::onFrameReplaced(const ::android::BufferItem& item) {
- sp<ConsumerListener> listener(mConsumerListener.promote());
- if (listener != NULL) {
- listener->onFrameReplaced(item);
- }
-}
-#endif
-
-void GonkBufferQueue::ProxyConsumerListener::onBuffersReleased() {
- sp<ConsumerListener> listener(mConsumerListener.promote());
- if (listener != NULL) {
- listener->onBuffersReleased();
- }
-}
-
-void GonkBufferQueue::ProxyConsumerListener::onSidebandStreamChanged() {
- sp<ConsumerListener> listener(mConsumerListener.promote());
- if (listener != NULL) {
- listener->onSidebandStreamChanged();
- }
-}
-
-void GonkBufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
- sp<IGonkGraphicBufferConsumer>* outConsumer,
- const sp<IGraphicBufferAlloc>& allocator) {
- LOG_ALWAYS_FATAL_IF(outProducer == NULL,
- "GonkBufferQueue: outProducer must not be NULL");
- LOG_ALWAYS_FATAL_IF(outConsumer == NULL,
- "GonkBufferQueue: outConsumer must not be NULL");
-
- sp<GonkBufferQueueCore> core(new GonkBufferQueueCore(allocator));
- LOG_ALWAYS_FATAL_IF(core == NULL,
- "GonkBufferQueue: failed to create GonkBufferQueueCore");
-
- sp<IGraphicBufferProducer> producer(new GonkBufferQueueProducer(core));
- LOG_ALWAYS_FATAL_IF(producer == NULL,
- "GonkBufferQueue: failed to create GonkBufferQueueProducer");
-
- sp<IGonkGraphicBufferConsumer> consumer(new GonkBufferQueueConsumer(core));
- LOG_ALWAYS_FATAL_IF(consumer == NULL,
- "GonkBufferQueue: failed to create GonkBufferQueueConsumer");
-
- *outProducer = producer;
- *outConsumer = consumer;
-}
-
-}; // namespace android
diff --git a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueLL.h b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueLL.h
deleted file mode 100644
index b1b4e06b5..000000000
--- a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueLL.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- * Copyright (C) 2014 Mozilla Foundation
- *
- * 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 NATIVEWINDOW_GONKBUFFERQUEUE_LL_H
-#define NATIVEWINDOW_GONKBUFFERQUEUE_LL_H
-
-#include "GonkBufferQueueDefs.h"
-#include "IGonkGraphicBufferConsumerLL.h"
-#include <gui/IGraphicBufferProducer.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>
-
-namespace android {
-
-class GonkBufferQueue {
-public:
- // GonkBufferQueue 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 = GonkBufferQueueDefs::NUM_BUFFER_SLOTS };
- // Used as a placeholder slot# when the value isn't pointing to an existing buffer.
- enum { INVALID_BUFFER_SLOT = IGonkGraphicBufferConsumer::BufferItem::INVALID_BUFFER_SLOT };
- // Alias to <IGonkGraphicBufferConsumer.h> -- please scope from there in future code!
- enum {
- NO_BUFFER_AVAILABLE = IGonkGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
- PRESENT_LATER = IGonkGraphicBufferConsumer::PRESENT_LATER,
- };
-
- // When in async mode 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 };
-
- // for backward source compatibility
- typedef ::android::ConsumerListener ConsumerListener;
- typedef IGonkGraphicBufferConsumer::BufferItem BufferItem;
-
- // ProxyConsumerListener is a ConsumerListener implementation that keeps a weak
- // reference to the actual consumer object. It forwards all calls to that
- // consumer object so long as it exists.
- //
- // This class exists to avoid having a circular reference between the
- // GonkBufferQueue object and the consumer object. The reason this can't be a weak
- // reference in the GonkBufferQueue class is because we're planning to expose the
- // consumer side of a GonkBufferQueue as a binder interface, which doesn't support
- // weak references.
- class ProxyConsumerListener : public BnConsumerListener {
- public:
- ProxyConsumerListener(const wp<ConsumerListener>& consumerListener);
- virtual ~ProxyConsumerListener();
-#if ANDROID_VERSION == 21
- virtual void onFrameAvailable();
-#else
- virtual void onFrameAvailable(const ::android::BufferItem& item);
- virtual void onFrameReplaced(const ::android::BufferItem& item);
-#endif
- virtual void onBuffersReleased();
- virtual void onSidebandStreamChanged();
- private:
- // mConsumerListener is a weak reference to the IConsumerListener. This is
- // the raison d'etre of ProxyConsumerListener.
- wp<ConsumerListener> mConsumerListener;
- };
-
- // GonkBufferQueue manages a pool of gralloc memory slots to be used by
- // producers and consumers. allocator is used to allocate all the
- // needed gralloc buffers.
- static void createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
- sp<IGonkGraphicBufferConsumer>* outConsumer,
- const sp<IGraphicBufferAlloc>& allocator = NULL);
-
-private:
- GonkBufferQueue(); // Create through createBufferQueue
-};
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-
-#endif // NATIVEWINDOW_GONKBUFFERQUEUE_LL_H
diff --git a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.cpp b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.cpp
deleted file mode 100644
index d3436756f..000000000
--- a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.cpp
+++ /dev/null
@@ -1,886 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- * Copyright (C) 2014 Mozilla Foundation
- *
- * 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 <inttypes.h>
-
-#define LOG_TAG "GonkBufferQueueProducer"
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-//#define LOG_NDEBUG 0
-
-#include "GonkBufferItem.h"
-#include "GonkBufferQueueCore.h"
-#include "GonkBufferQueueProducer.h"
-#include <gui/IConsumerListener.h>
-#include <gui/IGraphicBufferAlloc.h>
-#include <gui/IProducerListener.h>
-
-#include <cutils/compiler.h>
-#include <utils/Log.h>
-#include <utils/Trace.h>
-
-#include "mozilla/layers/GrallocTextureClient.h"
-#include "mozilla/layers/ImageBridgeChild.h"
-#include "mozilla/layers/TextureClient.h"
-
-namespace android {
-
-GonkBufferQueueProducer::GonkBufferQueueProducer(const sp<GonkBufferQueueCore>& core) :
- mCore(core),
- mSlots(core->mSlots),
- mConsumerName(),
- mSynchronousMode(true),
- mStickyTransform(0) {}
-
-GonkBufferQueueProducer::~GonkBufferQueueProducer() {}
-
-status_t GonkBufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
- ATRACE_CALL();
- ALOGV("requestBuffer: slot %d", slot);
- Mutex::Autolock lock(mCore->mMutex);
-
- if (mCore->mIsAbandoned) {
- ALOGE("requestBuffer: GonkBufferQueue has been abandoned");
- return NO_INIT;
- }
-
- if (slot < 0 || slot >= GonkBufferQueueDefs::NUM_BUFFER_SLOTS) {
- ALOGE("requestBuffer: slot index %d out of range [0, %d)",
- slot, GonkBufferQueueDefs::NUM_BUFFER_SLOTS);
- return BAD_VALUE;
- } else if (mSlots[slot].mBufferState != GonkBufferSlot::DEQUEUED) {
- ALOGE("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 GonkBufferQueueProducer::setBufferCount(int bufferCount) {
- ATRACE_CALL();
- ALOGV("setBufferCount: count = %d", bufferCount);
-
- sp<IConsumerListener> listener;
- { // Autolock scope
- Mutex::Autolock lock(mCore->mMutex);
- mCore->waitWhileAllocatingLocked();
-
- if (mCore->mIsAbandoned) {
- ALOGE("setBufferCount: GonkBufferQueue has been abandoned");
- return NO_INIT;
- }
-
- if (bufferCount > GonkBufferQueueDefs::NUM_BUFFER_SLOTS) {
- ALOGE("setBufferCount: bufferCount %d too large (max %d)",
- bufferCount, GonkBufferQueueDefs::NUM_BUFFER_SLOTS);
- return BAD_VALUE;
- }
-
- // There must be no dequeued buffers when changing the buffer count.
- for (int s = 0; s < GonkBufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
- if (mSlots[s].mBufferState == GonkBufferSlot::DEQUEUED) {
- ALOGE("setBufferCount: buffer owned by producer");
- return BAD_VALUE;
- }
- }
-
- if (bufferCount == 0) {
- mCore->mOverrideMaxBufferCount = 0;
- mCore->mDequeueCondition.broadcast();
- return NO_ERROR;
- }
-
- const int minBufferSlots = mCore->getMinMaxBufferCountLocked(false);
- if (bufferCount < minBufferSlots) {
- ALOGE("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 GonkBufferQueueProducer::waitForFreeSlotThenRelock(const char* caller,
- bool async, int* found, status_t* returnFlags) const {
- bool tryAgain = true;
- while (tryAgain) {
- if (mCore->mIsAbandoned) {
- ALOGE("%s: GonkBufferQueue has been abandoned", caller);
- 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) {
- ALOGE("%s: async mode is invalid with buffer count override",
- caller);
- return BAD_VALUE;
- }
- }
-
- // Free up any buffers that are in slots beyond the max buffer count
- //for (int s = maxBufferCount; s < GonkBufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
- // assert(mSlots[s].mBufferState == GonkBufferSlot::FREE);
- // if (mSlots[s].mGraphicBuffer != NULL) {
- // mCore->freeBufferLocked(s);
- // *returnFlags |= RELEASE_ALL_BUFFERS;
- // }
- //}
-
- // Look for a free buffer to give to the client
- *found = GonkBufferQueueCore::INVALID_BUFFER_SLOT;
- int dequeuedCount = 0;
- int acquiredCount = 0;
- for (int s = 0; s < maxBufferCount; ++s) {
- switch (mSlots[s].mBufferState) {
- case GonkBufferSlot::DEQUEUED:
- ++dequeuedCount;
- break;
- case GonkBufferSlot::ACQUIRED:
- ++acquiredCount;
- break;
- case GonkBufferSlot::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 == GonkBufferQueueCore::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) {
- ALOGE("%s: can't dequeue multiple buffers without setting the "
- "buffer count", caller);
- return INVALID_OPERATION;
- }
-
- // 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) {
- ALOGE("%s: min undequeued buffer count (%d) exceeded "
- "(dequeued=%d undequeued=%d)",
- caller, minUndequeuedCount,
- dequeuedCount, newUndequeuedCount);
- return INVALID_OPERATION;
- }
- }
-
- // 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.
- bool tooManyBuffers = mCore->mQueue.size()
- > static_cast<size_t>(maxBufferCount);
- if (tooManyBuffers) {
- ALOGV("%s: queue size is %zu, waiting", caller,
- mCore->mQueue.size());
- }
-
- // If no buffer is found, or if the queue has too many buffers
- // outstanding, wait for a buffer to be acquired or released, or for the
- // max buffer count to change.
- tryAgain = (*found == GonkBufferQueueCore::INVALID_BUFFER_SLOT) ||
- tooManyBuffers;
- 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)
-
- return NO_ERROR;
-}
-
-status_t GonkBufferQueueProducer::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
-
- ALOGV("dequeueBuffer: async=%s w=%u h=%u format=%#x, usage=%#x",
- async ? "true" : "false", width, height, format, usage);
-
- if ((width && !height) || (!width && height)) {
- ALOGE("dequeueBuffer: invalid size: w=%u h=%u", width, height);
- return BAD_VALUE;
- }
-
- status_t returnFlags = NO_ERROR;
- // Reset slot
- *outSlot = GonkBufferQueueCore::INVALID_BUFFER_SLOT;
-
- bool attachedByConsumer = false;
-
- { // Autolock scope
- Mutex::Autolock lock(mCore->mMutex);
- mCore->waitWhileAllocatingLocked();
-
- if (format == 0) {
- format = mCore->mDefaultBufferFormat;
- }
-
- // Enable the usage bits the consumer requested
- usage |= mCore->mConsumerUsageBits;
-
- int found;
- status_t status = waitForFreeSlotThenRelock("dequeueBuffer", async,
- &found, &returnFlags);
- if (status != NO_ERROR) {
- return status;
- }
-
- // This should not happen
- if (found == GonkBufferQueueCore::INVALID_BUFFER_SLOT) {
- ALOGE("dequeueBuffer: no available buffer slots");
- return -EBUSY;
- }
-
- *outSlot = found;
-
- attachedByConsumer = mSlots[found].mAttachedByConsumer;
-
- const bool useDefaultSize = !width && !height;
- if (useDefaultSize) {
- width = mCore->mDefaultWidth;
- height = mCore->mDefaultHeight;
- }
-
- mSlots[found].mBufferState = GonkBufferSlot::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].mFence = Fence::NO_FENCE;
-
- if (mSlots[found].mTextureClient) {
- mSlots[found].mTextureClient->ClearRecycleCallback();
- // release TextureClient in ImageBridge thread
- RefPtr<TextureClientReleaseTask> task =
- MakeAndAddRef<TextureClientReleaseTask>(mSlots[found].mTextureClient);
- mSlots[found].mTextureClient = NULL;
- ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask(task.forget());
- }
-
- returnFlags |= BUFFER_NEEDS_REALLOCATION;
- }
-
- if (CC_UNLIKELY(mSlots[found].mFence == NULL)) {
- ALOGE("dequeueBuffer: about to return a NULL fence - "
- "slot=%d w=%d h=%d format=%u",
- found, buffer->width, buffer->height, buffer->format);
- }
-
- *outFence = mSlots[found].mFence;
- mSlots[found].mFence = Fence::NO_FENCE;
- } // Autolock scope
-
- if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
- RefPtr<LayersIPCChannel> allocator = ImageBridgeChild::GetSingleton();
- usage |= GraphicBuffer::USAGE_HW_TEXTURE;
- GrallocTextureData* texData = GrallocTextureData::Create(IntSize(width,height), format,
- gfx::BackendType::NONE,
- usage, allocator);
- if (!texData) {
- ALOGE("dequeueBuffer: failed to alloc gralloc buffer");
- return -ENOMEM;
- }
- RefPtr<TextureClient> textureClient = TextureClient::CreateWithData(
- texData, TextureFlags::RECYCLE | TextureFlags::DEALLOCATE_CLIENT, allocator);
-
- sp<GraphicBuffer> graphicBuffer = texData->GetGraphicBuffer();
-
- { // Autolock scope
- Mutex::Autolock lock(mCore->mMutex);
-
- if (mCore->mIsAbandoned) {
- ALOGE("dequeueBuffer: GonkBufferQueue has been abandoned");
- return NO_INIT;
- }
-
- mSlots[*outSlot].mFrameNumber = UINT32_MAX;
- mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
- mSlots[*outSlot].mTextureClient = textureClient;
- } // Autolock scope
- }
-
- if (attachedByConsumer) {
- returnFlags |= BUFFER_NEEDS_REALLOCATION;
- }
-
- ALOGV("dequeueBuffer: returning slot=%d/%" PRIu64 " buf=%p flags=%#x",
- *outSlot,
- mSlots[*outSlot].mFrameNumber,
- mSlots[*outSlot].mGraphicBuffer->handle, returnFlags);
-
- return returnFlags;
-}
-
-status_t GonkBufferQueueProducer::detachBuffer(int slot) {
- ATRACE_CALL();
- ATRACE_BUFFER_INDEX(slot);
- ALOGV("detachBuffer(P): slot %d", slot);
- Mutex::Autolock lock(mCore->mMutex);
-
- if (mCore->mIsAbandoned) {
- ALOGE("detachBuffer(P): GonkBufferQueue has been abandoned");
- return NO_INIT;
- }
-
- if (slot < 0 || slot >= GonkBufferQueueDefs::NUM_BUFFER_SLOTS) {
- ALOGE("detachBuffer(P): slot index %d out of range [0, %d)",
- slot, GonkBufferQueueDefs::NUM_BUFFER_SLOTS);
- return BAD_VALUE;
- } else if (mSlots[slot].mBufferState != GonkBufferSlot::DEQUEUED) {
- ALOGE("detachBuffer(P): slot %d is not owned by the producer "
- "(state = %d)", slot, mSlots[slot].mBufferState);
- return BAD_VALUE;
- } else if (!mSlots[slot].mRequestBufferCalled) {
- ALOGE("detachBuffer(P): buffer in slot %d has not been requested",
- slot);
- return BAD_VALUE;
- }
-
- mCore->freeBufferLocked(slot);
- mCore->mDequeueCondition.broadcast();
-
- return NO_ERROR;
-}
-
-status_t GonkBufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
- sp<Fence>* outFence) {
- ATRACE_CALL();
-
- if (outBuffer == NULL) {
- ALOGE("detachNextBuffer: outBuffer must not be NULL");
- return BAD_VALUE;
- } else if (outFence == NULL) {
- ALOGE("detachNextBuffer: outFence must not be NULL");
- return BAD_VALUE;
- }
-
- Mutex::Autolock lock(mCore->mMutex);
- mCore->waitWhileAllocatingLocked();
-
- if (mCore->mIsAbandoned) {
- ALOGE("detachNextBuffer: GonkBufferQueue has been abandoned");
- return NO_INIT;
- }
-
- // Find the oldest valid slot
- int found = GonkBufferQueueCore::INVALID_BUFFER_SLOT;
- for (int s = 0; s < GonkBufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
- if (mSlots[s].mBufferState == GonkBufferSlot::FREE &&
- mSlots[s].mGraphicBuffer != NULL) {
- if (found == GonkBufferQueueCore::INVALID_BUFFER_SLOT ||
- mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) {
- found = s;
- }
- }
- }
-
- if (found == GonkBufferQueueCore::INVALID_BUFFER_SLOT) {
- return NO_MEMORY;
- }
-
- ALOGV("detachNextBuffer detached slot %d", found);
-
- *outBuffer = mSlots[found].mGraphicBuffer;
- *outFence = mSlots[found].mFence;
- mCore->freeBufferLocked(found);
-
- return NO_ERROR;
-}
-
-status_t GonkBufferQueueProducer::attachBuffer(int* outSlot,
- const sp<android::GraphicBuffer>& buffer) {
- ATRACE_CALL();
-
- if (outSlot == NULL) {
- ALOGE("attachBuffer(P): outSlot must not be NULL");
- return BAD_VALUE;
- } else if (buffer == NULL) {
- ALOGE("attachBuffer(P): cannot attach NULL buffer");
- return BAD_VALUE;
- }
-
- Mutex::Autolock lock(mCore->mMutex);
- mCore->waitWhileAllocatingLocked();
-
- status_t returnFlags = NO_ERROR;
- int found;
- // TODO: Should we provide an async flag to attachBuffer? It seems
- // unlikely that buffers which we are attaching to a GonkBufferQueue will
- // be asynchronous (droppable), but it may not be impossible.
- status_t status = waitForFreeSlotThenRelock("attachBuffer(P)", false,
- &found, &returnFlags);
- if (status != NO_ERROR) {
- return status;
- }
-
- // This should not happen
- if (found == GonkBufferQueueCore::INVALID_BUFFER_SLOT) {
- ALOGE("attachBuffer(P): no available buffer slots");
- return -EBUSY;
- }
-
- *outSlot = found;
- ATRACE_BUFFER_INDEX(*outSlot);
- ALOGV("attachBuffer(P): returning slot %d flags=%#x",
- *outSlot, returnFlags);
-
- mSlots[*outSlot].mGraphicBuffer = buffer;
- mSlots[*outSlot].mBufferState = GonkBufferSlot::DEQUEUED;
- mSlots[*outSlot].mFence = Fence::NO_FENCE;
- mSlots[*outSlot].mRequestBufferCalled = true;
-
- return returnFlags;
-}
-
-status_t GonkBufferQueueProducer::setSynchronousMode(bool enabled) {
- ALOGV("setSynchronousMode: enabled=%d", enabled);
- Mutex::Autolock lock(mCore->mMutex);
-
- if (mCore->mIsAbandoned) {
- ALOGE("setSynchronousMode: BufferQueue has been abandoned!");
- return NO_INIT;
- }
-
- if (mSynchronousMode != enabled) {
- mSynchronousMode = enabled;
- mCore->mDequeueCondition.broadcast();
- }
- return OK;
-}
-
-status_t GonkBufferQueueProducer::queueBuffer(int slot,
- const QueueBufferInput &input, QueueBufferOutput *output) {
- ATRACE_CALL();
-
- int64_t timestamp;
- bool isAutoTimestamp;
- Rect crop;
- int scalingMode;
- uint32_t transform;
- uint32_t stickyTransform;
- bool async;
- sp<Fence> fence;
- input.deflate(&timestamp, &isAutoTimestamp, &crop, &scalingMode, &transform,
- &async, &fence, &stickyTransform);
-
- if (fence == NULL) {
- ALOGE("queueBuffer: fence is NULL");
- // Temporary workaround for b/17946343: soldier-on instead of returning an error. This
- // prevents the client from dying, at the risk of visible corruption due to hwcomposer
- // reading the buffer before the producer is done rendering it. Unless the buffer is the
- // last frame of an animation, the corruption will be transient.
- fence = Fence::NO_FENCE;
- // 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:
- ALOGE("queueBuffer: unknown scaling mode %d", scalingMode);
- return BAD_VALUE;
- }
-
- GonkBufferItem item;
- sp<IConsumerListener> listener;
- { // Autolock scope
- Mutex::Autolock lock(mCore->mMutex);
-
- if (mCore->mIsAbandoned) {
- ALOGE("queueBuffer: GonkBufferQueue 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) {
- ALOGE("queueBuffer: async mode is invalid with "
- "buffer count override");
- return BAD_VALUE;
- }
- }
-
- if (slot < 0 || slot >= maxBufferCount) {
- ALOGE("queueBuffer: slot index %d out of range [0, %d)",
- slot, maxBufferCount);
- return BAD_VALUE;
- } else if (mSlots[slot].mBufferState != GonkBufferSlot::DEQUEUED) {
- ALOGE("queueBuffer: slot %d is not owned by the producer "
- "(state = %d)", slot, mSlots[slot].mBufferState);
- return BAD_VALUE;
- } else if (!mSlots[slot].mRequestBufferCalled) {
- ALOGE("queueBuffer: slot %d was queued without requesting "
- "a buffer", slot);
- return BAD_VALUE;
- }
-
- ALOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64
- " crop=[%d,%d,%d,%d] transform=%#x scale=%s",
- slot, mCore->mFrameCounter + 1, timestamp,
- crop.left, crop.top, crop.right, crop.bottom,
- transform, GonkBufferItem::scalingModeName(scalingMode));
-
- const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
- Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
- Rect croppedRect;
- crop.intersect(bufferRect, &croppedRect);
- if (croppedRect != crop) {
- ALOGE("queueBuffer: crop rect is not contained within the "
- "buffer in slot %d", slot);
- return BAD_VALUE;
- }
-
- mSlots[slot].mFence = fence;
- mSlots[slot].mBufferState = GonkBufferSlot::QUEUED;
- ++mCore->mFrameCounter;
- mSlots[slot].mFrameNumber = mCore->mFrameCounter;
-
- 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;
-
- mStickyTransform = stickyTransform;
-
- 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
- GonkBufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
- if (front->mIsDroppable || !mSynchronousMode) {
- // If the front queued buffer is still being tracked, we first
- // mark it as freed
- if (mCore->stillTracking(front)) {
- mSlots[front->mSlot].mBufferState = GonkBufferSlot::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;
- listener = mCore->mConsumerListener;
- } 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());
-
- item.mGraphicBuffer.clear();
- item.mSlot = GonkBufferItem::INVALID_BUFFER_SLOT;
- } // Autolock scope
-
- // Call back without lock held
- if (listener != NULL) {
-#if ANDROID_VERSION == 21
- listener->onFrameAvailable();
-#else
- listener->onFrameAvailable(reinterpret_cast<::android::BufferItem&>(item));
-#endif
- }
-
- return NO_ERROR;
-}
-
-void GonkBufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
- ATRACE_CALL();
- ALOGV("cancelBuffer: slot %d", slot);
- Mutex::Autolock lock(mCore->mMutex);
-
- if (mCore->mIsAbandoned) {
- ALOGE("cancelBuffer: GonkBufferQueue has been abandoned");
- return;
- }
-
- if (slot < 0 || slot >= GonkBufferQueueDefs::NUM_BUFFER_SLOTS) {
- ALOGE("cancelBuffer: slot index %d out of range [0, %d)",
- slot, GonkBufferQueueDefs::NUM_BUFFER_SLOTS);
- return;
- } else if (mSlots[slot].mBufferState != GonkBufferSlot::DEQUEUED) {
- ALOGE("cancelBuffer: slot %d is not owned by the producer "
- "(state = %d)", slot, mSlots[slot].mBufferState);
- return;
- } else if (fence == NULL) {
- ALOGE("cancelBuffer: fence is NULL");
- return;
- }
-
- mSlots[slot].mBufferState = GonkBufferSlot::FREE;
- mSlots[slot].mFrameNumber = 0;
- mSlots[slot].mFence = fence;
- mCore->mDequeueCondition.broadcast();
-}
-
-int GonkBufferQueueProducer::query(int what, int *outValue) {
- ATRACE_CALL();
- Mutex::Autolock lock(mCore->mMutex);
-
- if (outValue == NULL) {
- ALOGE("query: outValue was NULL");
- return BAD_VALUE;
- }
-
- if (mCore->mIsAbandoned) {
- ALOGE("query: GonkBufferQueue 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_STICKY_TRANSFORM:
- value = static_cast<int>(mStickyTransform);
- 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;
- }
-
- ALOGV("query: %d? %d", what, value);
- *outValue = value;
- return NO_ERROR;
-}
-
-status_t GonkBufferQueueProducer::connect(const sp<IProducerListener>& listener,
- int api, bool producerControlledByApp, QueueBufferOutput *output) {
- ATRACE_CALL();
- Mutex::Autolock lock(mCore->mMutex);
- mConsumerName = mCore->mConsumerName;
- ALOGV("connect(P): api=%d producerControlledByApp=%s", api,
- producerControlledByApp ? "true" : "false");
-
- if (mCore->mIsAbandoned) {
- ALOGE("connect(P): GonkBufferQueue has been abandoned");
- return NO_INIT;
- }
-
- if (mCore->mConsumerListener == NULL) {
- ALOGE("connect(P): GonkBufferQueue has no consumer");
- return NO_INIT;
- }
-
- if (output == NULL) {
- ALOGE("connect(P): output was NULL");
- return BAD_VALUE;
- }
-
- if (mCore->mConnectedApi != GonkBufferQueueCore::NO_CONNECTED_API) {
- ALOGE("connect(P): already connected (cur=%d req=%d)", mCore->mConnectedApi,
- api);
- return BAD_VALUE;
- }
-
- 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 (listener != NULL &&
- listener->asBinder()->remoteBinder() != NULL) {
- status = listener->asBinder()->linkToDeath(
- static_cast<IBinder::DeathRecipient*>(this));
- if (status != NO_ERROR) {
- ALOGE("connect(P): linkToDeath failed: %s (%d)",
- strerror(-status), status);
- }
- }
- mCore->mConnectedProducerListener = listener;
- break;
- default:
- ALOGE("connect(P): unknown API %d", api);
- status = BAD_VALUE;
- break;
- }
-
- mCore->mBufferHasBeenQueued = false;
- mCore->mDequeueBufferCannotBlock =
- mCore->mConsumerControlledByApp && producerControlledByApp;
-
- return status;
-}
-
-status_t GonkBufferQueueProducer::disconnect(int api) {
- ATRACE_CALL();
- ALOGV("disconnect(P): api %d", api);
-
- int status = NO_ERROR;
- sp<IConsumerListener> listener;
- { // Autolock scope
- Mutex::Autolock lock(mCore->mMutex);
- mCore->waitWhileAllocatingLocked();
-
- 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();
- mCore->mConnectedApi = GonkBufferQueueCore::NO_CONNECTED_API;
- mCore->mSidebandStream.clear();
- mCore->mDequeueCondition.broadcast();
- listener = mCore->mConsumerListener;
- } else {
- ALOGE("disconnect(P): connected to another API "
- "(cur=%d req=%d)", mCore->mConnectedApi, api);
- status = BAD_VALUE;
- }
- break;
- default:
- ALOGE("disconnect(P): unknown API %d", api);
- status = BAD_VALUE;
- break;
- }
- } // Autolock scope
-
- // Call back without lock held
- if (listener != NULL) {
- listener->onBuffersReleased();
- }
-
- return status;
-}
-
-status_t GonkBufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) {
- return INVALID_OPERATION;
-}
-
-void GonkBufferQueueProducer::allocateBuffers(bool async, uint32_t width,
- uint32_t height, uint32_t format, uint32_t usage) {
- ALOGE("allocateBuffers: no op");
-}
-
-void GonkBufferQueueProducer::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/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.h b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.h
deleted file mode 100644
index a1a22416a..000000000
--- a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.h
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- * Copyright (C) 2014 Mozilla Foundation
- *
- * 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 NATIVEWINDOW_GONKBUFFERQUEUEPRODUCER_LL_H
-#define NATIVEWINDOW_GONKBUFFERQUEUEPRODUCER_LL_H
-
-#include "GonkBufferQueueDefs.h"
-#include <gui/IGraphicBufferProducer.h>
-
-namespace android {
-
-class GonkBufferQueueProducer : public BnGraphicBufferProducer,
- private IBinder::DeathRecipient {
-public:
- friend class GonkBufferQueue; // Needed to access binderDied
-
- GonkBufferQueueProducer(const sp<GonkBufferQueueCore>& core);
- virtual ~GonkBufferQueueProducer();
-
- // requestBuffer returns the GraphicBuffer for slot N.
- //
- // In normal operation, this is called the first time slot N is returned
- // by dequeueBuffer. It must be called again if dequeueBuffer returns
- // flags indicating that previously-returned buffers are no longer valid.
- virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf);
-
- // setBufferCount updates the number of available buffer slots. If this
- // method succeeds, buffer slots will be both unallocated and owned by
- // the GonkBufferQueue object (i.e. they are not owned by the producer or
- // consumer).
- //
- // This will fail if the producer has dequeued any buffers, or if
- // bufferCount is invalid. bufferCount must generally be a value
- // between the minimum undequeued buffer count (exclusive) and NUM_BUFFER_SLOTS
- // (inclusive). It may also be set to zero (the default) to indicate
- // that the producer does not wish to set a value. The minimum value
- // can be obtained by calling query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
- // ...).
- //
- // This may only be called by the producer. The consumer will be told
- // to discard buffers through the onBuffersReleased callback.
- virtual status_t setBufferCount(int bufferCount);
-
- // dequeueBuffer gets the next buffer slot index for the producer to use.
- // If a buffer slot is available then that slot index is written to the
- // location pointed to by the buf argument and a status of OK is returned.
- // If no slot is available then a status of -EBUSY is returned and buf is
- // unmodified.
- //
- // The outFence parameter will be updated to hold the fence associated with
- // the buffer. The contents of the buffer must not be overwritten until the
- // fence signals. If the fence is Fence::NO_FENCE, the buffer may be
- // written immediately.
- //
- // The width and height parameters must be no greater than the minimum of
- // GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv).
- // An error due to invalid dimensions might not be reported until
- // updateTexImage() is called. If width and height are both zero, the
- // default values specified by setDefaultBufferSize() are used instead.
- //
- // The pixel formats are enumerated in graphics.h, e.g.
- // HAL_PIXEL_FORMAT_RGBA_8888. If the format is 0, the default format
- // will be used.
- //
- // The usage argument specifies gralloc buffer usage flags. The values
- // are enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER. These
- // will be merged with the usage flags specified by setConsumerUsageBits.
- //
- // The return value may be a negative error value or a non-negative
- // collection of flags. If the flags are set, the return values are
- // valid, but additional actions must be performed.
- //
- // If IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION is set, the
- // producer must discard cached GraphicBuffer references for the slot
- // returned in buf.
- // If IGraphicBufferProducer::RELEASE_ALL_BUFFERS is set, the producer
- // must discard cached GraphicBuffer references for all slots.
- //
- // In both cases, the producer will need to call requestBuffer to get a
- // GraphicBuffer handle for the returned slot.
- virtual status_t dequeueBuffer(int *outSlot, sp<Fence>* outFence, bool async,
- uint32_t width, uint32_t height, uint32_t format, uint32_t usage);
-
- // See IGraphicBufferProducer::detachBuffer
- virtual status_t detachBuffer(int slot);
-
- // See IGraphicBufferProducer::detachNextBuffer
- virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
- sp<Fence>* outFence);
-
- // See IGraphicBufferProducer::attachBuffer
- virtual status_t attachBuffer(int* outSlot, const sp<GraphicBuffer>& buffer);
-
- // queueBuffer returns a filled buffer to the GonkBufferQueue.
- //
- // Additional data is provided in the QueueBufferInput struct. Notably,
- // a timestamp must be provided for the buffer. The timestamp is in
- // nanoseconds, and must be monotonically increasing. Its other semantics
- // (zero point, etc) are producer-specific and should be documented by the
- // producer.
- //
- // The caller may provide a fence that signals when all rendering
- // operations have completed. Alternatively, NO_FENCE may be used,
- // indicating that the buffer is ready immediately.
- //
- // Some values are returned in the output struct: the current settings
- // for default width and height, the current transform hint, and the
- // number of queued buffers.
- virtual status_t queueBuffer(int slot,
- const QueueBufferInput& input, QueueBufferOutput* output);
-
- // cancelBuffer returns a dequeued buffer to the GonkBufferQueue, but doesn't
- // queue it for use by the consumer.
- //
- // The buffer will not be overwritten until the fence signals. The fence
- // will usually be the one obtained from dequeueBuffer.
- virtual void cancelBuffer(int slot, const sp<Fence>& fence);
-
- // Query native window attributes. The "what" values are enumerated in
- // window.h (e.g. NATIVE_WINDOW_FORMAT).
- virtual int query(int what, int* outValue);
-
- // connect attempts to connect a producer API to the GonkBufferQueue. This
- // must be called before any other IGraphicBufferProducer methods are
- // called except for getAllocator. A consumer must already be connected.
- //
- // This method will fail if connect was previously called on the
- // GonkBufferQueue and no corresponding disconnect call was made (i.e. if
- // it's still connected to a producer).
- //
- // APIs are enumerated in window.h (e.g. NATIVE_WINDOW_API_CPU).
- virtual status_t connect(const sp<IProducerListener>& listener,
- int api, bool producerControlledByApp, QueueBufferOutput* output);
-
- // disconnect attempts to disconnect a producer API from the GonkBufferQueue.
- // Calling this method will cause any subsequent calls to other
- // IGraphicBufferProducer methods to fail except for getAllocator and connect.
- // Successfully calling connect after this will allow the other methods to
- // succeed again.
- //
- // This method will fail if the the GonkBufferQueue is not currently
- // connected to the specified producer API.
- virtual status_t disconnect(int api);
-
- // Attaches a sideband buffer stream to the IGraphicBufferProducer.
- //
- // A sideband stream is a device-specific mechanism for passing buffers
- // from the producer to the consumer without using dequeueBuffer/
- // queueBuffer. If a sideband stream is present, the consumer can choose
- // whether to acquire buffers from the sideband stream or from the queued
- // buffers.
- //
- // Passing NULL or a different stream handle will detach the previous
- // handle if any.
- virtual status_t setSidebandStream(const sp<NativeHandle>& stream);
-
- // See IGraphicBufferProducer::allocateBuffers
- virtual void allocateBuffers(bool async, uint32_t width, uint32_t height,
- uint32_t format, uint32_t usage);
-
- // setSynchronousMode sets whether dequeueBuffer is synchronous or
- // asynchronous. In synchronous mode, dequeueBuffer blocks until
- // a buffer is available, the currently bound buffer can be dequeued and
- // queued buffers will be acquired in order. In asynchronous mode,
- // a queued buffer may be replaced by a subsequently queued buffer.
- //
- // The default mode is synchronous.
- // This should be called only during initialization.
- virtual status_t setSynchronousMode(bool enabled);
-
-private:
- // This is required by the IBinder::DeathRecipient interface
- virtual void binderDied(const wp<IBinder>& who);
-
- // waitForFreeSlotThenRelock finds the oldest slot in the FREE state. It may
- // block if there are no available slots and we are not in non-blocking
- // mode (producer and consumer controlled by the application). If it blocks,
- // it will release mCore->mMutex while blocked so that other operations on
- // the GonkBufferQueue may succeed.
- status_t waitForFreeSlotThenRelock(const char* caller, bool async,
- int* found, status_t* returnFlags) const;
-
- sp<GonkBufferQueueCore> mCore;
-
- // This references mCore->mSlots. Lock mCore->mMutex while accessing.
- GonkBufferQueueDefs::SlotsType& mSlots;
-
- // This is a cached copy of the name stored in the GonkBufferQueueCore.
- // It's updated during connect and dequeueBuffer (which should catch
- // most updates).
- String8 mConsumerName;
-
- // mSynchronousMode whether we're in synchronous mode or not
- bool mSynchronousMode;
-
- uint32_t mStickyTransform;
-
-}; // class GonkBufferQueueProducer
-
-} // namespace android
-
-#endif
diff --git a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferSlot.cpp b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferSlot.cpp
deleted file mode 100644
index 9e4a424a9..000000000
--- a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferSlot.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- * Copyright (C) 2014 Mozilla Foundation
- *
- * 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 "GonkBufferSlot.h"
-
-namespace android {
-
-const char* GonkBufferSlot::bufferStateName(BufferState state) {
- switch (state) {
- case GonkBufferSlot::DEQUEUED: return "DEQUEUED";
- case GonkBufferSlot::QUEUED: return "QUEUED";
- case GonkBufferSlot::FREE: return "FREE";
- case GonkBufferSlot::ACQUIRED: return "ACQUIRED";
- default: return "Unknown";
- }
-}
-
-} // namespace android
diff --git a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferSlot.h b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferSlot.h
deleted file mode 100644
index 759bb7b23..000000000
--- a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferSlot.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- * Copyright (C) 2014 Mozilla Foundation
- *
- * 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 NATIVEWINDOW_GONKBUFFERSLOT_LL_H
-#define NATIVEWINDOW_GONKBUFFERSLOT_LL_H
-
-#include <ui/Fence.h>
-#include <ui/GraphicBuffer.h>
-
-#include <utils/StrongPointer.h>
-
-#include "mozilla/layers/TextureClient.h"
-
-namespace android {
-
-struct GonkBufferSlot {
- typedef mozilla::layers::TextureClient TextureClient;
-
- GonkBufferSlot()
- : mBufferState(GonkBufferSlot::FREE),
- mRequestBufferCalled(false),
- mFrameNumber(0),
- mAcquireCalled(false),
- mNeedsCleanupOnRelease(false),
- mAttachedByConsumer(false) {
- }
-
- // mGraphicBuffer points to the buffer allocated for this slot or is NULL
- // if no buffer has been allocated.
- sp<GraphicBuffer> mGraphicBuffer;
-
- // 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
- };
-
- static const char* bufferStateName(BufferState state);
-
- // 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;
-
- // 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;
-
- // Indicates whether the buffer was attached on the consumer side.
- // If so, it needs to set the BUFFER_NEEDS_REALLOCATION flag when dequeued
- // to prevent the producer from using a stale cached buffer.
- bool mAttachedByConsumer;
-
- // mTextureClient is a thin abstraction over remotely allocated GraphicBuffer.
- RefPtr<TextureClient> mTextureClient;
-};
-
-} // namespace android
-
-#endif