summaryrefslogtreecommitdiff
path: root/libs/gui/ConsumerBase.cpp
diff options
context:
space:
mode:
author Lajos Molnar <lajos@google.com> 2013-05-03 14:50:50 -0700
committer Android (Google) Code Review <android-gerrit@google.com> 2013-05-23 22:17:54 +0000
commitc5d7b7d323bba8772a9005f7d300ad983a04733a (patch)
tree07479c25735c0bbaccd497db21a90a87c3926242 /libs/gui/ConsumerBase.cpp
parentd837969640efbc97eda2034c7811dda807d4174f (diff)
BufferQueue: track buffer-queue by instance vs. by reference
Instead of representing the buffer-queue as a vector of buffer indices, represent them as a vector of BufferItems (copies). This allows modifying the buffer slots independent of the queued buffers. As part of this change, BufferSlot properties that are only been relevant in the buffer-queue have been removed. Also, invalid scalingMode in queueBuffer now returns an error. ConsumerBase has also changed to allow reuse of the same buffer slots by different buffers. Change-Id: If2a698fa142b67c69ad41b8eaca6e127eb3ef75b Signed-off-by: Lajos Molnar <lajos@google.com> Related-to-bug: 7093648
Diffstat (limited to 'libs/gui/ConsumerBase.cpp')
-rw-r--r--libs/gui/ConsumerBase.cpp47
1 files changed, 38 insertions, 9 deletions
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index 8d911c9eaf..fd9d15365b 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -95,6 +95,7 @@ void ConsumerBase::freeBufferLocked(int slotIndex) {
CB_LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
mSlots[slotIndex].mGraphicBuffer = 0;
mSlots[slotIndex].mFence = Fence::NO_FENCE;
+ mSlots[slotIndex].mFrameNumber = 0;
}
// Used for refactoring, should not be in final interface
@@ -191,21 +192,31 @@ status_t ConsumerBase::acquireBufferLocked(BufferQueue::BufferItem *item) {
mSlots[item->mBuf].mGraphicBuffer = item->mGraphicBuffer;
}
+ mSlots[item->mBuf].mFrameNumber = item->mFrameNumber;
mSlots[item->mBuf].mFence = item->mFence;
- CB_LOGV("acquireBufferLocked: -> slot=%d", item->mBuf);
+ CB_LOGV("acquireBufferLocked: -> slot=%d/%llu",
+ item->mBuf, item->mFrameNumber);
return OK;
}
-status_t ConsumerBase::addReleaseFence(int slot, const sp<Fence>& fence) {
+status_t ConsumerBase::addReleaseFence(int slot,
+ const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence) {
Mutex::Autolock lock(mMutex);
- return addReleaseFenceLocked(slot, fence);
+ return addReleaseFenceLocked(slot, graphicBuffer, fence);
}
-status_t ConsumerBase::addReleaseFenceLocked(int slot, const sp<Fence>& fence) {
+status_t ConsumerBase::addReleaseFenceLocked(int slot,
+ const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence) {
CB_LOGV("addReleaseFenceLocked: slot=%d", slot);
+ // If consumer no longer tracks this graphicBuffer, we can safely
+ // drop this fence, as it will never be received by the producer.
+ if (!stillTracking(slot, graphicBuffer)) {
+ return OK;
+ }
+
if (!mSlots[slot].mFence.get()) {
mSlots[slot].mFence = fence;
} else {
@@ -225,11 +236,20 @@ status_t ConsumerBase::addReleaseFenceLocked(int slot, const sp<Fence>& fence) {
return OK;
}
-status_t ConsumerBase::releaseBufferLocked(int slot, EGLDisplay display,
- EGLSyncKHR eglFence) {
- CB_LOGV("releaseBufferLocked: slot=%d", slot);
- status_t err = mBufferQueue->releaseBuffer(slot, display, eglFence,
- mSlots[slot].mFence);
+status_t ConsumerBase::releaseBufferLocked(
+ int slot, const sp<GraphicBuffer> graphicBuffer,
+ EGLDisplay display, EGLSyncKHR eglFence) {
+ // If consumer no longer tracks this graphicBuffer (we received a new
+ // buffer on the same slot), the buffer producer is definitely no longer
+ // tracking it.
+ if (!stillTracking(slot, graphicBuffer)) {
+ return OK;
+ }
+
+ CB_LOGV("releaseBufferLocked: slot=%d/%llu",
+ slot, mSlots[slot].mFrameNumber);
+ status_t err = mBufferQueue->releaseBuffer(slot, mSlots[slot].mFrameNumber,
+ display, eglFence, mSlots[slot].mFence);
if (err == BufferQueue::STALE_BUFFER_SLOT) {
freeBufferLocked(slot);
}
@@ -239,4 +259,13 @@ status_t ConsumerBase::releaseBufferLocked(int slot, EGLDisplay display,
return err;
}
+bool ConsumerBase::stillTracking(int slot,
+ const sp<GraphicBuffer> graphicBuffer) {
+ if (slot < 0 || slot >= BufferQueue::NUM_BUFFER_SLOTS) {
+ return false;
+ }
+ return (mSlots[slot].mGraphicBuffer != NULL &&
+ mSlots[slot].mGraphicBuffer->handle == graphicBuffer->handle);
+}
+
} // namespace android