summaryrefslogtreecommitdiff
path: root/libs/gui/BufferQueueConsumer.cpp
diff options
context:
space:
mode:
author Sungtak Lee <taklee@google.com> 2024-07-31 20:38:19 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2024-07-31 20:38:19 +0000
commit9d04fe2c66aff0fea66657f397827ed334ea3b7d (patch)
tree1df38cce0b78f36bfca239cf7ec76e1e228e1ebe /libs/gui/BufferQueueConsumer.cpp
parenta0bbe3d478017b3393e19e5020e41f24bbd9dcb4 (diff)
parent6d223cbd07f0582ac99e4b607f6983284638aa0b (diff)
Merge "Add IProducerListener::onBufferAttached" into main
Diffstat (limited to 'libs/gui/BufferQueueConsumer.cpp')
-rw-r--r--libs/gui/BufferQueueConsumer.cpp147
1 files changed, 82 insertions, 65 deletions
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
index 11f5174d76..69d25be006 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -42,6 +42,8 @@
#include <system/window.h>
+#include <com_android_graphics_libgui_flags.h>
+
namespace android {
// Macros for include BufferQueueCore information in log messages
@@ -370,79 +372,94 @@ status_t BufferQueueConsumer::attachBuffer(int* outSlot,
return BAD_VALUE;
}
- std::lock_guard<std::mutex> lock(mCore->mMutex);
+ sp<IProducerListener> listener;
+ {
+ std::lock_guard<std::mutex> lock(mCore->mMutex);
- if (mCore->mSharedBufferMode) {
- BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode");
- return BAD_VALUE;
- }
+ if (mCore->mSharedBufferMode) {
+ BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode");
+ return BAD_VALUE;
+ }
- // Make sure we don't have too many acquired buffers
- int numAcquiredBuffers = 0;
- for (int s : mCore->mActiveBuffers) {
- if (mSlots[s].mBufferState.isAcquired()) {
- ++numAcquiredBuffers;
+ // Make sure we don't have too many acquired buffers
+ int numAcquiredBuffers = 0;
+ for (int s : mCore->mActiveBuffers) {
+ if (mSlots[s].mBufferState.isAcquired()) {
+ ++numAcquiredBuffers;
+ }
}
- }
- if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
- BQ_LOGE("attachBuffer: max acquired buffer count reached: %d "
- "(max %d)", numAcquiredBuffers,
- mCore->mMaxAcquiredBufferCount);
- return INVALID_OPERATION;
- }
+ if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
+ BQ_LOGE("attachBuffer: max acquired buffer count reached: %d "
+ "(max %d)", numAcquiredBuffers,
+ mCore->mMaxAcquiredBufferCount);
+ return INVALID_OPERATION;
+ }
- if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
- BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
- "[queue %u]", buffer->getGenerationNumber(),
- mCore->mGenerationNumber);
- return BAD_VALUE;
- }
+ if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
+ BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
+ "[queue %u]", buffer->getGenerationNumber(),
+ mCore->mGenerationNumber);
+ return BAD_VALUE;
+ }
- // Find a free slot to put the buffer into
- int found = BufferQueueCore::INVALID_BUFFER_SLOT;
- if (!mCore->mFreeSlots.empty()) {
- auto slot = mCore->mFreeSlots.begin();
- found = *slot;
- mCore->mFreeSlots.erase(slot);
- } else if (!mCore->mFreeBuffers.empty()) {
- found = mCore->mFreeBuffers.front();
- mCore->mFreeBuffers.remove(found);
- }
- if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
- BQ_LOGE("attachBuffer: could not find free buffer slot");
- return NO_MEMORY;
+ // Find a free slot to put the buffer into
+ int found = BufferQueueCore::INVALID_BUFFER_SLOT;
+ if (!mCore->mFreeSlots.empty()) {
+ auto slot = mCore->mFreeSlots.begin();
+ found = *slot;
+ mCore->mFreeSlots.erase(slot);
+ } else if (!mCore->mFreeBuffers.empty()) {
+ found = mCore->mFreeBuffers.front();
+ mCore->mFreeBuffers.remove(found);
+ }
+ if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
+ BQ_LOGE("attachBuffer: could not find free buffer slot");
+ return NO_MEMORY;
+ }
+
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
+ if (mCore->mBufferAttachedCbEnabled) {
+ listener = mCore->mConnectedProducerListener;
+ }
+#endif
+
+ mCore->mActiveBuffers.insert(found);
+ *outSlot = found;
+ ATRACE_BUFFER_INDEX(*outSlot);
+ BQ_LOGV("attachBuffer: returning slot %d", *outSlot);
+
+ mSlots[*outSlot].mGraphicBuffer = buffer;
+ mSlots[*outSlot].mBufferState.attachConsumer();
+ mSlots[*outSlot].mNeedsReallocation = true;
+ mSlots[*outSlot].mFence = Fence::NO_FENCE;
+ mSlots[*outSlot].mFrameNumber = 0;
+
+ // mAcquireCalled tells BufferQueue 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;
+
+ VALIDATE_CONSISTENCY();
}
- mCore->mActiveBuffers.insert(found);
- *outSlot = found;
- ATRACE_BUFFER_INDEX(*outSlot);
- BQ_LOGV("attachBuffer: returning slot %d", *outSlot);
-
- mSlots[*outSlot].mGraphicBuffer = buffer;
- mSlots[*outSlot].mBufferState.attachConsumer();
- mSlots[*outSlot].mNeedsReallocation = true;
- mSlots[*outSlot].mFence = Fence::NO_FENCE;
- mSlots[*outSlot].mFrameNumber = 0;
-
- // mAcquireCalled tells BufferQueue 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;
-
- VALIDATE_CONSISTENCY();
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
+ if (listener != nullptr) {
+ listener->onBufferAttached();
+ }
+#endif
return NO_ERROR;
}