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.cpp139
1 files changed, 87 insertions, 52 deletions
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index b7a7aa0ccb..8e23eb8766 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -137,6 +137,7 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinati
mSize(1, 1),
mRequestedSize(mSize),
mFormat(PIXEL_FORMAT_RGBA_8888),
+ mTransactionReadyCallback(nullptr),
mSyncTransaction(nullptr),
mUpdateDestinationFrame(updateDestinationFrame) {
createBufferQueue(&mProducer, &mConsumer);
@@ -608,60 +609,69 @@ void BLASTBufferQueue::flushAndWaitForFreeBuffer(std::unique_lock<std::mutex>& l
}
void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) {
- BBQ_TRACE();
- std::unique_lock _lock{mMutex};
+ std::function<void(SurfaceComposerClient::Transaction*)> prevCallback = nullptr;
+ SurfaceComposerClient::Transaction* prevTransaction = nullptr;
+ {
+ BBQ_TRACE();
+ std::unique_lock _lock{mMutex};
+ const bool syncTransactionSet = mTransactionReadyCallback != nullptr;
+ BQA_LOGV("onFrameAvailable-start syncTransactionSet=%s", boolToString(syncTransactionSet));
+
+ if (syncTransactionSet) {
+ 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->generateReleaseCallbackId(),
+ bufferData->acquireFence);
+ // Because we just released a buffer, we know there's no need to wait for a free
+ // buffer.
+ mayNeedToWaitForBuffer = false;
+ }
+ }
- const bool syncTransactionSet = mSyncTransaction != nullptr;
- BQA_LOGV("onFrameAvailable-start syncTransactionSet=%s", boolToString(syncTransactionSet));
-
- if (syncTransactionSet) {
- 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->generateReleaseCallbackId(), bufferData->acquireFence);
- // Because we just released a buffer, we know there's no need to wait for a free
- // buffer.
- mayNeedToWaitForBuffer = false;
+ if (mayNeedToWaitForBuffer) {
+ flushAndWaitForFreeBuffer(_lock);
}
}
- if (mayNeedToWaitForBuffer) {
- flushAndWaitForFreeBuffer(_lock);
+ // add to shadow queue
+ mNumFrameAvailable++;
+ if (mWaitForTransactionCallback && mNumFrameAvailable >= 2) {
+ acquireAndReleaseBuffer();
}
- }
-
- // add to shadow queue
- mNumFrameAvailable++;
- if (mWaitForTransactionCallback && mNumFrameAvailable >= 2) {
- acquireAndReleaseBuffer();
- }
- ATRACE_INT(mQueuedBufferTrace.c_str(),
- mNumFrameAvailable + mNumAcquired - mPendingRelease.size());
-
- BQA_LOGV("onFrameAvailable framenumber=%" PRIu64 " syncTransactionSet=%s", item.mFrameNumber,
- boolToString(syncTransactionSet));
-
- if (syncTransactionSet) {
- acquireNextBufferLocked(mSyncTransaction);
-
- // Only need a commit callback when syncing to ensure the buffer that's synced has been sent
- // to SF
- incStrong((void*)transactionCommittedCallbackThunk);
- mSyncTransaction->addTransactionCommittedCallback(transactionCommittedCallbackThunk,
- static_cast<void*>(this));
-
- if (mAcquireSingleBuffer) {
- mSyncTransaction = nullptr;
+ ATRACE_INT(mQueuedBufferTrace.c_str(),
+ mNumFrameAvailable + mNumAcquired - mPendingRelease.size());
+
+ BQA_LOGV("onFrameAvailable framenumber=%" PRIu64 " syncTransactionSet=%s",
+ item.mFrameNumber, boolToString(syncTransactionSet));
+
+ if (syncTransactionSet) {
+ acquireNextBufferLocked(mSyncTransaction);
+
+ // Only need a commit callback when syncing to ensure the buffer that's synced has been
+ // sent to SF
+ incStrong((void*)transactionCommittedCallbackThunk);
+ mSyncTransaction->addTransactionCommittedCallback(transactionCommittedCallbackThunk,
+ static_cast<void*>(this));
+ mWaitForTransactionCallback = true;
+ if (mAcquireSingleBuffer) {
+ prevCallback = mTransactionReadyCallback;
+ prevTransaction = mSyncTransaction;
+ mTransactionReadyCallback = nullptr;
+ mSyncTransaction = nullptr;
+ }
+ } else if (!mWaitForTransactionCallback) {
+ acquireNextBufferLocked(std::nullopt);
}
- mWaitForTransactionCallback = true;
- } else if (!mWaitForTransactionCallback) {
- acquireNextBufferLocked(std::nullopt);
+ }
+ if (prevCallback) {
+ prevCallback(prevTransaction);
}
}
@@ -680,12 +690,37 @@ void BLASTBufferQueue::onFrameCancelled(const uint64_t bufferId) {
mDequeueTimestamps.erase(bufferId);
};
-void BLASTBufferQueue::setSyncTransaction(SurfaceComposerClient::Transaction* t,
- bool acquireSingleBuffer) {
+void BLASTBufferQueue::syncNextTransaction(
+ std::function<void(SurfaceComposerClient::Transaction*)> callback,
+ bool acquireSingleBuffer) {
BBQ_TRACE();
std::lock_guard _lock{mMutex};
- mSyncTransaction = t;
- mAcquireSingleBuffer = mSyncTransaction ? acquireSingleBuffer : true;
+ mTransactionReadyCallback = callback;
+ if (callback) {
+ mSyncTransaction = new SurfaceComposerClient::Transaction();
+ } else {
+ mSyncTransaction = nullptr;
+ }
+ mAcquireSingleBuffer = mTransactionReadyCallback ? acquireSingleBuffer : true;
+}
+
+void BLASTBufferQueue::stopContinuousSyncTransaction() {
+ std::function<void(SurfaceComposerClient::Transaction*)> prevCallback = nullptr;
+ SurfaceComposerClient::Transaction* prevTransaction = nullptr;
+ {
+ std::lock_guard _lock{mMutex};
+ bool invokeCallback = mTransactionReadyCallback && !mAcquireSingleBuffer;
+ if (invokeCallback) {
+ prevCallback = mTransactionReadyCallback;
+ prevTransaction = mSyncTransaction;
+ }
+ mTransactionReadyCallback = nullptr;
+ mSyncTransaction = nullptr;
+ mAcquireSingleBuffer = true;
+ }
+ if (prevCallback) {
+ prevCallback(prevTransaction);
+ }
}
bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) {