• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 #define LOG_TAG "TransactionState"
18 #include <gui/LayerState.h>
19 #include <gui/SurfaceComposerClient.h>
20 #include <gui/TransactionState.h>
21 #include <private/gui/ParcelUtils.h>
22 #include <algorithm>
23 
24 namespace android {
25 
writeToParcel(Parcel * parcel) const26 status_t TransactionState::writeToParcel(Parcel* parcel) const {
27     SAFE_PARCEL(parcel->writeUint64, mId);
28     SAFE_PARCEL(parcel->writeUint32, mFlags);
29     SAFE_PARCEL(parcel->writeInt64, mDesiredPresentTime);
30     SAFE_PARCEL(parcel->writeBool, mIsAutoTimestamp);
31     SAFE_PARCEL(parcel->writeParcelable, mFrameTimelineInfo);
32     SAFE_PARCEL(parcel->writeStrongBinder, mApplyToken);
33     SAFE_PARCEL(parcel->writeBool, mMayContainBuffer);
34     SAFE_PARCEL(parcel->writeBool, mLogCallPoints);
35 
36     SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mDisplayStates.size()));
37     for (auto const& displayState : mDisplayStates) {
38         displayState.write(*parcel);
39     }
40     SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mComposerStates.size()));
41     for (auto const& composerState : mComposerStates) {
42         composerState.write(*parcel);
43     }
44 
45     mInputWindowCommands.write(*parcel);
46     SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mUncacheBuffers.size()));
47     for (const client_cache_t& uncacheBuffer : mUncacheBuffers) {
48         SAFE_PARCEL(parcel->writeStrongBinder, uncacheBuffer.token.promote());
49         SAFE_PARCEL(parcel->writeUint64, uncacheBuffer.id);
50     }
51 
52     SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mMergedTransactionIds.size()));
53     for (auto mergedTransactionId : mMergedTransactionIds) {
54         SAFE_PARCEL(parcel->writeUint64, mergedTransactionId);
55     }
56 
57     SAFE_PARCEL(parcel->writeBool, mHasListenerCallbacks);
58     SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mListenerCallbacks.size()));
59     for (const auto& [listener, callbackIds] : mListenerCallbacks) {
60         SAFE_PARCEL(parcel->writeStrongBinder, listener);
61         SAFE_PARCEL(parcel->writeParcelableVector, callbackIds);
62     }
63 
64     return NO_ERROR;
65 }
66 
readFromParcel(const Parcel * parcel)67 status_t TransactionState::readFromParcel(const Parcel* parcel) {
68     SAFE_PARCEL(parcel->readUint64, &mId);
69     SAFE_PARCEL(parcel->readUint32, &mFlags);
70     SAFE_PARCEL(parcel->readInt64, &mDesiredPresentTime);
71     SAFE_PARCEL(parcel->readBool, &mIsAutoTimestamp);
72     SAFE_PARCEL(parcel->readParcelable, &mFrameTimelineInfo);
73     SAFE_PARCEL(parcel->readNullableStrongBinder, &mApplyToken);
74     SAFE_PARCEL(parcel->readBool, &mMayContainBuffer);
75     SAFE_PARCEL(parcel->readBool, &mLogCallPoints);
76 
77     uint32_t count;
78     SAFE_PARCEL_READ_SIZE(parcel->readUint32, &count, parcel->dataSize())
79     mDisplayStates.clear();
80     mDisplayStates.reserve(count);
81     for (size_t i = 0; i < count; i++) {
82         DisplayState displayState;
83         if (displayState.read(*parcel) == BAD_VALUE) {
84             return BAD_VALUE;
85         }
86         mDisplayStates.emplace_back(std::move(displayState));
87     }
88 
89     SAFE_PARCEL_READ_SIZE(parcel->readUint32, &count, parcel->dataSize())
90     mComposerStates.clear();
91     mComposerStates.reserve(count);
92     for (size_t i = 0; i < count; i++) {
93         ComposerState composerState;
94         if (composerState.read(*parcel) == BAD_VALUE) {
95             return BAD_VALUE;
96         }
97         mComposerStates.emplace_back(std::move(composerState));
98     }
99 
100     if (status_t status = mInputWindowCommands.read(*parcel) != NO_ERROR) {
101         return status;
102     }
103 
104     SAFE_PARCEL_READ_SIZE(parcel->readUint32, &count, parcel->dataSize())
105     mUncacheBuffers.clear();
106     mUncacheBuffers.reserve(count);
107     for (size_t i = 0; i < count; i++) {
108         client_cache_t client_cache;
109         sp<IBinder> tmpBinder;
110         SAFE_PARCEL(parcel->readStrongBinder, &tmpBinder);
111         client_cache.token = tmpBinder;
112         SAFE_PARCEL(parcel->readUint64, &client_cache.id);
113         mUncacheBuffers.emplace_back(std::move(client_cache));
114     }
115 
116     SAFE_PARCEL_READ_SIZE(parcel->readUint32, &count, parcel->dataSize())
117     mMergedTransactionIds.clear();
118     mMergedTransactionIds.resize(count);
119     for (size_t i = 0; i < count; i++) {
120         SAFE_PARCEL(parcel->readUint64, &mMergedTransactionIds[i]);
121     }
122 
123     SAFE_PARCEL(parcel->readBool, &mHasListenerCallbacks);
124     SAFE_PARCEL_READ_SIZE(parcel->readUint32, &count, parcel->dataSize());
125     mListenerCallbacks.clear();
126     mListenerCallbacks.reserve(count);
127     for (uint32_t i = 0; i < count; i++) {
128         sp<IBinder> tmpBinder;
129         SAFE_PARCEL(parcel->readStrongBinder, &tmpBinder);
130         std::vector<CallbackId> callbackIds;
131         SAFE_PARCEL(parcel->readParcelableVector, &callbackIds);
132         mListenerCallbacks.emplace_back(tmpBinder, callbackIds);
133     }
134 
135     return NO_ERROR;
136 }
137 
merge(TransactionState && other,const std::function<void (layer_state_t &)> & onBufferOverwrite)138 void TransactionState::merge(TransactionState&& other,
139                              const std::function<void(layer_state_t&)>& onBufferOverwrite) {
140     while (mMergedTransactionIds.size() + other.mMergedTransactionIds.size() >
141                    MAX_MERGE_HISTORY_LENGTH - 1 &&
142            mMergedTransactionIds.size() > 0) {
143         mMergedTransactionIds.pop_back();
144     }
145     if (other.mMergedTransactionIds.size() == MAX_MERGE_HISTORY_LENGTH) {
146         mMergedTransactionIds.insert(mMergedTransactionIds.begin(),
147                                      other.mMergedTransactionIds.begin(),
148                                      other.mMergedTransactionIds.end() - 1);
149     } else if (other.mMergedTransactionIds.size() > 0u) {
150         mMergedTransactionIds.insert(mMergedTransactionIds.begin(),
151                                      other.mMergedTransactionIds.begin(),
152                                      other.mMergedTransactionIds.end());
153     }
154     mMergedTransactionIds.insert(mMergedTransactionIds.begin(), other.mId);
155 
156     for (auto const& otherState : other.mComposerStates) {
157         if (auto it = std::find_if(mComposerStates.begin(), mComposerStates.end(),
158                                    [&otherState](const auto& composerState) {
159                                        return composerState.state.surface ==
160                                                otherState.state.surface;
161                                    });
162             it != mComposerStates.end()) {
163             if (otherState.state.what & layer_state_t::eBufferChanged) {
164                 onBufferOverwrite(it->state);
165             }
166             it->state.merge(otherState.state);
167         } else {
168             mComposerStates.push_back(otherState);
169         }
170     }
171 
172     for (auto const& state : other.mDisplayStates) {
173         if (auto it = std::find_if(mDisplayStates.begin(), mDisplayStates.end(),
174                                    [&state](const auto& displayState) {
175                                        return displayState.token == state.token;
176                                    });
177             it != mDisplayStates.end()) {
178             it->merge(state);
179         } else {
180             mDisplayStates.push_back(state);
181         }
182     }
183 
184     for (const auto& cacheId : other.mUncacheBuffers) {
185         mUncacheBuffers.push_back(cacheId);
186     }
187 
188     mInputWindowCommands.merge(other.mInputWindowCommands);
189     // TODO(b/385156191) Consider merging desired present time.
190     mFlags |= other.mFlags;
191     mMayContainBuffer |= other.mMayContainBuffer;
192     mLogCallPoints |= other.mLogCallPoints;
193 
194     // mApplyToken is explicitly not merged. Token should be set before applying the transactions to
195     // make synchronization decisions a bit simpler.
196     mergeFrameTimelineInfo(other.mFrameTimelineInfo);
197     other.clear();
198 }
199 
200 // copied from FrameTimelineInfo::merge()
mergeFrameTimelineInfo(const FrameTimelineInfo & other)201 void TransactionState::mergeFrameTimelineInfo(const FrameTimelineInfo& other) {
202     // When merging vsync Ids we take the oldest valid one
203     if (mFrameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID &&
204         other.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) {
205         if (other.vsyncId > mFrameTimelineInfo.vsyncId) {
206             mFrameTimelineInfo = other;
207         }
208     } else if (mFrameTimelineInfo.vsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) {
209         mFrameTimelineInfo = other;
210     }
211 }
212 
clear()213 void TransactionState::clear() {
214     mComposerStates.clear();
215     mDisplayStates.clear();
216     mListenerCallbacks.clear();
217     mHasListenerCallbacks = false;
218     mInputWindowCommands.clear();
219     mUncacheBuffers.clear();
220     mDesiredPresentTime = 0;
221     mIsAutoTimestamp = true;
222     mApplyToken = nullptr;
223     mFrameTimelineInfo = {};
224     mMergedTransactionIds.clear();
225     mFlags = 0;
226     mMayContainBuffer = false;
227     mLogCallPoints = false;
228 }
229 
getLayerState(const sp<SurfaceControl> & sc)230 layer_state_t* TransactionState::getLayerState(const sp<SurfaceControl>& sc) {
231     auto handle = sc->getLayerStateHandle();
232     if (auto it = std::find_if(mComposerStates.begin(), mComposerStates.end(),
233                                [&handle](const auto& composerState) {
234                                    return composerState.state.surface == handle;
235                                });
236         it != mComposerStates.end()) {
237         return &it->state;
238     }
239 
240     // we don't have it, add an initialized layer_state to our list
241     ComposerState s;
242     s.state.surface = handle;
243     s.state.layerId = sc->getLayerId();
244     mComposerStates.push_back(s);
245 
246     return &mComposerStates.back().state;
247 }
248 
getDisplayState(const sp<IBinder> & token)249 DisplayState& TransactionState::getDisplayState(const sp<IBinder>& token) {
250     if (auto it = std::find_if(mDisplayStates.begin(), mDisplayStates.end(),
251                                [token](const auto& display) { return display.token == token; });
252         it != mDisplayStates.end()) {
253         return *it;
254     }
255 
256     // If display state doesn't exist, add a new one.
257     DisplayState s;
258     s.token = token;
259     mDisplayStates.push_back(s);
260     return mDisplayStates.back();
261 }
262 
263 }; // namespace android
264