blob: 900d5669421f491bf37a94a74d5d1ab3a0e35ad0 [file] [log] [blame]
Vishnu Nair6b591152021-10-08 11:45:14 -07001/*
Dominik Laskowski1f6fc702022-03-21 08:34:50 -07002 * Copyright 2021 The Android Open Source Project
Vishnu Nair6b591152021-10-08 11:45:14 -07003 *
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
Dominik Laskowski1f6fc702022-03-21 08:34:50 -070019#include <condition_variable>
20#include <memory>
21#include <mutex>
22#include <vector>
23
Vishnu Nair6b591152021-10-08 11:45:14 -070024#include <gui/LayerState.h>
Dominik Laskowski1f6fc702022-03-21 08:34:50 -070025#include <system/window.h>
Vishnu Nair6b591152021-10-08 11:45:14 -070026
27namespace android {
Dominik Laskowski1f6fc702022-03-21 08:34:50 -070028
Vishnu Nair6b591152021-10-08 11:45:14 -070029class CountDownLatch;
30
31struct TransactionState {
Dominik Laskowski1f6fc702022-03-21 08:34:50 -070032 TransactionState() = default;
33
Vishnu Nair6b591152021-10-08 11:45:14 -070034 TransactionState(const FrameTimelineInfo& frameTimelineInfo,
35 const Vector<ComposerState>& composerStates,
36 const Vector<DisplayState>& displayStates, uint32_t transactionFlags,
37 const sp<IBinder>& applyToken, const InputWindowCommands& inputWindowCommands,
38 int64_t desiredPresentTime, bool isAutoTimestamp,
39 const client_cache_t& uncacheBuffer, int64_t postTime, uint32_t permissions,
40 bool hasListenerCallbacks, std::vector<ListenerCallbacks> listenerCallbacks,
41 int originPid, int originUid, uint64_t transactionId)
42 : frameTimelineInfo(frameTimelineInfo),
43 states(composerStates),
44 displays(displayStates),
45 flags(transactionFlags),
46 applyToken(applyToken),
47 inputWindowCommands(inputWindowCommands),
48 desiredPresentTime(desiredPresentTime),
49 isAutoTimestamp(isAutoTimestamp),
50 buffer(uncacheBuffer),
51 postTime(postTime),
52 permissions(permissions),
53 hasListenerCallbacks(hasListenerCallbacks),
54 listenerCallbacks(listenerCallbacks),
55 originPid(originPid),
56 originUid(originUid),
57 id(transactionId) {}
58
Dominik Laskowski1f6fc702022-03-21 08:34:50 -070059 // Invokes `void(const layer_state_t&)` visitor for matching layers.
60 template <typename Visitor>
61 void traverseStatesWithBuffers(Visitor&& visitor) const {
62 for (const auto& [state] : states) {
63 if (state.hasBufferChanges() && state.hasValidBuffer() && state.surface) {
64 visitor(state);
65 }
66 }
67 }
Vishnu Nair6b591152021-10-08 11:45:14 -070068
Dominik Laskowski1f6fc702022-03-21 08:34:50 -070069 // TODO(b/185535769): Remove FrameHint. Instead, reset the idle timer (of the relevant physical
70 // display) on the main thread if commit leads to composite. Then, RefreshRateOverlay should be
71 // able to setFrameRate once, rather than for each transaction.
72 bool isFrameActive() const {
73 if (!displays.empty()) return true;
74
75 for (const auto& [state] : states) {
76 if (state.frameRateCompatibility != ANATIVEWINDOW_FRAME_RATE_NO_VOTE) {
77 return true;
78 }
79 }
80
81 return false;
82 }
Vishnu Nair6b591152021-10-08 11:45:14 -070083
84 FrameTimelineInfo frameTimelineInfo;
85 Vector<ComposerState> states;
86 Vector<DisplayState> displays;
87 uint32_t flags;
88 sp<IBinder> applyToken;
89 InputWindowCommands inputWindowCommands;
90 int64_t desiredPresentTime;
91 bool isAutoTimestamp;
92 client_cache_t buffer;
93 int64_t postTime;
94 uint32_t permissions;
95 bool hasListenerCallbacks;
96 std::vector<ListenerCallbacks> listenerCallbacks;
97 int originPid;
98 int originUid;
99 uint64_t id;
100 std::shared_ptr<CountDownLatch> transactionCommittedSignal;
Robert Carr4c1b6462021-12-21 10:30:50 -0800101 int64_t queueTime = 0;
102 bool sentFenceTimeoutWarning = false;
Vishnu Nair6b591152021-10-08 11:45:14 -0700103};
104
105class CountDownLatch {
106public:
107 enum {
108 eSyncTransaction = 1 << 0,
109 eSyncInputWindows = 1 << 1,
110 };
111 explicit CountDownLatch(uint32_t flags) : mFlags(flags) {}
112
113 // True if there is no waiting condition after count down.
114 bool countDown(uint32_t flag) {
115 std::unique_lock<std::mutex> lock(mMutex);
116 if (mFlags == 0) {
117 return true;
118 }
119 mFlags &= ~flag;
120 if (mFlags == 0) {
121 mCountDownComplete.notify_all();
122 return true;
123 }
124 return false;
125 }
126
127 // Return true if triggered.
Ady Abrahame9ebce02022-02-03 12:05:06 -0800128 bool wait_until(const std::chrono::nanoseconds& timeout) const {
Vishnu Nair6b591152021-10-08 11:45:14 -0700129 std::unique_lock<std::mutex> lock(mMutex);
130 const auto untilTime = std::chrono::system_clock::now() + timeout;
131 while (mFlags != 0) {
132 // Conditional variables can be woken up sporadically, so we check count
133 // to verify the wakeup was triggered by |countDown|.
134 if (std::cv_status::timeout == mCountDownComplete.wait_until(lock, untilTime)) {
135 return false;
136 }
137 }
138 return true;
139 }
140
141private:
142 uint32_t mFlags;
143 mutable std::condition_variable mCountDownComplete;
144 mutable std::mutex mMutex;
145};
146
147} // namespace android