diff options
| author | 2022-10-18 18:29:37 +0000 | |
|---|---|---|
| committer | 2022-10-18 19:53:51 +0000 | |
| commit | a61e4fbf1b2276ae43d23d8889f214f40ca13e20 (patch) | |
| tree | c8ac62fe629739be2c934b995c7a1c26f4a6c250 /services/surfaceflinger/TransactionHandler.cpp | |
| parent | 22c43f5828ea5b995f699f13246ed323539e9575 (diff) | |
SF: Move TransactionHandler to frontend
Makes it easier to carve out a library in
the future.
Test: presubmit
Bug: 238781169
Change-Id: Iaaa576b47b226114eba48606bffa9ed0dc77c71a
Diffstat (limited to 'services/surfaceflinger/TransactionHandler.cpp')
| -rw-r--r-- | services/surfaceflinger/TransactionHandler.cpp | 188 |
1 files changed, 0 insertions, 188 deletions
diff --git a/services/surfaceflinger/TransactionHandler.cpp b/services/surfaceflinger/TransactionHandler.cpp deleted file mode 100644 index 6c6a487b67..0000000000 --- a/services/surfaceflinger/TransactionHandler.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// #define LOG_NDEBUG 0 -#undef LOG_TAG -#define LOG_TAG "TransactionHandler" -#define ATRACE_TAG ATRACE_TAG_GRAPHICS - -#include <cutils/trace.h> -#include <utils/Log.h> - -#include "TransactionHandler.h" - -namespace android { - -void TransactionHandler::queueTransaction(TransactionState&& state) { - mLocklessTransactionQueue.push(std::move(state)); - mPendingTransactionCount.fetch_add(1); - ATRACE_INT("TransactionQueue", static_cast<int>(mPendingTransactionCount.load())); -} - -std::vector<TransactionState> TransactionHandler::flushTransactions() { - while (!mLocklessTransactionQueue.isEmpty()) { - auto maybeTransaction = mLocklessTransactionQueue.pop(); - if (!maybeTransaction.has_value()) { - break; - } - auto transaction = maybeTransaction.value(); - mPendingTransactionQueues[transaction.applyToken].emplace(std::move(transaction)); - } - - // Collect transaction that are ready to be applied. - std::vector<TransactionState> transactions; - TransactionFlushState flushState; - flushState.queueProcessTime = systemTime(); - // Transactions with a buffer pending on a barrier may be on a different applyToken - // than the transaction which satisfies our barrier. In fact this is the exact use case - // that the primitive is designed for. This means we may first process - // the barrier dependent transaction, determine it ineligible to complete - // and then satisfy in a later inner iteration of flushPendingTransactionQueues. - // The barrier dependent transaction was eligible to be presented in this frame - // but we would have prevented it without case. To fix this we continually - // 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. - int lastTransactionsPendingBarrier = 0; - int transactionsPendingBarrier = 0; - do { - lastTransactionsPendingBarrier = transactionsPendingBarrier; - // Collect transactions that are ready to be applied. - transactionsPendingBarrier = flushPendingTransactionQueues(transactions, flushState); - } while (lastTransactionsPendingBarrier != transactionsPendingBarrier); - - mPendingTransactionCount.fetch_sub(transactions.size()); - ATRACE_INT("TransactionQueue", static_cast<int>(mPendingTransactionCount.load())); - return transactions; -} - -TransactionHandler::TransactionReadiness TransactionHandler::applyFilters( - TransactionFlushState& flushState) { - auto ready = TransactionReadiness::Ready; - for (auto& filter : mTransactionReadyFilters) { - auto perFilterReady = filter(flushState); - switch (perFilterReady) { - case TransactionReadiness::NotReady: - case TransactionReadiness::NotReadyBarrier: - return perFilterReady; - - case TransactionReadiness::ReadyUnsignaled: - case TransactionReadiness::ReadyUnsignaledSingle: - // If one of the filters allows latching an unsignaled buffer, latch this ready - // state. - ready = perFilterReady; - break; - case TransactionReadiness::Ready: - continue; - } - } - return ready; -} - -int TransactionHandler::flushPendingTransactionQueues(std::vector<TransactionState>& transactions, - TransactionFlushState& flushState) { - int transactionsPendingBarrier = 0; - auto it = mPendingTransactionQueues.begin(); - while (it != mPendingTransactionQueues.end()) { - auto& queue = it->second; - IBinder* queueToken = it->first.get(); - - // if we have already flushed a transaction with an unsignaled buffer then stop queue - // processing - if (std::find(flushState.queuesWithUnsignaledBuffers.begin(), - flushState.queuesWithUnsignaledBuffers.end(), - queueToken) != flushState.queuesWithUnsignaledBuffers.end()) { - continue; - } - - while (!queue.empty()) { - auto& transaction = queue.front(); - flushState.transaction = &transaction; - auto ready = applyFilters(flushState); - if (ready == TransactionReadiness::NotReadyBarrier) { - transactionsPendingBarrier++; - break; - } else if (ready == TransactionReadiness::NotReady) { - break; - } - - // Transaction is ready move it from the pending queue. - flushState.firstTransaction = false; - removeFromStalledTransactions(transaction.id); - transactions.emplace_back(std::move(transaction)); - queue.pop(); - - // If the buffer is unsignaled, then we don't want to signal other transactions using - // the buffer as a barrier. - auto& readyToApplyTransaction = transactions.back(); - if (ready == TransactionReadiness::Ready) { - readyToApplyTransaction.traverseStatesWithBuffers([&](const layer_state_t& state) { - const bool frameNumberChanged = state.bufferData->flags.test( - BufferData::BufferDataChange::frameNumberChanged); - if (frameNumberChanged) { - flushState.bufferLayersReadyToPresent - .emplace_or_replace(state.surface.get(), - state.bufferData->frameNumber); - } else { - // Barrier function only used for BBQ which always includes a frame number. - // This value only used for barrier logic. - flushState.bufferLayersReadyToPresent - .emplace_or_replace(state.surface.get(), - std::numeric_limits<uint64_t>::max()); - } - }); - } else if (ready == TransactionReadiness::ReadyUnsignaledSingle) { - // Track queues with a flushed unsingaled buffer. - flushState.queuesWithUnsignaledBuffers.emplace_back(queueToken); - break; - } - } - - if (queue.empty()) { - it = mPendingTransactionQueues.erase(it); - } else { - it = std::next(it, 1); - } - } - return transactionsPendingBarrier; -} - -void TransactionHandler::addTransactionReadyFilter(TransactionFilter&& filter) { - mTransactionReadyFilters.emplace_back(std::move(filter)); -} - -bool TransactionHandler::hasPendingTransactions() { - return !mPendingTransactionQueues.empty() || !mLocklessTransactionQueue.isEmpty(); -} - -void TransactionHandler::onTransactionQueueStalled(const TransactionState& transaction, - sp<ITransactionCompletedListener>& listener) { - if (std::find(mStalledTransactions.begin(), mStalledTransactions.end(), transaction.id) != - mStalledTransactions.end()) { - return; - } - - mStalledTransactions.push_back(transaction.id); - listener->onTransactionQueueStalled(); -} - -void TransactionHandler::removeFromStalledTransactions(uint64_t id) { - auto it = std::find(mStalledTransactions.begin(), mStalledTransactions.end(), id); - if (it != mStalledTransactions.end()) { - mStalledTransactions.erase(it); - } -} -} // namespace android
\ No newline at end of file |