blob: bab5326093cbf0f029ce925691d504b6352326a7 [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;
101};
102
103class CountDownLatch {
104public:
105 enum {
106 eSyncTransaction = 1 << 0,
107 eSyncInputWindows = 1 << 1,
108 };
109 explicit CountDownLatch(uint32_t flags) : mFlags(flags) {}
110
111 // True if there is no waiting condition after count down.
112 bool countDown(uint32_t flag) {
113 std::unique_lock<std::mutex> lock(mMutex);
114 if (mFlags == 0) {
115 return true;
116 }
117 mFlags &= ~flag;
118 if (mFlags == 0) {
119 mCountDownComplete.notify_all();
120 return true;
121 }
122 return false;
123 }
124
125 // Return true if triggered.
Ady Abrahame9ebce02022-02-03 12:05:06 -0800126 bool wait_until(const std::chrono::nanoseconds& timeout) const {
Vishnu Nair6b591152021-10-08 11:45:14 -0700127 std::unique_lock<std::mutex> lock(mMutex);
128 const auto untilTime = std::chrono::system_clock::now() + timeout;
129 while (mFlags != 0) {
130 // Conditional variables can be woken up sporadically, so we check count
131 // to verify the wakeup was triggered by |countDown|.
132 if (std::cv_status::timeout == mCountDownComplete.wait_until(lock, untilTime)) {
133 return false;
134 }
135 }
136 return true;
137 }
138
139private:
140 uint32_t mFlags;
141 mutable std::condition_variable mCountDownComplete;
142 mutable std::mutex mMutex;
143};
144
145} // namespace android