summaryrefslogtreecommitdiff
path: root/libs/gui/BLASTBufferQueue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/gui/BLASTBufferQueue.cpp')
-rw-r--r--libs/gui/BLASTBufferQueue.cpp96
1 files changed, 64 insertions, 32 deletions
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index e9149f3a3e..55703214a5 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -407,18 +407,9 @@ void BLASTBufferQueue::releaseBufferCallback(
// Release all buffers that are beyond the ones that we need to hold
while (mPendingRelease.size() > numPendingBuffersToHold) {
- const auto releaseBuffer = mPendingRelease.front();
+ const auto releasedBuffer = mPendingRelease.front();
mPendingRelease.pop_front();
- auto it = mSubmitted.find(releaseBuffer.callbackId);
- if (it == mSubmitted.end()) {
- BQA_LOGE("ERROR: releaseBufferCallback without corresponding submitted buffer %s",
- releaseBuffer.callbackId.to_string().c_str());
- return;
- }
- mNumAcquired--;
- BQA_LOGV("released %s", releaseBuffer.callbackId.to_string().c_str());
- mBufferItemConsumer->releaseBuffer(it->second, releaseBuffer.releaseFence);
- mSubmitted.erase(it);
+ releaseBuffer(releasedBuffer.callbackId, releasedBuffer.releaseFence);
// Don't process the transactions here if mWaitForTransactionCallback is set. Instead, let
// onFrameAvailable handle processing them since it will merge with the syncTransaction.
if (!mWaitForTransactionCallback) {
@@ -432,6 +423,20 @@ void BLASTBufferQueue::releaseBufferCallback(
mCallbackCV.notify_all();
}
+void BLASTBufferQueue::releaseBuffer(const ReleaseCallbackId& callbackId,
+ const sp<Fence>& releaseFence) {
+ auto it = mSubmitted.find(callbackId);
+ if (it == mSubmitted.end()) {
+ BQA_LOGE("ERROR: releaseBufferCallback without corresponding submitted buffer %s",
+ callbackId.to_string().c_str());
+ return;
+ }
+ mNumAcquired--;
+ BQA_LOGV("released %s", callbackId.to_string().c_str());
+ mBufferItemConsumer->releaseBuffer(it->second, releaseFence);
+ mSubmitted.erase(it);
+}
+
void BLASTBufferQueue::acquireNextBufferLocked(
const std::optional<SurfaceComposerClient::Transaction*> transaction) {
ATRACE_CALL();
@@ -589,34 +594,57 @@ void BLASTBufferQueue::acquireAndReleaseBuffer() {
mBufferItemConsumer->releaseBuffer(bufferItem, bufferItem.mFence);
}
+void BLASTBufferQueue::flushAndWaitForFreeBuffer(std::unique_lock<std::mutex>& lock) {
+ if (mWaitForTransactionCallback && mNumFrameAvailable > 0) {
+ // We are waiting on a previous sync's transaction callback so allow another sync
+ // transaction to proceed.
+ //
+ // We need to first flush out the transactions that were in between the two syncs.
+ // We do this by merging them into mSyncTransaction so any buffer merging will get
+ // a release callback invoked. The release callback will be async so we need to wait
+ // on max acquired to make sure we have the capacity to acquire another buffer.
+ if (maxBuffersAcquired(false /* includeExtraAcquire */)) {
+ BQA_LOGD("waiting to flush shadow queue...");
+ mCallbackCV.wait(lock);
+ }
+ while (mNumFrameAvailable > 0) {
+ // flush out the shadow queue
+ acquireAndReleaseBuffer();
+ }
+ }
+
+ while (maxBuffersAcquired(false /* includeExtraAcquire */)) {
+ BQA_LOGD("waiting for free buffer.");
+ mCallbackCV.wait(lock);
+ }
+}
+
void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) {
ATRACE_CALL();
std::unique_lock _lock{mMutex};
const bool syncTransactionSet = mSyncTransaction != nullptr;
BQA_LOGV("onFrameAvailable-start syncTransactionSet=%s", boolToString(syncTransactionSet));
+
if (syncTransactionSet) {
- if (mWaitForTransactionCallback) {
- // We are waiting on a previous sync's transaction callback so allow another sync
- // transaction to proceed.
- //
- // We need to first flush out the transactions that were in between the two syncs.
- // We do this by merging them into mSyncTransaction so any buffer merging will get
- // a release callback invoked. The release callback will be async so we need to wait
- // on max acquired to make sure we have the capacity to acquire another buffer.
- if (maxBuffersAcquired(false /* includeExtraAcquire */)) {
- BQA_LOGD("waiting to flush shadow queue...");
- mCallbackCV.wait(_lock);
- }
- while (mNumFrameAvailable > 0) {
- // flush out the shadow queue
- acquireAndReleaseBuffer();
+ bool mayNeedToWaitForBuffer = true;
+ // If we are going to re-use the same mSyncTransaction, release the buffer that may already
+ // be set in the Transaction. This is to allow us a free slot early to continue processing
+ // a new buffer.
+ if (!mAcquireSingleBuffer) {
+ auto bufferData = mSyncTransaction->getAndClearBuffer(mSurfaceControl);
+ if (bufferData) {
+ BQA_LOGD("Releasing previous buffer when syncing: framenumber=%" PRIu64,
+ bufferData->frameNumber);
+ releaseBuffer(bufferData->releaseCallbackId, bufferData->acquireFence);
+ // Because we just released a buffer, we know there's no need to wait for a free
+ // buffer.
+ mayNeedToWaitForBuffer = false;
}
}
- while (maxBuffersAcquired(false /* includeExtraAcquire */)) {
- BQA_LOGD("waiting for free buffer.");
- mCallbackCV.wait(_lock);
+ if (mayNeedToWaitForBuffer) {
+ flushAndWaitForFreeBuffer(_lock);
}
}
@@ -629,8 +657,10 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) {
boolToString(syncTransactionSet));
if (syncTransactionSet) {
- acquireNextBufferLocked(std::move(mSyncTransaction));
- mSyncTransaction = nullptr;
+ acquireNextBufferLocked(mSyncTransaction);
+ if (mAcquireSingleBuffer) {
+ mSyncTransaction = nullptr;
+ }
mWaitForTransactionCallback = true;
} else if (!mWaitForTransactionCallback) {
acquireNextBufferLocked(std::nullopt);
@@ -652,9 +682,11 @@ void BLASTBufferQueue::onFrameCancelled(const uint64_t bufferId) {
mDequeueTimestamps.erase(bufferId);
};
-void BLASTBufferQueue::setSyncTransaction(SurfaceComposerClient::Transaction* t) {
+void BLASTBufferQueue::setSyncTransaction(SurfaceComposerClient::Transaction* t,
+ bool acquireSingleBuffer) {
std::lock_guard _lock{mMutex};
mSyncTransaction = t;
+ mAcquireSingleBuffer = mSyncTransaction ? acquireSingleBuffer : true;
}
bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) {