1*38e8c45fSAndroid Build Coastguard Worker /* 2*38e8c45fSAndroid Build Coastguard Worker * Copyright 2022 The Android Open Source Project 3*38e8c45fSAndroid Build Coastguard Worker * 4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*38e8c45fSAndroid Build Coastguard Worker * 8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*38e8c45fSAndroid Build Coastguard Worker * 10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License. 15*38e8c45fSAndroid Build Coastguard Worker */ 16*38e8c45fSAndroid Build Coastguard Worker 17*38e8c45fSAndroid Build Coastguard Worker #pragma once 18*38e8c45fSAndroid Build Coastguard Worker 19*38e8c45fSAndroid Build Coastguard Worker #include <semaphore.h> 20*38e8c45fSAndroid Build Coastguard Worker #include <cstdint> 21*38e8c45fSAndroid Build Coastguard Worker #include <optional> 22*38e8c45fSAndroid Build Coastguard Worker #include <vector> 23*38e8c45fSAndroid Build Coastguard Worker 24*38e8c45fSAndroid Build Coastguard Worker #include <LocklessQueue.h> 25*38e8c45fSAndroid Build Coastguard Worker #include <TransactionState.h> 26*38e8c45fSAndroid Build Coastguard Worker #include <android-base/thread_annotations.h> 27*38e8c45fSAndroid Build Coastguard Worker #include <ftl/small_map.h> 28*38e8c45fSAndroid Build Coastguard Worker #include <ftl/small_vector.h> 29*38e8c45fSAndroid Build Coastguard Worker 30*38e8c45fSAndroid Build Coastguard Worker namespace android { 31*38e8c45fSAndroid Build Coastguard Worker 32*38e8c45fSAndroid Build Coastguard Worker class TestableSurfaceFlinger; 33*38e8c45fSAndroid Build Coastguard Worker namespace surfaceflinger::frontend { 34*38e8c45fSAndroid Build Coastguard Worker 35*38e8c45fSAndroid Build Coastguard Worker class TransactionHandler { 36*38e8c45fSAndroid Build Coastguard Worker public: 37*38e8c45fSAndroid Build Coastguard Worker struct TransactionFlushState { 38*38e8c45fSAndroid Build Coastguard Worker TransactionState* transaction; 39*38e8c45fSAndroid Build Coastguard Worker bool firstTransaction = true; 40*38e8c45fSAndroid Build Coastguard Worker nsecs_t queueProcessTime = 0; 41*38e8c45fSAndroid Build Coastguard Worker // Layer handles that have transactions with buffers that are ready to be applied. 42*38e8c45fSAndroid Build Coastguard Worker ftl::SmallMap<IBinder* /* binder address */, uint64_t /* framenumber */, 15> 43*38e8c45fSAndroid Build Coastguard Worker bufferLayersReadyToPresent = {}; 44*38e8c45fSAndroid Build Coastguard Worker // Tracks the queue with an unsignaled buffer. This is used to handle 45*38e8c45fSAndroid Build Coastguard Worker // LatchUnsignaledConfig::AutoSingleLayer to ensure we only apply an unsignaled buffer 46*38e8c45fSAndroid Build Coastguard Worker // if it's the only transaction that is ready to be applied. 47*38e8c45fSAndroid Build Coastguard Worker sp<IBinder> queueWithUnsignaledBuffer = nullptr; 48*38e8c45fSAndroid Build Coastguard Worker }; 49*38e8c45fSAndroid Build Coastguard Worker enum class TransactionReadiness { 50*38e8c45fSAndroid Build Coastguard Worker // Transaction is ready to be applied 51*38e8c45fSAndroid Build Coastguard Worker Ready, 52*38e8c45fSAndroid Build Coastguard Worker // Transaction has unmet conditions (fence, present time, etc) and cannot be applied. 53*38e8c45fSAndroid Build Coastguard Worker NotReady, 54*38e8c45fSAndroid Build Coastguard Worker // Transaction is waiting on a barrier (another buffer to be latched first) 55*38e8c45fSAndroid Build Coastguard Worker NotReadyBarrier, 56*38e8c45fSAndroid Build Coastguard Worker // Transaction has an unsignaled fence but can be applied if it's the only transaction 57*38e8c45fSAndroid Build Coastguard Worker NotReadyUnsignaled, 58*38e8c45fSAndroid Build Coastguard Worker }; 59*38e8c45fSAndroid Build Coastguard Worker using TransactionFilter = std::function<TransactionReadiness(const TransactionFlushState&)>; 60*38e8c45fSAndroid Build Coastguard Worker 61*38e8c45fSAndroid Build Coastguard Worker bool hasPendingTransactions(); 62*38e8c45fSAndroid Build Coastguard Worker // Moves transactions from the lockless queue. 63*38e8c45fSAndroid Build Coastguard Worker void collectTransactions(); 64*38e8c45fSAndroid Build Coastguard Worker std::vector<TransactionState> flushTransactions(); 65*38e8c45fSAndroid Build Coastguard Worker void addTransactionReadyFilter(TransactionFilter&&); 66*38e8c45fSAndroid Build Coastguard Worker void queueTransaction(TransactionState&&); 67*38e8c45fSAndroid Build Coastguard Worker 68*38e8c45fSAndroid Build Coastguard Worker struct StalledTransactionInfo { 69*38e8c45fSAndroid Build Coastguard Worker pid_t pid; 70*38e8c45fSAndroid Build Coastguard Worker uint32_t layerId; 71*38e8c45fSAndroid Build Coastguard Worker std::string layerName; 72*38e8c45fSAndroid Build Coastguard Worker uint64_t bufferId; 73*38e8c45fSAndroid Build Coastguard Worker uint64_t frameNumber; 74*38e8c45fSAndroid Build Coastguard Worker }; 75*38e8c45fSAndroid Build Coastguard Worker void onTransactionQueueStalled(uint64_t transactionId, StalledTransactionInfo); 76*38e8c45fSAndroid Build Coastguard Worker void removeFromStalledTransactions(uint64_t transactionId); 77*38e8c45fSAndroid Build Coastguard Worker std::optional<StalledTransactionInfo> getStalledTransactionInfo(pid_t pid); 78*38e8c45fSAndroid Build Coastguard Worker void onLayerDestroyed(uint32_t layerId); 79*38e8c45fSAndroid Build Coastguard Worker 80*38e8c45fSAndroid Build Coastguard Worker private: 81*38e8c45fSAndroid Build Coastguard Worker // For unit tests 82*38e8c45fSAndroid Build Coastguard Worker friend class ::android::TestableSurfaceFlinger; 83*38e8c45fSAndroid Build Coastguard Worker 84*38e8c45fSAndroid Build Coastguard Worker int flushPendingTransactionQueues(std::vector<TransactionState>&, TransactionFlushState&); 85*38e8c45fSAndroid Build Coastguard Worker void applyUnsignaledBufferTransaction(std::vector<TransactionState>&, TransactionFlushState&); 86*38e8c45fSAndroid Build Coastguard Worker void popTransactionFromPending(std::vector<TransactionState>&, TransactionFlushState&, 87*38e8c45fSAndroid Build Coastguard Worker std::queue<TransactionState>&); 88*38e8c45fSAndroid Build Coastguard Worker TransactionReadiness applyFilters(TransactionFlushState&); 89*38e8c45fSAndroid Build Coastguard Worker std::unordered_map<sp<IBinder>, std::queue<TransactionState>, IListenerHash> 90*38e8c45fSAndroid Build Coastguard Worker mPendingTransactionQueues; 91*38e8c45fSAndroid Build Coastguard Worker LocklessQueue<TransactionState> mLocklessTransactionQueue; 92*38e8c45fSAndroid Build Coastguard Worker std::atomic<size_t> mPendingTransactionCount = 0; 93*38e8c45fSAndroid Build Coastguard Worker ftl::SmallVector<TransactionFilter, 2> mTransactionReadyFilters; 94*38e8c45fSAndroid Build Coastguard Worker 95*38e8c45fSAndroid Build Coastguard Worker std::mutex mStalledMutex; 96*38e8c45fSAndroid Build Coastguard Worker std::unordered_map<uint64_t /* transactionId */, StalledTransactionInfo> mStalledTransactions 97*38e8c45fSAndroid Build Coastguard Worker GUARDED_BY(mStalledMutex); 98*38e8c45fSAndroid Build Coastguard Worker }; 99*38e8c45fSAndroid Build Coastguard Worker } // namespace surfaceflinger::frontend 100*38e8c45fSAndroid Build Coastguard Worker } // namespace android 101