diff options
| author | 2021-11-09 03:45:53 +0000 | |
|---|---|---|
| committer | 2021-11-09 03:45:53 +0000 | |
| commit | dbf7eef33365e918db5909e6cdde0a8bbdcdb208 (patch) | |
| tree | b84511d94f84ba04eb4bdba07eaf864180a16c06 /libs/gui/BLASTBufferQueue.cpp | |
| parent | c9963a2d6e1b8751541fa395115311bd50b90b87 (diff) | |
| parent | 9051fb1885df913eecfa9072155797bdaf05d278 (diff) | |
Merge "BBQ: Clean up acquire states on BQ disconnect"
Diffstat (limited to 'libs/gui/BLASTBufferQueue.cpp')
| -rw-r--r-- | libs/gui/BLASTBufferQueue.cpp | 73 |
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 |