1 /* 2 * Copyright 2021 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 <condition_variable> 20 #include <memory> 21 #include <mutex> 22 #include <vector> 23 24 #include <gui/LayerState.h> 25 #include <system/window.h> 26 27 namespace android { 28 29 class CountDownLatch; 30 31 struct TransactionState { 32 TransactionState() = default; 33 TransactionStateTransactionState34 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 59 // Invokes `void(const layer_state_t&)` visitor for matching layers. 60 template <typename Visitor> traverseStatesWithBuffersTransactionState61 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 } 68 69 // 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. isFrameActiveTransactionState72 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 } 83 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 int64_t queueTime = 0; 102 bool sentFenceTimeoutWarning = false; 103 }; 104 105 class CountDownLatch { 106 public: 107 enum { 108 eSyncTransaction = 1 << 0, 109 eSyncInputWindows = 1 << 1, 110 }; CountDownLatch(uint32_t flags)111 explicit CountDownLatch(uint32_t flags) : mFlags(flags) {} 112 113 // True if there is no waiting condition after count down. countDown(uint32_t flag)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. wait_until(const std::chrono::nanoseconds & timeout)128 bool wait_until(const std::chrono::nanoseconds& timeout) const { 129 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 141 private: 142 uint32_t mFlags; 143 mutable std::condition_variable mCountDownComplete; 144 mutable std::mutex mMutex; 145 }; 146 147 } // namespace android 148