Loading libs/gui/BLASTBufferQueue.cpp +42 −2 Original line number Diff line number Diff line Loading @@ -151,6 +151,19 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceCont mPendingReleaseItem.releaseFence = nullptr; } BLASTBufferQueue::~BLASTBufferQueue() { if (mPendingTransactions.empty()) { return; } BQA_LOGE("Applying pending transactions on dtor %d", static_cast<uint32_t>(mPendingTransactions.size())); SurfaceComposerClient::Transaction t; for (auto& [targetFrameNumber, transaction] : mPendingTransactions) { t.merge(std::move(transaction)); } t.apply(); } void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height) { std::unique_lock _lock{mMutex}; mSurfaceControl = surface; Loading Loading @@ -312,6 +325,7 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { incStrong((void*)transactionCallbackThunk); mLastBufferScalingMode = bufferItem.mScalingMode; mLastAcquiredFrameNumber = bufferItem.mFrameNumber; t->setBuffer(mSurfaceControl, buffer); t->setDataspace(mSurfaceControl, static_cast<ui::Dataspace>(bufferItem.mDataSpace)); Loading Loading @@ -341,14 +355,29 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { mAutoRefresh = bufferItem.mAutoRefresh; } auto mergeTransaction = [&t, currentFrameNumber = bufferItem.mFrameNumber]( std::tuple<uint64_t, SurfaceComposerClient::Transaction> pendingTransaction) { auto& [targetFrameNumber, transaction] = pendingTransaction; if (currentFrameNumber < targetFrameNumber) { return false; } t->merge(std::move(transaction)); return true; }; mPendingTransactions.erase(std::remove_if(mPendingTransactions.begin(), mPendingTransactions.end(), mergeTransaction), mPendingTransactions.end()); if (applyTransaction) { t->apply(); } BQA_LOGV("processNextBufferLocked size=%dx%d mFrameNumber=%" PRIu64 " applyTransaction=%s mTimestamp=%" PRId64, " applyTransaction=%s mTimestamp=%" PRId64 " mPendingTransactions.size=%d", mSize.width, mSize.height, bufferItem.mFrameNumber, toString(applyTransaction), bufferItem.mTimestamp); bufferItem.mTimestamp, static_cast<uint32_t>(mPendingTransactions.size())); } Rect BLASTBufferQueue::computeCrop(const BufferItem& item) { Loading Loading @@ -487,6 +516,17 @@ sp<Surface> BLASTBufferQueue::getSurface(bool includeSurfaceControlHandle) { return new BBQSurface(mProducer, true, scHandle, this); } void BLASTBufferQueue::mergeWithNextTransaction(SurfaceComposerClient::Transaction* t, uint64_t frameNumber) { std::lock_guard _lock{mMutex}; if (mLastAcquiredFrameNumber >= frameNumber) { // Apply the transaction since we have already acquired the desired frame. t->apply(); } else { mPendingTransactions.emplace_back(frameNumber, std::move(*t)); } } // Maintains a single worker thread per process that services a list of runnables. class AsyncWorker : public Singleton<AsyncWorker> { private: Loading libs/gui/include/gui/BLASTBufferQueue.h +8 −1 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ public: void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence, const std::vector<SurfaceControlStats>& stats); void setNextTransaction(SurfaceComposerClient::Transaction *t); void mergeWithNextTransaction(SurfaceComposerClient::Transaction* t, uint64_t frameNumber); void setTransactionCompleteCallback(uint64_t frameNumber, std::function<void(int64_t)>&& transactionCompleteCallback); Loading @@ -91,7 +92,7 @@ public: status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless); status_t setFrameTimelineVsync(int64_t frameTimelineVsyncId); virtual ~BLASTBufferQueue() = default; virtual ~BLASTBufferQueue(); private: friend class BLASTBufferQueueHelper; Loading Loading @@ -141,6 +142,9 @@ private: sp<BLASTBufferItemConsumer> mBufferItemConsumer; SurfaceComposerClient::Transaction* mNextTransaction GUARDED_BY(mMutex); std::vector<std::tuple<uint64_t /* framenumber */, SurfaceComposerClient::Transaction>> mPendingTransactions GUARDED_BY(mMutex); // If set to true, the next queue buffer will wait until the shadow queue has been processed by // the adapter. bool mFlushShadowQueue = false; Loading @@ -156,6 +160,9 @@ private: // where the layer can change sizes and the buffer will scale to fit the new size. uint32_t mLastBufferScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW; // Tracks the last acquired frame number uint64_t mLastAcquiredFrameNumber GUARDED_BY(mMutex) = 0; std::function<void(int64_t)> mTransactionCompleteCallback GUARDED_BY(mMutex) = nullptr; uint64_t mTransactionCompleteFrameNumber GUARDED_BY(mMutex){0}; }; Loading Loading
libs/gui/BLASTBufferQueue.cpp +42 −2 Original line number Diff line number Diff line Loading @@ -151,6 +151,19 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceCont mPendingReleaseItem.releaseFence = nullptr; } BLASTBufferQueue::~BLASTBufferQueue() { if (mPendingTransactions.empty()) { return; } BQA_LOGE("Applying pending transactions on dtor %d", static_cast<uint32_t>(mPendingTransactions.size())); SurfaceComposerClient::Transaction t; for (auto& [targetFrameNumber, transaction] : mPendingTransactions) { t.merge(std::move(transaction)); } t.apply(); } void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height) { std::unique_lock _lock{mMutex}; mSurfaceControl = surface; Loading Loading @@ -312,6 +325,7 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { incStrong((void*)transactionCallbackThunk); mLastBufferScalingMode = bufferItem.mScalingMode; mLastAcquiredFrameNumber = bufferItem.mFrameNumber; t->setBuffer(mSurfaceControl, buffer); t->setDataspace(mSurfaceControl, static_cast<ui::Dataspace>(bufferItem.mDataSpace)); Loading Loading @@ -341,14 +355,29 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { mAutoRefresh = bufferItem.mAutoRefresh; } auto mergeTransaction = [&t, currentFrameNumber = bufferItem.mFrameNumber]( std::tuple<uint64_t, SurfaceComposerClient::Transaction> pendingTransaction) { auto& [targetFrameNumber, transaction] = pendingTransaction; if (currentFrameNumber < targetFrameNumber) { return false; } t->merge(std::move(transaction)); return true; }; mPendingTransactions.erase(std::remove_if(mPendingTransactions.begin(), mPendingTransactions.end(), mergeTransaction), mPendingTransactions.end()); if (applyTransaction) { t->apply(); } BQA_LOGV("processNextBufferLocked size=%dx%d mFrameNumber=%" PRIu64 " applyTransaction=%s mTimestamp=%" PRId64, " applyTransaction=%s mTimestamp=%" PRId64 " mPendingTransactions.size=%d", mSize.width, mSize.height, bufferItem.mFrameNumber, toString(applyTransaction), bufferItem.mTimestamp); bufferItem.mTimestamp, static_cast<uint32_t>(mPendingTransactions.size())); } Rect BLASTBufferQueue::computeCrop(const BufferItem& item) { Loading Loading @@ -487,6 +516,17 @@ sp<Surface> BLASTBufferQueue::getSurface(bool includeSurfaceControlHandle) { return new BBQSurface(mProducer, true, scHandle, this); } void BLASTBufferQueue::mergeWithNextTransaction(SurfaceComposerClient::Transaction* t, uint64_t frameNumber) { std::lock_guard _lock{mMutex}; if (mLastAcquiredFrameNumber >= frameNumber) { // Apply the transaction since we have already acquired the desired frame. t->apply(); } else { mPendingTransactions.emplace_back(frameNumber, std::move(*t)); } } // Maintains a single worker thread per process that services a list of runnables. class AsyncWorker : public Singleton<AsyncWorker> { private: Loading
libs/gui/include/gui/BLASTBufferQueue.h +8 −1 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ public: void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence, const std::vector<SurfaceControlStats>& stats); void setNextTransaction(SurfaceComposerClient::Transaction *t); void mergeWithNextTransaction(SurfaceComposerClient::Transaction* t, uint64_t frameNumber); void setTransactionCompleteCallback(uint64_t frameNumber, std::function<void(int64_t)>&& transactionCompleteCallback); Loading @@ -91,7 +92,7 @@ public: status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless); status_t setFrameTimelineVsync(int64_t frameTimelineVsyncId); virtual ~BLASTBufferQueue() = default; virtual ~BLASTBufferQueue(); private: friend class BLASTBufferQueueHelper; Loading Loading @@ -141,6 +142,9 @@ private: sp<BLASTBufferItemConsumer> mBufferItemConsumer; SurfaceComposerClient::Transaction* mNextTransaction GUARDED_BY(mMutex); std::vector<std::tuple<uint64_t /* framenumber */, SurfaceComposerClient::Transaction>> mPendingTransactions GUARDED_BY(mMutex); // If set to true, the next queue buffer will wait until the shadow queue has been processed by // the adapter. bool mFlushShadowQueue = false; Loading @@ -156,6 +160,9 @@ private: // where the layer can change sizes and the buffer will scale to fit the new size. uint32_t mLastBufferScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW; // Tracks the last acquired frame number uint64_t mLastAcquiredFrameNumber GUARDED_BY(mMutex) = 0; std::function<void(int64_t)> mTransactionCompleteCallback GUARDED_BY(mMutex) = nullptr; uint64_t mTransactionCompleteFrameNumber GUARDED_BY(mMutex){0}; }; Loading