blob: cb5320b88cf2aff582ec4ce2c08699a04cd1739d [file] [log] [blame]
Vishnu Nair7891e962021-11-11 12:07:21 -08001/*
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#undef LOG_TAG
18#define LOG_TAG "TransactionTracing"
19#define ATRACE_TAG ATRACE_TAG_GRAPHICS
20
21#include <android-base/stringprintf.h>
22#include <log/log.h>
23#include <utils/SystemClock.h>
24#include <utils/Trace.h>
25
Vishnu Nair685cfef2022-02-02 10:01:25 -080026#include "ClientCache.h"
Vishnu Nair7891e962021-11-11 12:07:21 -080027#include "TransactionTracing.h"
Vishnu Nair685cfef2022-02-02 10:01:25 -080028#include "renderengine/ExternalTexture.h"
Vishnu Nair7891e962021-11-11 12:07:21 -080029
30namespace android {
31
Robert Carra63d52a2022-03-03 08:03:37 -080032// Keeps the binder address as the layer id so we can avoid holding the tracing lock in the
33// binder thread.
34class FlatDataMapper : public TransactionProtoParser::FlingerDataMapper {
Vishnu Nair685cfef2022-02-02 10:01:25 -080035public:
Robert Carra63d52a2022-03-03 08:03:37 -080036 virtual int64_t getLayerId(const sp<IBinder>& layerHandle) const {
Vishnu Nair685cfef2022-02-02 10:01:25 -080037 if (layerHandle == nullptr) {
38 return -1;
39 }
Robert Carra63d52a2022-03-03 08:03:37 -080040
41 return reinterpret_cast<int64_t>(layerHandle->localBinder());
Vishnu Nair685cfef2022-02-02 10:01:25 -080042 }
43
44 void getGraphicBufferPropertiesFromCache(client_cache_t cachedBuffer, uint64_t* outBufferId,
45 uint32_t* outWidth, uint32_t* outHeight,
46 int32_t* outPixelFormat,
47 uint64_t* outUsage) const override {
48 std::shared_ptr<renderengine::ExternalTexture> buffer =
49 ClientCache::getInstance().get(cachedBuffer);
50 if (!buffer || !buffer->getBuffer()) {
51 *outBufferId = 0;
52 *outWidth = 0;
53 *outHeight = 0;
54 *outPixelFormat = 0;
55 *outUsage = 0;
56 return;
57 }
58
59 *outBufferId = buffer->getId();
60 *outWidth = buffer->getWidth();
61 *outHeight = buffer->getHeight();
62 *outPixelFormat = buffer->getPixelFormat();
63 *outUsage = buffer->getUsage();
64 return;
65 }
66};
67
Robert Carra63d52a2022-03-03 08:03:37 -080068class FlingerDataMapper : public FlatDataMapper {
69 std::unordered_map<BBinder* /* layerHandle */, int32_t /* layerId */>& mLayerHandles;
70
71public:
72 FlingerDataMapper(std::unordered_map<BBinder* /* handle */, int32_t /* id */>& layerHandles)
73 : mLayerHandles(layerHandles) {}
74
75 int64_t getLayerId(const sp<IBinder>& layerHandle) const override {
76 if (layerHandle == nullptr) {
77 return -1;
78 }
79 return getLayerId(layerHandle->localBinder());
80 }
81
82 int64_t getLayerId(BBinder* localBinder) const {
83 auto it = mLayerHandles.find(localBinder);
84 if (it == mLayerHandles.end()) {
85 ALOGW("Could not find layer handle %p", localBinder);
86 return -1;
87 }
88 return it->second;
89 }
90};
91
Vishnu Nair685cfef2022-02-02 10:01:25 -080092TransactionTracing::TransactionTracing()
Robert Carra63d52a2022-03-03 08:03:37 -080093 : mProtoParser(std::make_unique<FlingerDataMapper>(mLayerHandles)),
94 mLockfreeProtoParser(std::make_unique<FlatDataMapper>()) {
Vishnu Nair7891e962021-11-11 12:07:21 -080095 std::scoped_lock lock(mTraceLock);
Dominik Laskowski46471e62022-01-14 15:34:03 -080096
97 mBuffer.setSize(mBufferSizeInBytes);
Vishnu Nair0cc69e12021-11-18 09:05:49 -080098 mStartingTimestamp = systemTime();
Vishnu Nair7891e962021-11-11 12:07:21 -080099 {
100 std::scoped_lock lock(mMainThreadLock);
Vishnu Nair7891e962021-11-11 12:07:21 -0800101 mThread = std::thread(&TransactionTracing::loop, this);
102 }
Vishnu Nair7891e962021-11-11 12:07:21 -0800103}
104
Dominik Laskowski46471e62022-01-14 15:34:03 -0800105TransactionTracing::~TransactionTracing() {
Vishnu Nair7891e962021-11-11 12:07:21 -0800106 std::thread thread;
107 {
108 std::scoped_lock lock(mMainThreadLock);
109 mDone = true;
110 mTransactionsAvailableCv.notify_all();
111 thread = std::move(mThread);
112 }
113 if (thread.joinable()) {
114 thread.join();
115 }
116
Dominik Laskowski46471e62022-01-14 15:34:03 -0800117 writeToFile();
Vishnu Nair7891e962021-11-11 12:07:21 -0800118}
119
Vishnu Naird8f5e9f2022-02-03 10:23:28 -0800120status_t TransactionTracing::writeToFile(std::string filename) {
Vishnu Nair7891e962021-11-11 12:07:21 -0800121 std::scoped_lock lock(mTraceLock);
Vishnu Nair7891e962021-11-11 12:07:21 -0800122 proto::TransactionTraceFile fileProto = createTraceFileProto();
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800123 addStartingStateToProtoLocked(fileProto);
Vishnu Naird8f5e9f2022-02-03 10:23:28 -0800124 return mBuffer.writeToFile(fileProto, filename);
Vishnu Nair7891e962021-11-11 12:07:21 -0800125}
126
127void TransactionTracing::setBufferSize(size_t bufferSizeInBytes) {
128 std::scoped_lock lock(mTraceLock);
129 mBufferSizeInBytes = bufferSizeInBytes;
Dominik Laskowski46471e62022-01-14 15:34:03 -0800130 mBuffer.setSize(mBufferSizeInBytes);
Vishnu Nair7891e962021-11-11 12:07:21 -0800131}
132
133proto::TransactionTraceFile TransactionTracing::createTraceFileProto() const {
134 proto::TransactionTraceFile proto;
135 proto.set_magic_number(uint64_t(proto::TransactionTraceFile_MagicNumber_MAGIC_NUMBER_H) << 32 |
136 proto::TransactionTraceFile_MagicNumber_MAGIC_NUMBER_L);
Kean Mariottic44fdaf2022-07-29 14:20:39 +0000137 auto timeOffsetNs = static_cast<std::uint64_t>(systemTime(SYSTEM_TIME_REALTIME) -
138 systemTime(SYSTEM_TIME_MONOTONIC));
139 proto.set_real_to_elapsed_time_offset_nanos(timeOffsetNs);
Vishnu Nair7891e962021-11-11 12:07:21 -0800140 return proto;
141}
142
143void TransactionTracing::dump(std::string& result) const {
144 std::scoped_lock lock(mTraceLock);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800145 base::StringAppendF(&result,
146 " queued transactions=%zu created layers=%zu handles=%zu states=%zu\n",
147 mQueuedTransactions.size(), mCreatedLayers.size(), mLayerHandles.size(),
148 mStartingStates.size());
Dominik Laskowski46471e62022-01-14 15:34:03 -0800149 mBuffer.dump(result);
Vishnu Nair7891e962021-11-11 12:07:21 -0800150}
151
152void TransactionTracing::addQueuedTransaction(const TransactionState& transaction) {
Robert Carra63d52a2022-03-03 08:03:37 -0800153 proto::TransactionState* state =
154 new proto::TransactionState(mLockfreeProtoParser.toProto(transaction));
155 mTransactionQueue.push(state);
Vishnu Nair7891e962021-11-11 12:07:21 -0800156}
157
Vishnu Nair286f4f92022-06-08 16:37:39 -0700158TransactionTracing::CommittedTransactions&
159TransactionTracing::findOrCreateCommittedTransactionRecord(int64_t vsyncId) {
160 for (auto& pendingTransaction : mPendingTransactions) {
161 if (pendingTransaction.vsyncId == vsyncId) {
162 return pendingTransaction;
163 }
164 }
165
Vishnu Nair7891e962021-11-11 12:07:21 -0800166 CommittedTransactions committedTransactions;
167 committedTransactions.vsyncId = vsyncId;
168 committedTransactions.timestamp = systemTime();
Vishnu Nair286f4f92022-06-08 16:37:39 -0700169 mPendingTransactions.emplace_back(committedTransactions);
170 return mPendingTransactions.back();
171}
172
173void TransactionTracing::onLayerAddedToDrawingState(int layerId, int64_t vsyncId) {
174 CommittedTransactions& committedTransactions = findOrCreateCommittedTransactionRecord(vsyncId);
175 committedTransactions.createdLayerIds.emplace_back(layerId);
176}
177
178void TransactionTracing::addCommittedTransactions(std::vector<TransactionState>& transactions,
179 int64_t vsyncId) {
180 CommittedTransactions& committedTransactions = findOrCreateCommittedTransactionRecord(vsyncId);
Vishnu Nair7891e962021-11-11 12:07:21 -0800181 committedTransactions.transactionIds.reserve(transactions.size());
182 for (const auto& transaction : transactions) {
183 committedTransactions.transactionIds.emplace_back(transaction.id);
184 }
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800185 tryPushToTracingThread();
Vishnu Nair7891e962021-11-11 12:07:21 -0800186}
187
188void TransactionTracing::loop() {
189 while (true) {
190 std::vector<CommittedTransactions> committedTransactions;
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800191 std::vector<int32_t> removedLayers;
Vishnu Nair7891e962021-11-11 12:07:21 -0800192 {
193 std::unique_lock<std::mutex> lock(mMainThreadLock);
194 base::ScopedLockAssertion assumeLocked(mMainThreadLock);
195 mTransactionsAvailableCv.wait(lock, [&]() REQUIRES(mMainThreadLock) {
196 return mDone || !mCommittedTransactions.empty();
197 });
198 if (mDone) {
199 mCommittedTransactions.clear();
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800200 mRemovedLayers.clear();
Vishnu Nair7891e962021-11-11 12:07:21 -0800201 break;
202 }
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800203
204 removedLayers = std::move(mRemovedLayers);
205 mRemovedLayers.clear();
Vishnu Nair7891e962021-11-11 12:07:21 -0800206 committedTransactions = std::move(mCommittedTransactions);
207 mCommittedTransactions.clear();
208 } // unlock mMainThreadLock
209
Vishnu Nairb8f2a2d2022-01-13 08:10:10 -0800210 if (!committedTransactions.empty() || !removedLayers.empty()) {
211 addEntry(committedTransactions, removedLayers);
212 }
Vishnu Nair7891e962021-11-11 12:07:21 -0800213 }
214}
215
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800216void TransactionTracing::addEntry(const std::vector<CommittedTransactions>& committedTransactions,
217 const std::vector<int32_t>& removedLayers) {
Vishnu Nair7891e962021-11-11 12:07:21 -0800218 ATRACE_CALL();
219 std::scoped_lock lock(mTraceLock);
Vishnu Nair62863552021-12-10 13:34:48 -0800220 std::vector<std::string> removedEntries;
221 proto::TransactionTraceEntry entryProto;
Robert Carra63d52a2022-03-03 08:03:37 -0800222
223 while (auto incomingTransaction = mTransactionQueue.pop()) {
224 auto transaction = *incomingTransaction;
225 int32_t layerCount = transaction.layer_changes_size();
226 for (int i = 0; i < layerCount; i++) {
227 auto layer = transaction.mutable_layer_changes(i);
228 layer->set_layer_id(
229 mProtoParser.mMapper->getLayerId(reinterpret_cast<BBinder*>(layer->layer_id())));
230 if ((layer->what() & layer_state_t::eReparent) && layer->parent_id() != -1) {
231 layer->set_parent_id(
232 mProtoParser.mMapper->getLayerId(reinterpret_cast<BBinder*>(
233 layer->parent_id())));
234 }
235
236 if ((layer->what() & layer_state_t::eRelativeLayerChanged) &&
237 layer->relative_parent_id() != -1) {
238 layer->set_relative_parent_id(
239 mProtoParser.mMapper->getLayerId(reinterpret_cast<BBinder*>(
240 layer->relative_parent_id())));
241 }
242
243 if (layer->has_window_info_handle() &&
244 layer->window_info_handle().crop_layer_id() != -1) {
245 auto input = layer->mutable_window_info_handle();
246 input->set_crop_layer_id(
247 mProtoParser.mMapper->getLayerId(reinterpret_cast<BBinder*>(
248 input->crop_layer_id())));
249 }
250 }
251 mQueuedTransactions[incomingTransaction->transaction_id()] = transaction;
252 delete incomingTransaction;
253 }
Vishnu Nair7891e962021-11-11 12:07:21 -0800254 for (const CommittedTransactions& entry : committedTransactions) {
Vishnu Nair7891e962021-11-11 12:07:21 -0800255 entryProto.set_elapsed_realtime_nanos(entry.timestamp);
256 entryProto.set_vsync_id(entry.vsyncId);
Vishnu Nair286f4f92022-06-08 16:37:39 -0700257 entryProto.mutable_added_layers()->Reserve(
258 static_cast<int32_t>(entry.createdLayerIds.size()));
259
260 for (const int32_t& id : entry.createdLayerIds) {
261 auto it = mCreatedLayers.find(id);
262 if (it != mCreatedLayers.end()) {
263 entryProto.mutable_added_layers()->Add(std::move(it->second));
264 mCreatedLayers.erase(it);
265 } else {
266 ALOGW("Could not created layer with id %d", id);
267 }
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800268 }
Vishnu Nair286f4f92022-06-08 16:37:39 -0700269
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800270 entryProto.mutable_removed_layers()->Reserve(static_cast<int32_t>(removedLayers.size()));
271 for (auto& removedLayer : removedLayers) {
272 entryProto.mutable_removed_layers()->Add(removedLayer);
Vishnu Nair286f4f92022-06-08 16:37:39 -0700273 mCreatedLayers.erase(removedLayer);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800274 }
Vishnu Nair7891e962021-11-11 12:07:21 -0800275 entryProto.mutable_transactions()->Reserve(
276 static_cast<int32_t>(entry.transactionIds.size()));
277 for (const uint64_t& id : entry.transactionIds) {
278 auto it = mQueuedTransactions.find(id);
279 if (it != mQueuedTransactions.end()) {
280 entryProto.mutable_transactions()->Add(std::move(it->second));
281 mQueuedTransactions.erase(it);
282 } else {
Vishnu Nair047fb332021-12-09 09:54:36 -0800283 ALOGW("Could not find transaction id %" PRIu64, id);
Vishnu Nair7891e962021-11-11 12:07:21 -0800284 }
285 }
Vishnu Nair62863552021-12-10 13:34:48 -0800286
Vishnu Nair3e40cdd2022-06-08 16:50:17 -0700287 entryProto.mutable_removed_layer_handles()->Reserve(
288 static_cast<int32_t>(mRemovedLayerHandles.size()));
289 for (auto& [handle, layerId] : mRemovedLayerHandles) {
290 entryProto.mutable_removed_layer_handles()->Add(layerId);
291 mLayerHandles.erase(handle);
292 }
293 mRemovedLayerHandles.clear();
294
Vishnu Nair62863552021-12-10 13:34:48 -0800295 std::string serializedProto;
296 entryProto.SerializeToString(&serializedProto);
297 entryProto.Clear();
Dominik Laskowski46471e62022-01-14 15:34:03 -0800298 std::vector<std::string> entries = mBuffer.emplace(std::move(serializedProto));
Vishnu Nair62863552021-12-10 13:34:48 -0800299 removedEntries.reserve(removedEntries.size() + entries.size());
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800300 removedEntries.insert(removedEntries.end(), std::make_move_iterator(entries.begin()),
301 std::make_move_iterator(entries.end()));
302 }
303
Vishnu Nair62863552021-12-10 13:34:48 -0800304 proto::TransactionTraceEntry removedEntryProto;
305 for (const std::string& removedEntry : removedEntries) {
306 removedEntryProto.ParseFromString(removedEntry);
307 updateStartingStateLocked(removedEntryProto);
308 removedEntryProto.Clear();
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800309 }
310 mTransactionsAddedToBufferCv.notify_one();
311}
312
313void TransactionTracing::flush(int64_t vsyncId) {
314 while (!mPendingTransactions.empty() || !mPendingRemovedLayers.empty()) {
315 tryPushToTracingThread();
316 }
317 std::unique_lock<std::mutex> lock(mTraceLock);
318 base::ScopedLockAssertion assumeLocked(mTraceLock);
319 mTransactionsAddedToBufferCv.wait(lock, [&]() REQUIRES(mTraceLock) {
Vishnu Nair62863552021-12-10 13:34:48 -0800320 proto::TransactionTraceEntry entry;
Dominik Laskowski46471e62022-01-14 15:34:03 -0800321 if (mBuffer.used() > 0) {
322 entry.ParseFromString(mBuffer.back());
Vishnu Nair62863552021-12-10 13:34:48 -0800323 }
Dominik Laskowski46471e62022-01-14 15:34:03 -0800324 return mBuffer.used() > 0 && entry.vsync_id() >= vsyncId;
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800325 });
326}
327
328void TransactionTracing::onLayerAdded(BBinder* layerHandle, int layerId, const std::string& name,
329 uint32_t flags, int parentId) {
330 std::scoped_lock lock(mTraceLock);
Vishnu Nair84125ac2021-12-02 08:47:48 -0800331 TracingLayerCreationArgs args{layerId, name, flags, parentId, -1 /* mirrorFromId */};
Vishnu Nair047fb332021-12-09 09:54:36 -0800332 if (mLayerHandles.find(layerHandle) != mLayerHandles.end()) {
333 ALOGW("Duplicate handles found. %p", layerHandle);
334 }
Vishnu Nair84125ac2021-12-02 08:47:48 -0800335 mLayerHandles[layerHandle] = layerId;
Vishnu Nair286f4f92022-06-08 16:37:39 -0700336 mCreatedLayers[layerId] = mProtoParser.toProto(args);
Vishnu Nair84125ac2021-12-02 08:47:48 -0800337}
338
339void TransactionTracing::onMirrorLayerAdded(BBinder* layerHandle, int layerId,
340 const std::string& name, int mirrorFromId) {
341 std::scoped_lock lock(mTraceLock);
342 TracingLayerCreationArgs args{layerId, name, 0 /* flags */, -1 /* parentId */, mirrorFromId};
Vishnu Nair047fb332021-12-09 09:54:36 -0800343 if (mLayerHandles.find(layerHandle) != mLayerHandles.end()) {
344 ALOGW("Duplicate handles found. %p", layerHandle);
345 }
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800346 mLayerHandles[layerHandle] = layerId;
Vishnu Nair286f4f92022-06-08 16:37:39 -0700347 mCreatedLayers[layerId] = mProtoParser.toProto(args);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800348}
349
350void TransactionTracing::onLayerRemoved(int32_t layerId) {
351 mPendingRemovedLayers.emplace_back(layerId);
352 tryPushToTracingThread();
353}
354
Vishnu Nair047fb332021-12-09 09:54:36 -0800355void TransactionTracing::onHandleRemoved(BBinder* layerHandle) {
356 std::scoped_lock lock(mTraceLock);
Vishnu Naird37343b2022-01-12 16:18:56 -0800357 auto it = mLayerHandles.find(layerHandle);
358 if (it == mLayerHandles.end()) {
359 ALOGW("handle not found. %p", layerHandle);
360 return;
361 }
Vishnu Nair3e40cdd2022-06-08 16:50:17 -0700362 mRemovedLayerHandles.emplace_back(layerHandle, it->second);
Vishnu Nair047fb332021-12-09 09:54:36 -0800363}
364
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800365void TransactionTracing::tryPushToTracingThread() {
366 // Try to acquire the lock from main thread.
367 if (mMainThreadLock.try_lock()) {
368 // We got the lock! Collect any pending transactions and continue.
369 mCommittedTransactions.insert(mCommittedTransactions.end(),
370 std::make_move_iterator(mPendingTransactions.begin()),
371 std::make_move_iterator(mPendingTransactions.end()));
372 mPendingTransactions.clear();
373 mRemovedLayers.insert(mRemovedLayers.end(), mPendingRemovedLayers.begin(),
374 mPendingRemovedLayers.end());
375 mPendingRemovedLayers.clear();
376 mTransactionsAvailableCv.notify_one();
377 mMainThreadLock.unlock();
378 } else {
379 ALOGV("Couldn't get lock");
Vishnu Nair7891e962021-11-11 12:07:21 -0800380 }
381}
382
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800383void TransactionTracing::updateStartingStateLocked(
384 const proto::TransactionTraceEntry& removedEntry) {
Vishnu Nairb8f2a2d2022-01-13 08:10:10 -0800385 mStartingTimestamp = removedEntry.elapsed_realtime_nanos();
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800386 // Keep track of layer starting state so we can reconstruct the layer state as we purge
387 // transactions from the buffer.
388 for (const proto::LayerCreationArgs& addedLayer : removedEntry.added_layers()) {
389 TracingLayerState& startingState = mStartingStates[addedLayer.layer_id()];
390 startingState.layerId = addedLayer.layer_id();
Vishnu Nair685cfef2022-02-02 10:01:25 -0800391 mProtoParser.fromProto(addedLayer, startingState.args);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800392 }
393
394 // Merge layer states to starting transaction state.
395 for (const proto::TransactionState& transaction : removedEntry.transactions()) {
396 for (const proto::LayerState& layerState : transaction.layer_changes()) {
Robert Carra63d52a2022-03-03 08:03:37 -0800397 auto it = mStartingStates.find((int32_t)layerState.layer_id());
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800398 if (it == mStartingStates.end()) {
Robert Carra63d52a2022-03-03 08:03:37 -0800399 ALOGW("Could not find layer id %d", (int32_t)layerState.layer_id());
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800400 continue;
401 }
Vishnu Nair685cfef2022-02-02 10:01:25 -0800402 mProtoParser.mergeFromProto(layerState, it->second);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800403 }
404 }
405
Vishnu Nair3e40cdd2022-06-08 16:50:17 -0700406 for (const int32_t removedLayerHandleId : removedEntry.removed_layer_handles()) {
407 mRemovedLayerHandlesAtStart.insert(removedLayerHandleId);
408 }
409
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800410 // Clean up stale starting states since the layer has been removed and the buffer does not
411 // contain any references to the layer.
412 for (const int32_t removedLayerId : removedEntry.removed_layers()) {
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800413 mStartingStates.erase(removedLayerId);
Vishnu Nair3e40cdd2022-06-08 16:50:17 -0700414 mRemovedLayerHandlesAtStart.erase(removedLayerId);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800415 }
416}
417
418void TransactionTracing::addStartingStateToProtoLocked(proto::TransactionTraceFile& proto) {
Vishnu Nair84125ac2021-12-02 08:47:48 -0800419 if (mStartingStates.size() == 0) {
420 return;
421 }
422
Vishnu Nairb8f2a2d2022-01-13 08:10:10 -0800423 proto::TransactionTraceEntry* entryProto = proto.add_entry();
424 entryProto->set_elapsed_realtime_nanos(mStartingTimestamp);
425 entryProto->set_vsync_id(0);
426
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800427 entryProto->mutable_added_layers()->Reserve(static_cast<int32_t>(mStartingStates.size()));
428 for (auto& [layerId, state] : mStartingStates) {
Vishnu Nair685cfef2022-02-02 10:01:25 -0800429 entryProto->mutable_added_layers()->Add(mProtoParser.toProto(state.args));
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800430 }
431
Vishnu Nair685cfef2022-02-02 10:01:25 -0800432 proto::TransactionState transactionProto = mProtoParser.toProto(mStartingStates);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800433 transactionProto.set_vsync_id(0);
434 transactionProto.set_post_time(mStartingTimestamp);
435 entryProto->mutable_transactions()->Add(std::move(transactionProto));
Vishnu Nair3e40cdd2022-06-08 16:50:17 -0700436
437 entryProto->mutable_removed_layer_handles()->Reserve(
438 static_cast<int32_t>(mRemovedLayerHandlesAtStart.size()));
439 for (const int32_t removedLayerHandleId : mRemovedLayerHandlesAtStart) {
440 entryProto->mutable_removed_layer_handles()->Add(removedLayerHandleId);
441 }
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800442}
443
444proto::TransactionTraceFile TransactionTracing::writeToProto() {
445 std::scoped_lock<std::mutex> lock(mTraceLock);
446 proto::TransactionTraceFile proto = createTraceFileProto();
447 addStartingStateToProtoLocked(proto);
Dominik Laskowski46471e62022-01-14 15:34:03 -0800448 mBuffer.writeToProto(proto);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800449 return proto;
Vishnu Nair7891e962021-11-11 12:07:21 -0800450}
451
452} // namespace android