summaryrefslogtreecommitdiff
path: root/libs/gui/BLASTBufferQueue.cpp
diff options
context:
space:
mode:
author Patrick Williams <pdwilliams@google.com> 2024-08-01 16:08:51 -0500
committer Patrick Williams <pdwilliams@google.com> 2024-08-06 09:58:03 -0500
commitf5b42de949b928d5b08854a592c2af0600bbca7b (patch)
treeceb1bcfa2c14ca610e212506787d2d2d00e28515 /libs/gui/BLASTBufferQueue.cpp
parentfd0e14cbaa6140b47bb390b3d00bad1fc733b2a6 (diff)
Track BBQ dequeue count and mode
Counts, shared buffer mode, and async mode will be used to determine when dequeueBuffer should block. Bug: 294133380 Flag: com.android.graphics.libgui.flags.buffer_release_channel Test: BLASTBufferQueueTest Change-Id: I23cd5606f84ac5e0c29c470d05b28153fc4c9ce8
Diffstat (limited to 'libs/gui/BLASTBufferQueue.cpp')
-rw-r--r--libs/gui/BLASTBufferQueue.cpp173
1 files changed, 153 insertions, 20 deletions
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 739c3c2a41..7f0e80e0f0 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -39,7 +39,6 @@
#include <private/gui/ComposerServiceAIDL.h>
#include <android-base/thread_annotations.h>
-#include <chrono>
#include <com_android_graphics_libgui_flags.h>
@@ -179,8 +178,6 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinati
// explicitly so that dequeueBuffer will block
mProducer->setDequeueTimeout(std::numeric_limits<int64_t>::max());
- // safe default, most producers are expected to override this
- mProducer->setMaxDequeuedBufferCount(2);
mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer,
GraphicBuffer::USAGE_HW_COMPOSER |
GraphicBuffer::USAGE_HW_TEXTURE,
@@ -236,6 +233,11 @@ BLASTBufferQueue::~BLASTBufferQueue() {
}
}
+void BLASTBufferQueue::onFirstRef() {
+ // safe default, most producers are expected to override this
+ mProducer->setMaxDequeuedBufferCount(2);
+}
+
void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height,
int32_t format) {
LOG_ALWAYS_FATAL_IF(surface == nullptr, "BLASTBufferQueue: mSurfaceControl must not be NULL");
@@ -499,7 +501,13 @@ void BLASTBufferQueue::releaseBuffer(const ReleaseCallbackId& callbackId,
callbackId.to_string().c_str());
return;
}
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
+ if (!it->second.mIsStale) {
+ mNumAcquired--;
+ }
+#else
mNumAcquired--;
+#endif
BBQ_TRACE("frame=%" PRIu64, callbackId.framenumber);
BQA_LOGV("released %s", callbackId.to_string().c_str());
mBufferItemConsumer->releaseBuffer(it->second, releaseFence);
@@ -761,6 +769,9 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) {
}
// add to shadow queue
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
+ mNumDequeued--;
+#endif
mNumFrameAvailable++;
if (waitForTransactionCallback && mNumFrameAvailable >= 2) {
acquireAndReleaseBuffer();
@@ -815,9 +826,18 @@ void BLASTBufferQueue::onFrameDequeued(const uint64_t bufferId) {
};
void BLASTBufferQueue::onFrameCancelled(const uint64_t bufferId) {
- std::lock_guard _lock{mTimestampMutex};
- mDequeueTimestamps.erase(bufferId);
-};
+ {
+ std::lock_guard _lock{mTimestampMutex};
+ mDequeueTimestamps.erase(bufferId);
+ }
+
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
+ {
+ std::lock_guard lock{mMutex};
+ mNumDequeued--;
+ }
+#endif
+}
bool BLASTBufferQueue::syncNextTransaction(
std::function<void(SurfaceComposerClient::Transaction*)> callback,
@@ -1116,30 +1136,143 @@ public:
producerControlledByApp, output);
}
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
+ status_t disconnect(int api, DisconnectMode mode) override {
+ sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
+ if (!bbq) {
+ return BufferQueueProducer::disconnect(api, mode);
+ }
+
+ std::lock_guard lock{bbq->mMutex};
+ if (status_t status = BufferQueueProducer::disconnect(api, mode); status != OK) {
+ return status;
+ }
+
+ bbq->mNumDequeued = 0;
+ bbq->mNumAcquired = 0;
+ for (auto& [releaseId, bufferItem] : bbq->mSubmitted) {
+ bufferItem.mIsStale = true;
+ }
+
+ return OK;
+ }
+
+ status_t setAsyncMode(bool asyncMode) override {
+ if (status_t status = BufferQueueProducer::setAsyncMode(asyncMode); status != OK) {
+ return status;
+ }
+
+ sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
+ if (!bbq) {
+ return OK;
+ }
+
+ {
+ std::lock_guard lock{bbq->mMutex};
+ bbq->mAsyncMode = asyncMode;
+ }
+
+ return OK;
+ }
+
+ status_t setSharedBufferMode(bool sharedBufferMode) override {
+ if (status_t status = BufferQueueProducer::setSharedBufferMode(sharedBufferMode);
+ status != OK) {
+ return status;
+ }
+
+ sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
+ if (!bbq) {
+ return OK;
+ }
+
+ {
+ std::lock_guard lock{bbq->mMutex};
+ bbq->mSharedBufferMode = sharedBufferMode;
+ }
+
+ return OK;
+ }
+
+ status_t detachBuffer(int slot) override {
+ if (status_t status = BufferQueueProducer::detachBuffer(slot); status != OK) {
+ return status;
+ }
+
+ sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
+ if (!bbq) {
+ return OK;
+ }
+
+ {
+ std::lock_guard lock{bbq->mMutex};
+ bbq->mNumDequeued--;
+ }
+
+ return OK;
+ }
+
+ status_t dequeueBuffer(int* outSlot, sp<Fence>* outFence, uint32_t width, uint32_t height,
+ PixelFormat format, uint64_t usage, uint64_t* outBufferAge,
+ FrameEventHistoryDelta* outTimestamps) override {
+ sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
+ if (!bbq) {
+ return BufferQueueProducer::dequeueBuffer(outSlot, outFence, width, height, format,
+ usage, outBufferAge, outTimestamps);
+ }
+
+ {
+ std::lock_guard lock{bbq->mMutex};
+ bbq->mNumDequeued++;
+ }
+
+ status_t status =
+ BufferQueueProducer::dequeueBuffer(outSlot, outFence, width, height, format, usage,
+ outBufferAge, outTimestamps);
+ if (status < 0) {
+ std::lock_guard lock{bbq->mMutex};
+ bbq->mNumDequeued--;
+ }
+ return status;
+ }
+#endif
+
// We want to resize the frame history when changing the size of the buffer queue
status_t setMaxDequeuedBufferCount(int maxDequeuedBufferCount) override {
int maxBufferCount;
- status_t status = BufferQueueProducer::setMaxDequeuedBufferCount(maxDequeuedBufferCount,
- &maxBufferCount);
+ if (status_t status = BufferQueueProducer::setMaxDequeuedBufferCount(maxDequeuedBufferCount,
+ &maxBufferCount);
+ status != OK) {
+ return status;
+ }
+
+ sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
+ if (!bbq) {
+ return OK;
+ }
+
// if we can't determine the max buffer count, then just skip growing the history size
- if (status == OK) {
- size_t newFrameHistorySize = maxBufferCount + 2; // +2 because triple buffer rendering
- // optimize away resizing the frame history unless it will grow
- if (newFrameHistorySize > FrameEventHistory::INITIAL_MAX_FRAME_HISTORY) {
- sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
- if (bbq != nullptr) {
- ALOGV("increasing frame history size to %zu", newFrameHistorySize);
- bbq->resizeFrameEventHistory(newFrameHistorySize);
- }
- }
+ size_t newFrameHistorySize = maxBufferCount + 2; // +2 because triple buffer rendering
+ // optimize away resizing the frame history unless it will grow
+ if (newFrameHistorySize > FrameEventHistory::INITIAL_MAX_FRAME_HISTORY) {
+ ALOGV("increasing frame history size to %zu", newFrameHistorySize);
+ bbq->resizeFrameEventHistory(newFrameHistorySize);
}
- return status;
+
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
+ {
+ std::lock_guard lock{bbq->mMutex};
+ bbq->mMaxDequeuedBuffers = maxDequeuedBufferCount;
+ }
+#endif
+
+ return OK;
}
int query(int what, int* value) override {
if (what == NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER) {
*value = 1;
- return NO_ERROR;
+ return OK;
}
return BufferQueueProducer::query(what, value);
}