/* * 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. */ #pragma once #include #include #include #include #include #include #include #include #include namespace android { class TestableSurfaceFlinger; namespace surfaceflinger::frontend { class TransactionHandler { public: struct TransactionFlushState { TransactionState* transaction; bool firstTransaction = true; nsecs_t queueProcessTime = 0; // Layer handles that have transactions with buffers that are ready to be applied. ftl::SmallMap bufferLayersReadyToPresent = {}; // Tracks the queue with an unsignaled buffer. This is used to handle // LatchUnsignaledConfig::AutoSingleLayer to ensure we only apply an unsignaled buffer // if it's the only transaction that is ready to be applied. sp queueWithUnsignaledBuffer = nullptr; }; enum class TransactionReadiness { // Transaction is ready to be applied Ready, // Transaction has unmet conditions (fence, present time, etc) and cannot be applied. NotReady, // Transaction is waiting on a barrier (another buffer to be latched first) NotReadyBarrier, // Transaction has an unsignaled fence but can be applied if it's the only transaction NotReadyUnsignaled, }; using TransactionFilter = std::function; bool hasPendingTransactions(); // Moves transactions from the lockless queue. void collectTransactions(); std::vector flushTransactions(); void addTransactionReadyFilter(TransactionFilter&&); void queueTransaction(TransactionState&&); struct StalledTransactionInfo { pid_t pid; uint32_t layerId; std::string layerName; uint64_t bufferId; uint64_t frameNumber; }; void onTransactionQueueStalled(uint64_t transactionId, StalledTransactionInfo); void removeFromStalledTransactions(uint64_t transactionId); std::optional getStalledTransactionInfo(pid_t pid); void onLayerDestroyed(uint32_t layerId); private: // For unit tests friend class ::android::TestableSurfaceFlinger; int flushPendingTransactionQueues(std::vector&, TransactionFlushState&); void applyUnsignaledBufferTransaction(std::vector&, TransactionFlushState&); void popTransactionFromPending(std::vector&, TransactionFlushState&, std::queue&); TransactionReadiness applyFilters(TransactionFlushState&); std::unordered_map, std::queue, IListenerHash> mPendingTransactionQueues; LocklessQueue mLocklessTransactionQueue; std::atomic mPendingTransactionCount = 0; ftl::SmallVector mTransactionReadyFilters; std::mutex mStalledMutex; std::unordered_map mStalledTransactions GUARDED_BY(mStalledMutex); }; } // namespace surfaceflinger::frontend } // namespace android