xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/FrontEnd/TransactionHandler.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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