summaryrefslogtreecommitdiffstats
path: root/libs/gui/BufferQueueCore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/gui/BufferQueueCore.cpp')
-rw-r--r--libs/gui/BufferQueueCore.cpp60
1 files changed, 59 insertions, 1 deletions
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index edebc45..29415c9 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -53,6 +53,8 @@ BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) :
mConnectedProducerListener(),
mSlots(),
mQueue(),
+ mFreeSlots(),
+ mFreeBuffers(),
mOverrideMaxBufferCount(0),
mDequeueCondition(),
mUseAsyncBuffer(true),
@@ -76,6 +78,9 @@ BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) :
BQ_LOGE("createGraphicBufferAlloc failed");
}
}
+ for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) {
+ mFreeSlots.insert(slot);
+ }
}
BufferQueueCore::~BufferQueueCore() {}
@@ -190,12 +195,20 @@ status_t BufferQueueCore::setDefaultMaxBufferCountLocked(int count) {
void BufferQueueCore::freeBufferLocked(int slot) {
BQ_LOGV("freeBufferLocked: slot %d", slot);
+ bool hadBuffer = mSlots[slot].mGraphicBuffer != NULL;
mSlots[slot].mGraphicBuffer.clear();
if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) {
mSlots[slot].mNeedsCleanupOnRelease = true;
}
+ if (mSlots[slot].mBufferState != BufferSlot::FREE) {
+ mFreeSlots.insert(slot);
+ } else if (hadBuffer) {
+ // If the slot was FREE, but we had a buffer, we need to move this slot
+ // from the free buffers list to the the free slots list
+ mFreeBuffers.remove(slot);
+ mFreeSlots.insert(slot);
+ }
mSlots[slot].mBufferState = BufferSlot::FREE;
- mSlots[slot].mFrameNumber = UINT32_MAX;
mSlots[slot].mAcquireCalled = false;
// Destroy fence as BufferQueue now takes ownership
@@ -204,6 +217,7 @@ void BufferQueueCore::freeBufferLocked(int slot) {
mSlots[slot].mEglFence = EGL_NO_SYNC_KHR;
}
mSlots[slot].mFence = Fence::NO_FENCE;
+ validateConsistencyLocked();
}
void BufferQueueCore::freeAllBuffersLocked() {
@@ -236,4 +250,48 @@ void BufferQueueCore::waitWhileAllocatingLocked() const {
}
}
+void BufferQueueCore::validateConsistencyLocked() const {
+ static const useconds_t PAUSE_TIME = 0;
+ for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) {
+ bool isInFreeSlots = mFreeSlots.count(slot) != 0;
+ bool isInFreeBuffers =
+ std::find(mFreeBuffers.cbegin(), mFreeBuffers.cend(), slot) !=
+ mFreeBuffers.cend();
+ if (mSlots[slot].mBufferState == BufferSlot::FREE) {
+ if (mSlots[slot].mGraphicBuffer == NULL) {
+ if (!isInFreeSlots) {
+ BQ_LOGE("Slot %d is FREE but is not in mFreeSlots", slot);
+ usleep(PAUSE_TIME);
+ }
+ if (isInFreeBuffers) {
+ BQ_LOGE("Slot %d is in mFreeSlots "
+ "but is also in mFreeBuffers", slot);
+ usleep(PAUSE_TIME);
+ }
+ } else {
+ if (!isInFreeBuffers) {
+ BQ_LOGE("Slot %d is FREE but is not in mFreeBuffers", slot);
+ usleep(PAUSE_TIME);
+ }
+ if (isInFreeSlots) {
+ BQ_LOGE("Slot %d is in mFreeBuffers "
+ "but is also in mFreeSlots", slot);
+ usleep(PAUSE_TIME);
+ }
+ }
+ } else {
+ if (isInFreeSlots) {
+ BQ_LOGE("Slot %d is in mFreeSlots but is not FREE (%d)",
+ slot, mSlots[slot].mBufferState);
+ usleep(PAUSE_TIME);
+ }
+ if (isInFreeBuffers) {
+ BQ_LOGE("Slot %d is in mFreeBuffers but is not FREE (%d)",
+ slot, mSlots[slot].mBufferState);
+ usleep(PAUSE_TIME);
+ }
+ }
+ }
+}
+
} // namespace android