blob: 00f6bcebe60839d09ca9faa78ed442eb6cff963d [file] [log] [blame]
Vishnu Nair59f6d2d2022-10-05 16:59:56 -07001/*
2 * Copyright 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <semaphore.h>
20#include <cstdint>
Patrick Williams090ad062023-08-08 12:30:10 -050021#include <optional>
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070022#include <vector>
23
24#include <LocklessQueue.h>
25#include <TransactionState.h>
26#include <android-base/thread_annotations.h>
27#include <ftl/small_map.h>
28#include <ftl/small_vector.h>
29
30namespace android {
Vishnu Nairaf6d2972022-11-18 06:26:38 +000031
32class TestableSurfaceFlinger;
33namespace surfaceflinger::frontend {
34
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070035class TransactionHandler {
36public:
37 struct TransactionFlushState {
liulijuneb489f62022-10-17 22:02:14 +080038 TransactionState* transaction;
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070039 bool firstTransaction = true;
40 nsecs_t queueProcessTime = 0;
41 // Layer handles that have transactions with buffers that are ready to be applied.
42 ftl::SmallMap<IBinder* /* binder address */, uint64_t /* framenumber */, 15>
43 bufferLayersReadyToPresent = {};
Vishnu Nairf01a6f12023-04-03 22:34:17 +000044 // Tracks the queue with an unsignaled buffer. This is used to handle
45 // LatchUnsignaledConfig::AutoSingleLayer to ensure we only apply an unsignaled buffer
46 // if it's the only transaction that is ready to be applied.
47 sp<IBinder> queueWithUnsignaledBuffer = nullptr;
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070048 };
49 enum class TransactionReadiness {
Vishnu Nairf01a6f12023-04-03 22:34:17 +000050 // Transaction is ready to be applied
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070051 Ready,
Vishnu Nairf01a6f12023-04-03 22:34:17 +000052 // Transaction has unmet conditions (fence, present time, etc) and cannot be applied.
53 NotReady,
54 // Transaction is waiting on a barrier (another buffer to be latched first)
55 NotReadyBarrier,
56 // Transaction has an unsignaled fence but can be applied if it's the only transaction
57 NotReadyUnsignaled,
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070058 };
59 using TransactionFilter = std::function<TransactionReadiness(const TransactionFlushState&)>;
60
61 bool hasPendingTransactions();
Vishnu Nair4d9cef92023-06-24 22:34:41 +000062 // Moves transactions from the lockless queue.
63 void collectTransactions();
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070064 std::vector<TransactionState> flushTransactions();
65 void addTransactionReadyFilter(TransactionFilter&&);
66 void queueTransaction(TransactionState&&);
Patrick Williams090ad062023-08-08 12:30:10 -050067
68 struct StalledTransactionInfo {
69 pid_t pid;
70 uint32_t layerId;
71 std::string layerName;
72 uint64_t bufferId;
73 uint64_t frameNumber;
74 };
75 void onTransactionQueueStalled(uint64_t transactionId, StalledTransactionInfo);
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070076 void removeFromStalledTransactions(uint64_t transactionId);
Patrick Williams090ad062023-08-08 12:30:10 -050077 std::optional<StalledTransactionInfo> getStalledTransactionInfo(pid_t pid);
78 void onLayerDestroyed(uint32_t layerId);
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070079
80private:
81 // For unit tests
Vishnu Nairaf6d2972022-11-18 06:26:38 +000082 friend class ::android::TestableSurfaceFlinger;
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070083
84 int flushPendingTransactionQueues(std::vector<TransactionState>&, TransactionFlushState&);
Vishnu Nairf01a6f12023-04-03 22:34:17 +000085 void applyUnsignaledBufferTransaction(std::vector<TransactionState>&, TransactionFlushState&);
86 void popTransactionFromPending(std::vector<TransactionState>&, TransactionFlushState&,
87 std::queue<TransactionState>&);
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070088 TransactionReadiness applyFilters(TransactionFlushState&);
89 std::unordered_map<sp<IBinder>, std::queue<TransactionState>, IListenerHash>
90 mPendingTransactionQueues;
91 LocklessQueue<TransactionState> mLocklessTransactionQueue;
92 std::atomic<size_t> mPendingTransactionCount = 0;
93 ftl::SmallVector<TransactionFilter, 2> mTransactionReadyFilters;
Patrick Williams090ad062023-08-08 12:30:10 -050094
95 std::mutex mStalledMutex;
96 std::unordered_map<uint64_t /* transactionId */, StalledTransactionInfo> mStalledTransactions
97 GUARDED_BY(mStalledMutex);
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070098};
Vishnu Nairaf6d2972022-11-18 06:26:38 +000099} // namespace surfaceflinger::frontend
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700100} // namespace android