summaryrefslogtreecommitdiff
path: root/libs/gui/BLASTBufferQueue.cpp
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2021-11-09 03:45:53 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-11-09 03:45:53 +0000
commitdbf7eef33365e918db5909e6cdde0a8bbdcdb208 (patch)
treeb84511d94f84ba04eb4bdba07eaf864180a16c06 /libs/gui/BLASTBufferQueue.cpp
parentc9963a2d6e1b8751541fa395115311bd50b90b87 (diff)
parent9051fb1885df913eecfa9072155797bdaf05d278 (diff)
Merge "BBQ: Clean up acquire states on BQ disconnect"
Diffstat (limited to 'libs/gui/BLASTBufferQueue.cpp')
-rw-r--r--libs/gui/BLASTBufferQueue.cpp73
1 files changed, 66 insertions, 7 deletions
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 9080822f92..9cb7c88956 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -58,13 +58,22 @@ namespace android {
ALOGE("[%s](f:%u,a:%u) " x, mName.c_str(), mNumFrameAvailable, mNumAcquired, ##__VA_ARGS__)
void BLASTBufferItemConsumer::onDisconnect() {
- Mutex::Autolock lock(mMutex);
- mPreviouslyConnected = mCurrentlyConnected;
- mCurrentlyConnected = false;
- if (mPreviouslyConnected) {
- mDisconnectEvents.push(mCurrentFrameNumber);
+ {
+ Mutex::Autolock lock(mMutex);
+ mPreviouslyConnected = mCurrentlyConnected;
+ mCurrentlyConnected = false;
+ if (mPreviouslyConnected) {
+ mDisconnectEvents.push(mCurrentFrameNumber);
+ }
+ mFrameEventHistory.onDisconnect();
+ }
+
+ {
+ std::scoped_lock lock(mBufferQueueMutex);
+ if (mBLASTBufferQueue != nullptr) {
+ mBLASTBufferQueue->onProducerDisconnect();
+ }
}
- mFrameEventHistory.onDisconnect();
}
void BLASTBufferItemConsumer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps,
@@ -202,7 +211,11 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width,
}
SurfaceComposerClient::Transaction t;
- const bool setBackpressureFlag = !SurfaceControl::isSameSurface(mSurfaceControl, surface);
+ bool setBackpressureFlag = false;
+ if (!SurfaceControl::isSameSurface(mSurfaceControl, surface)) {
+ mSurfaceControlSwapCount++;
+ setBackpressureFlag = true;
+ }
bool applyTransaction = false;
// Always update the native object even though they might have the same layer handle, so we can
@@ -388,6 +401,19 @@ void BLASTBufferQueue::releaseBufferCallback(
std::unique_lock _lock{mMutex};
BQA_LOGV("releaseBufferCallback %s", id.to_string().c_str());
+ const auto it = mFreedBuffers.find(id);
+ if (it != mFreedBuffers.end()) {
+ mFreedBuffers.erase(it);
+ BQA_LOGV("releaseBufferCallback ignoring freed buffer %s", id.to_string().c_str());
+ return;
+ }
+
+ if (mFreedBuffers.size() != 0 && mLogMissingReleaseCallback) {
+ BQA_LOGD("Unexpected out of order buffer release. mFreedBuffer count=%d",
+ static_cast<uint32_t>(mFreedBuffers.size()));
+ mLogMissingReleaseCallback = false;
+ }
+
// Calculate how many buffers we need to hold before we release them back
// to the buffer queue. This will prevent higher latency when we are running
// on a lower refresh rate than the max supported. We only do that for EGL
@@ -593,6 +619,12 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) {
ATRACE_CALL();
std::unique_lock _lock{mMutex};
+ if ((mSurfaceControlSwapCount > mProducerDisconnectCount) && mLogScSwap) {
+ BQA_LOGD("Expected producer disconnect sc swap count=%d bq disconnect count=%d",
+ mSurfaceControlSwapCount, mProducerDisconnectCount);
+ mLogScSwap = false;
+ }
+
const bool nextTransactionSet = mNextTransaction != nullptr;
BQA_LOGV("onFrameAvailable-start nextTransactionSet=%s", boolToString(nextTransactionSet));
if (nextTransactionSet) {
@@ -959,4 +991,31 @@ uint64_t BLASTBufferQueue::getLastAcquiredFrameNum() {
return mLastAcquiredFrameNumber;
}
+// When the producer disconnects, all buffers in the queue will be freed. So clean up the bbq
+// acquire state and handle any pending release callbacks. If we do get a release callback for a
+// pending buffer for a disconnected queue, we cannot release the buffer back to the queue. So track
+// these separately and drop the release callbacks as they come.
+
+// Transaction callbacks are still expected to come in the order they were submitted regardless of
+// buffer queue state. So we can continue to handles the pending transactions and transaction
+// complete callbacks. When the queue is reconnected, the queue will increment the framenumbers
+// starting from the last queued framenumber.
+void BLASTBufferQueue::onProducerDisconnect() {
+ BQA_LOGV("onProducerDisconnect");
+ std::scoped_lock _lock{mMutex};
+ // reset counts since the queue has been disconnected and all buffers have been freed.
+ mNumFrameAvailable = 0;
+ mNumAcquired = 0;
+
+ // Track submitted buffers in a different container so we can handle any pending release buffer
+ // callbacks without affecting the BBQ acquire state.
+ mFreedBuffers.insert(mSubmitted.begin(), mSubmitted.end());
+ mSubmitted.clear();
+ mPendingRelease.clear();
+ mProducerDisconnectCount++;
+ mCallbackCV.notify_all();
+ mLogMissingReleaseCallback = true;
+ mLogScSwap = true;
+}
+
} // namespace android