Loading services/surfaceflinger/SurfaceFlinger.cpp +16 −87 Original line number Diff line number Diff line Loading @@ -3621,39 +3621,21 @@ void SurfaceFlinger::setTransactionFlags(uint32_t mask, TransactionSchedule sche } } bool SurfaceFlinger::stopTransactionProcessing( const std::unordered_set<sp<IBinder>, SpHash<IBinder>>& applyTokensWithUnsignaledTransactions) const { if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::AutoSingleLayer) { // if we are in LatchUnsignaledConfig::AutoSingleLayer // then we should have only one applyToken for processing. // so we can stop further transactions on this applyToken. return !applyTokensWithUnsignaledTransactions.empty(); } return false; } int SurfaceFlinger::flushUnsignaledPendingTransactionQueues( std::vector<TransactionState>& transactions, std::unordered_map<sp<IBinder>, uint64_t, SpHash<IBinder>>& bufferLayersReadyToPresent, std::unordered_set<sp<IBinder>, SpHash<IBinder>>& applyTokensWithUnsignaledTransactions) { return flushPendingTransactionQueues(transactions, bufferLayersReadyToPresent, applyTokensWithUnsignaledTransactions, /*tryApplyUnsignaled*/ true); } int SurfaceFlinger::flushPendingTransactionQueues( std::vector<TransactionState>& transactions, std::unordered_map<sp<IBinder>, uint64_t, SpHash<IBinder>>& bufferLayersReadyToPresent, std::unordered_set<sp<IBinder>, SpHash<IBinder>>& applyTokensWithUnsignaledTransactions, bool tryApplyUnsignaled) { std::unordered_set<sp<IBinder>, SpHash<IBinder>> applyTokensWithUnsignaledTransactions; int transactionsPendingBarrier = 0; auto it = mPendingTransactionQueues.begin(); while (it != mPendingTransactionQueues.end()) { auto& [applyToken, transactionQueue] = *it; while (!transactionQueue.empty()) { if (stopTransactionProcessing(applyTokensWithUnsignaledTransactions)) { // if we are in LatchUnsignaledConfig::AutoSingleLayer // then we should have only one applyToken for processing. // so we can stop further transactions on this applyToken. if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::AutoSingleLayer && !applyTokensWithUnsignaledTransactions.empty()) { ATRACE_NAME("stopTransactionProcessing"); break; } Loading Loading @@ -3701,7 +3683,6 @@ int SurfaceFlinger::flushPendingTransactionQueues( if (transactionQueue.empty()) { it = mPendingTransactionQueues.erase(it); mTransactionQueueCV.broadcast(); } else { it = std::next(it, 1); } Loading @@ -3716,68 +3697,16 @@ bool SurfaceFlinger::flushTransactionQueues(int64_t vsyncId) { std::vector<TransactionState> transactions; // Layer handles that have transactions with buffers that are ready to be applied. std::unordered_map<sp<IBinder>, uint64_t, SpHash<IBinder>> bufferLayersReadyToPresent; std::unordered_set<sp<IBinder>, SpHash<IBinder>> applyTokensWithUnsignaledTransactions; { Mutex::Autolock _l(mStateLock); { int lastTransactionsPendingBarrier = 0; int transactionsPendingBarrier = 0; // First collect transactions from the pending transaction queues. // We are not allowing unsignaled buffers here as we want to // collect all the transactions from applyTokens that are ready first. transactionsPendingBarrier = flushPendingTransactionQueues(transactions, bufferLayersReadyToPresent, applyTokensWithUnsignaledTransactions, /*tryApplyUnsignaled*/ false); // Second, collect transactions from the transaction queue. // Here as well we are not allowing unsignaled buffers for the same // reason as above. while (!mLocklessTransactionQueue.isEmpty()) { auto maybeTransaction = mLocklessTransactionQueue.pop(); if (!maybeTransaction.has_value()) { break; } auto transaction = maybeTransaction.value(); const bool pendingTransactions = mPendingTransactionQueues.find(transaction.applyToken) != mPendingTransactionQueues.end(); const auto ready = [&]() REQUIRES(mStateLock) { if (pendingTransactions) { ATRACE_NAME("pendingTransactions"); return TransactionReadiness::NotReady; } return transactionIsReadyToBeApplied(transaction, transaction.frameTimelineInfo, transaction.isAutoTimestamp, transaction.desiredPresentTime, transaction.originUid, transaction.states, bufferLayersReadyToPresent, transactions.size(), /*tryApplyUnsignaled*/ false); }(); ATRACE_INT("TransactionReadiness", static_cast<int>(ready)); if (ready != TransactionReadiness::Ready) { if (ready == TransactionReadiness::NotReadyBarrier) { transactionsPendingBarrier++; } mPendingTransactionQueues[transaction.applyToken].push(std::move(transaction)); } else { transaction.traverseStatesWithBuffers([&](const layer_state_t& state) { const bool frameNumberChanged = state.bufferData->flags.test( BufferData::BufferDataChange::frameNumberChanged); if (frameNumberChanged) { bufferLayersReadyToPresent[state.surface] = state.bufferData->frameNumber; } else { // Barrier function only used for BBQ which always includes a frame number. // This value only used for barrier logic. bufferLayersReadyToPresent[state.surface] = std::numeric_limits<uint64_t>::max(); } }); transactions.emplace_back(std::move(transaction)); mPendingTransactionCount--; ATRACE_INT("TransactionQueue", mPendingTransactionCount.load()); } } // Transactions with a buffer pending on a barrier may be on a different applyToken Loading @@ -3790,20 +3719,21 @@ bool SurfaceFlinger::flushTransactionQueues(int64_t vsyncId) { // loop through flushPendingTransactionQueues until we perform an iteration // where the number of transactionsPendingBarrier doesn't change. This way // we can continue to resolve dependency chains of barriers as far as possible. while (lastTransactionsPendingBarrier != transactionsPendingBarrier) { int lastTransactionsPendingBarrier = 0; int transactionsPendingBarrier = 0; do { lastTransactionsPendingBarrier = transactionsPendingBarrier; transactionsPendingBarrier = flushPendingTransactionQueues(transactions, bufferLayersReadyToPresent, applyTokensWithUnsignaledTransactions, /*tryApplyUnsignaled*/ false); } } while (lastTransactionsPendingBarrier != transactionsPendingBarrier); // We collected all transactions that could apply without latching unsignaled buffers. // If we are allowing latch unsignaled of some form, now it's the time to go over the // transactions that were not applied and try to apply them unsignaled. if (enableLatchUnsignaledConfig != LatchUnsignaledConfig::Disabled) { flushUnsignaledPendingTransactionQueues(transactions, bufferLayersReadyToPresent, applyTokensWithUnsignaledTransactions); flushPendingTransactionQueues(transactions, bufferLayersReadyToPresent, /*tryApplyUnsignaled*/ true); } return applyTransactions(transactions, vsyncId); Loading Loading @@ -3977,7 +3907,7 @@ auto SurfaceFlinger::transactionIsReadyToBeApplied(TransactionState& transaction if (fenceUnsignaled && !allowLatchUnsignaled) { if (!transaction.sentFenceTimeoutWarning && queueProcessTime - transaction.queueTime > std::chrono::nanoseconds(4s).count()) { queueProcessTime - transaction.postTime > std::chrono::nanoseconds(4s).count()) { transaction.sentFenceTimeoutWarning = true; auto listener = s.bufferData->releaseBufferListener; if (listener) { Loading @@ -4004,7 +3934,6 @@ auto SurfaceFlinger::transactionIsReadyToBeApplied(TransactionState& transaction } void SurfaceFlinger::queueTransaction(TransactionState& state) { state.queueTime = systemTime(); // Generate a CountDownLatch pending state if this is a synchronous transaction. if (state.flags & eSynchronous) { state.transactionCommittedSignal = Loading services/surfaceflinger/SurfaceFlinger.h +0 −10 Original line number Diff line number Diff line Loading @@ -754,15 +754,8 @@ private: int flushPendingTransactionQueues( std::vector<TransactionState>& transactions, std::unordered_map<sp<IBinder>, uint64_t, SpHash<IBinder>>& bufferLayersReadyToPresent, std::unordered_set<sp<IBinder>, SpHash<IBinder>>& applyTokensWithUnsignaledTransactions, bool tryApplyUnsignaled) REQUIRES(mStateLock); int flushUnsignaledPendingTransactionQueues( std::vector<TransactionState>& transactions, std::unordered_map<sp<IBinder>, uint64_t, SpHash<IBinder>>& bufferLayersReadyToPresent, std::unordered_set<sp<IBinder>, SpHash<IBinder>>& applyTokensWithUnsignaledTransactions) REQUIRES(mStateLock); uint32_t setClientStateLocked(const FrameTimelineInfo&, ComposerState&, int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, uint32_t permissions) REQUIRES(mStateLock); Loading Loading @@ -794,8 +787,6 @@ private: static LatchUnsignaledConfig getLatchUnsignaledConfig(); bool shouldLatchUnsignaled(const sp<Layer>& layer, const layer_state_t&, size_t numStates, size_t totalTXapplied) const; bool stopTransactionProcessing(const std::unordered_set<sp<IBinder>, SpHash<IBinder>>& applyTokensWithUnsignaledTransactions) const; bool applyTransactions(std::vector<TransactionState>& transactions, int64_t vsyncId) REQUIRES(mStateLock); uint32_t setDisplayStateLocked(const DisplayState& s) REQUIRES(mStateLock); Loading Loading @@ -1245,7 +1236,6 @@ private: uint32_t mTexturePoolSize = 0; std::vector<uint32_t> mTexturePool; Condition mTransactionQueueCV; std::unordered_map<sp<IBinder>, std::queue<TransactionState>, IListenerHash> mPendingTransactionQueues; LocklessQueue<TransactionState> mLocklessTransactionQueue; Loading services/surfaceflinger/TransactionState.h +0 −1 Original line number Diff line number Diff line Loading @@ -98,7 +98,6 @@ struct TransactionState { int originUid; uint64_t id; std::shared_ptr<CountDownLatch> transactionCommittedSignal; int64_t queueTime = 0; bool sentFenceTimeoutWarning = false; }; Loading Loading
services/surfaceflinger/SurfaceFlinger.cpp +16 −87 Original line number Diff line number Diff line Loading @@ -3621,39 +3621,21 @@ void SurfaceFlinger::setTransactionFlags(uint32_t mask, TransactionSchedule sche } } bool SurfaceFlinger::stopTransactionProcessing( const std::unordered_set<sp<IBinder>, SpHash<IBinder>>& applyTokensWithUnsignaledTransactions) const { if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::AutoSingleLayer) { // if we are in LatchUnsignaledConfig::AutoSingleLayer // then we should have only one applyToken for processing. // so we can stop further transactions on this applyToken. return !applyTokensWithUnsignaledTransactions.empty(); } return false; } int SurfaceFlinger::flushUnsignaledPendingTransactionQueues( std::vector<TransactionState>& transactions, std::unordered_map<sp<IBinder>, uint64_t, SpHash<IBinder>>& bufferLayersReadyToPresent, std::unordered_set<sp<IBinder>, SpHash<IBinder>>& applyTokensWithUnsignaledTransactions) { return flushPendingTransactionQueues(transactions, bufferLayersReadyToPresent, applyTokensWithUnsignaledTransactions, /*tryApplyUnsignaled*/ true); } int SurfaceFlinger::flushPendingTransactionQueues( std::vector<TransactionState>& transactions, std::unordered_map<sp<IBinder>, uint64_t, SpHash<IBinder>>& bufferLayersReadyToPresent, std::unordered_set<sp<IBinder>, SpHash<IBinder>>& applyTokensWithUnsignaledTransactions, bool tryApplyUnsignaled) { std::unordered_set<sp<IBinder>, SpHash<IBinder>> applyTokensWithUnsignaledTransactions; int transactionsPendingBarrier = 0; auto it = mPendingTransactionQueues.begin(); while (it != mPendingTransactionQueues.end()) { auto& [applyToken, transactionQueue] = *it; while (!transactionQueue.empty()) { if (stopTransactionProcessing(applyTokensWithUnsignaledTransactions)) { // if we are in LatchUnsignaledConfig::AutoSingleLayer // then we should have only one applyToken for processing. // so we can stop further transactions on this applyToken. if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::AutoSingleLayer && !applyTokensWithUnsignaledTransactions.empty()) { ATRACE_NAME("stopTransactionProcessing"); break; } Loading Loading @@ -3701,7 +3683,6 @@ int SurfaceFlinger::flushPendingTransactionQueues( if (transactionQueue.empty()) { it = mPendingTransactionQueues.erase(it); mTransactionQueueCV.broadcast(); } else { it = std::next(it, 1); } Loading @@ -3716,68 +3697,16 @@ bool SurfaceFlinger::flushTransactionQueues(int64_t vsyncId) { std::vector<TransactionState> transactions; // Layer handles that have transactions with buffers that are ready to be applied. std::unordered_map<sp<IBinder>, uint64_t, SpHash<IBinder>> bufferLayersReadyToPresent; std::unordered_set<sp<IBinder>, SpHash<IBinder>> applyTokensWithUnsignaledTransactions; { Mutex::Autolock _l(mStateLock); { int lastTransactionsPendingBarrier = 0; int transactionsPendingBarrier = 0; // First collect transactions from the pending transaction queues. // We are not allowing unsignaled buffers here as we want to // collect all the transactions from applyTokens that are ready first. transactionsPendingBarrier = flushPendingTransactionQueues(transactions, bufferLayersReadyToPresent, applyTokensWithUnsignaledTransactions, /*tryApplyUnsignaled*/ false); // Second, collect transactions from the transaction queue. // Here as well we are not allowing unsignaled buffers for the same // reason as above. while (!mLocklessTransactionQueue.isEmpty()) { auto maybeTransaction = mLocklessTransactionQueue.pop(); if (!maybeTransaction.has_value()) { break; } auto transaction = maybeTransaction.value(); const bool pendingTransactions = mPendingTransactionQueues.find(transaction.applyToken) != mPendingTransactionQueues.end(); const auto ready = [&]() REQUIRES(mStateLock) { if (pendingTransactions) { ATRACE_NAME("pendingTransactions"); return TransactionReadiness::NotReady; } return transactionIsReadyToBeApplied(transaction, transaction.frameTimelineInfo, transaction.isAutoTimestamp, transaction.desiredPresentTime, transaction.originUid, transaction.states, bufferLayersReadyToPresent, transactions.size(), /*tryApplyUnsignaled*/ false); }(); ATRACE_INT("TransactionReadiness", static_cast<int>(ready)); if (ready != TransactionReadiness::Ready) { if (ready == TransactionReadiness::NotReadyBarrier) { transactionsPendingBarrier++; } mPendingTransactionQueues[transaction.applyToken].push(std::move(transaction)); } else { transaction.traverseStatesWithBuffers([&](const layer_state_t& state) { const bool frameNumberChanged = state.bufferData->flags.test( BufferData::BufferDataChange::frameNumberChanged); if (frameNumberChanged) { bufferLayersReadyToPresent[state.surface] = state.bufferData->frameNumber; } else { // Barrier function only used for BBQ which always includes a frame number. // This value only used for barrier logic. bufferLayersReadyToPresent[state.surface] = std::numeric_limits<uint64_t>::max(); } }); transactions.emplace_back(std::move(transaction)); mPendingTransactionCount--; ATRACE_INT("TransactionQueue", mPendingTransactionCount.load()); } } // Transactions with a buffer pending on a barrier may be on a different applyToken Loading @@ -3790,20 +3719,21 @@ bool SurfaceFlinger::flushTransactionQueues(int64_t vsyncId) { // loop through flushPendingTransactionQueues until we perform an iteration // where the number of transactionsPendingBarrier doesn't change. This way // we can continue to resolve dependency chains of barriers as far as possible. while (lastTransactionsPendingBarrier != transactionsPendingBarrier) { int lastTransactionsPendingBarrier = 0; int transactionsPendingBarrier = 0; do { lastTransactionsPendingBarrier = transactionsPendingBarrier; transactionsPendingBarrier = flushPendingTransactionQueues(transactions, bufferLayersReadyToPresent, applyTokensWithUnsignaledTransactions, /*tryApplyUnsignaled*/ false); } } while (lastTransactionsPendingBarrier != transactionsPendingBarrier); // We collected all transactions that could apply without latching unsignaled buffers. // If we are allowing latch unsignaled of some form, now it's the time to go over the // transactions that were not applied and try to apply them unsignaled. if (enableLatchUnsignaledConfig != LatchUnsignaledConfig::Disabled) { flushUnsignaledPendingTransactionQueues(transactions, bufferLayersReadyToPresent, applyTokensWithUnsignaledTransactions); flushPendingTransactionQueues(transactions, bufferLayersReadyToPresent, /*tryApplyUnsignaled*/ true); } return applyTransactions(transactions, vsyncId); Loading Loading @@ -3977,7 +3907,7 @@ auto SurfaceFlinger::transactionIsReadyToBeApplied(TransactionState& transaction if (fenceUnsignaled && !allowLatchUnsignaled) { if (!transaction.sentFenceTimeoutWarning && queueProcessTime - transaction.queueTime > std::chrono::nanoseconds(4s).count()) { queueProcessTime - transaction.postTime > std::chrono::nanoseconds(4s).count()) { transaction.sentFenceTimeoutWarning = true; auto listener = s.bufferData->releaseBufferListener; if (listener) { Loading @@ -4004,7 +3934,6 @@ auto SurfaceFlinger::transactionIsReadyToBeApplied(TransactionState& transaction } void SurfaceFlinger::queueTransaction(TransactionState& state) { state.queueTime = systemTime(); // Generate a CountDownLatch pending state if this is a synchronous transaction. if (state.flags & eSynchronous) { state.transactionCommittedSignal = Loading
services/surfaceflinger/SurfaceFlinger.h +0 −10 Original line number Diff line number Diff line Loading @@ -754,15 +754,8 @@ private: int flushPendingTransactionQueues( std::vector<TransactionState>& transactions, std::unordered_map<sp<IBinder>, uint64_t, SpHash<IBinder>>& bufferLayersReadyToPresent, std::unordered_set<sp<IBinder>, SpHash<IBinder>>& applyTokensWithUnsignaledTransactions, bool tryApplyUnsignaled) REQUIRES(mStateLock); int flushUnsignaledPendingTransactionQueues( std::vector<TransactionState>& transactions, std::unordered_map<sp<IBinder>, uint64_t, SpHash<IBinder>>& bufferLayersReadyToPresent, std::unordered_set<sp<IBinder>, SpHash<IBinder>>& applyTokensWithUnsignaledTransactions) REQUIRES(mStateLock); uint32_t setClientStateLocked(const FrameTimelineInfo&, ComposerState&, int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, uint32_t permissions) REQUIRES(mStateLock); Loading Loading @@ -794,8 +787,6 @@ private: static LatchUnsignaledConfig getLatchUnsignaledConfig(); bool shouldLatchUnsignaled(const sp<Layer>& layer, const layer_state_t&, size_t numStates, size_t totalTXapplied) const; bool stopTransactionProcessing(const std::unordered_set<sp<IBinder>, SpHash<IBinder>>& applyTokensWithUnsignaledTransactions) const; bool applyTransactions(std::vector<TransactionState>& transactions, int64_t vsyncId) REQUIRES(mStateLock); uint32_t setDisplayStateLocked(const DisplayState& s) REQUIRES(mStateLock); Loading Loading @@ -1245,7 +1236,6 @@ private: uint32_t mTexturePoolSize = 0; std::vector<uint32_t> mTexturePool; Condition mTransactionQueueCV; std::unordered_map<sp<IBinder>, std::queue<TransactionState>, IListenerHash> mPendingTransactionQueues; LocklessQueue<TransactionState> mLocklessTransactionQueue; Loading
services/surfaceflinger/TransactionState.h +0 −1 Original line number Diff line number Diff line Loading @@ -98,7 +98,6 @@ struct TransactionState { int originUid; uint64_t id; std::shared_ptr<CountDownLatch> transactionCommittedSignal; int64_t queueTime = 0; bool sentFenceTimeoutWarning = false; }; Loading