blob: 74541ace0b5e0b0a028a9ffbc24f863f6feb1452 [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#include <gmock/gmock.h>
18#include <gtest/gtest.h>
19
20#include <gui/SurfaceComposerClient.h>
Vishnu Nair81750622023-03-08 15:02:06 -080021#include <cstdint>
22#include "Client.h"
Vishnu Nair7891e962021-11-11 12:07:21 -080023
Vishnu Nair81750622023-03-08 15:02:06 -080024#include "FrontEnd/LayerCreationArgs.h"
25#include "FrontEnd/Update.h"
Vishnu Nair7891e962021-11-11 12:07:21 -080026#include "Tracing/RingBuffer.h"
27#include "Tracing/TransactionTracing.h"
28
29using namespace android::surfaceflinger;
30
31namespace android {
32
33class TransactionTracingTest : public testing::Test {
34protected:
Vishnu Nair0cc69e12021-11-18 09:05:49 -080035 static constexpr size_t SMALL_BUFFER_SIZE = 1024;
Dominik Laskowski46471e62022-01-14 15:34:03 -080036 TransactionTracing mTracing;
Vishnu Nair7891e962021-11-11 12:07:21 -080037
Dominik Laskowski46471e62022-01-14 15:34:03 -080038 void flush(int64_t vsyncId) { mTracing.flush(vsyncId); }
39 proto::TransactionTraceFile writeToProto() { return mTracing.writeToProto(); }
Vishnu Nair7891e962021-11-11 12:07:21 -080040
Dominik Laskowski46471e62022-01-14 15:34:03 -080041 proto::TransactionTraceEntry bufferFront() {
42 std::scoped_lock<std::mutex> lock(mTracing.mTraceLock);
Vishnu Nair62863552021-12-10 13:34:48 -080043 proto::TransactionTraceEntry entry;
Dominik Laskowski46471e62022-01-14 15:34:03 -080044 entry.ParseFromString(mTracing.mBuffer.front());
Vishnu Nair62863552021-12-10 13:34:48 -080045 return entry;
Vishnu Nair7891e962021-11-11 12:07:21 -080046 }
47
Vishnu Nair0cc69e12021-11-18 09:05:49 -080048 void queueAndCommitTransaction(int64_t vsyncId) {
Vishnu Nair81750622023-03-08 15:02:06 -080049 frontend::Update update;
Vishnu Nair0cc69e12021-11-18 09:05:49 -080050 TransactionState transaction;
51 transaction.id = static_cast<uint64_t>(vsyncId * 3);
52 transaction.originUid = 1;
53 transaction.originPid = 2;
Dominik Laskowski46471e62022-01-14 15:34:03 -080054 mTracing.addQueuedTransaction(transaction);
Vishnu Nair0cc69e12021-11-18 09:05:49 -080055 std::vector<TransactionState> transactions;
Vishnu Nair81750622023-03-08 15:02:06 -080056 update.transactions.emplace_back(transaction);
57 mTracing.addCommittedTransactions(vsyncId, 0, update, {}, false);
Vishnu Nair0cc69e12021-11-18 09:05:49 -080058 flush(vsyncId);
Vishnu Nair7891e962021-11-11 12:07:21 -080059 }
60
Vishnu Nair7891e962021-11-11 12:07:21 -080061 void verifyEntry(const proto::TransactionTraceEntry& actualProto,
Dominik Laskowski46471e62022-01-14 15:34:03 -080062 const std::vector<TransactionState>& expectedTransactions,
Vishnu Nair7891e962021-11-11 12:07:21 -080063 int64_t expectedVsyncId) {
64 EXPECT_EQ(actualProto.vsync_id(), expectedVsyncId);
Vishnu Nair81750622023-03-08 15:02:06 -080065 ASSERT_EQ(actualProto.transactions().size(),
Vishnu Nair7891e962021-11-11 12:07:21 -080066 static_cast<int32_t>(expectedTransactions.size()));
67 for (uint32_t i = 0; i < expectedTransactions.size(); i++) {
68 EXPECT_EQ(actualProto.transactions(static_cast<int32_t>(i)).pid(),
69 expectedTransactions[i].originPid);
70 }
71 }
Vishnu Nair81750622023-03-08 15:02:06 -080072
73 LayerCreationArgs getLayerCreationArgs(uint32_t layerId, uint32_t parentId,
74 uint32_t layerIdToMirror, uint32_t flags,
75 bool addToRoot) {
76 LayerCreationArgs args;
77 args.sequence = layerId;
78 args.parentId = parentId;
79 args.layerIdToMirror = layerIdToMirror;
80 args.flags = flags;
81 args.addToRoot = addToRoot;
82 return args;
83 }
Vishnu Nair7891e962021-11-11 12:07:21 -080084};
85
Vishnu Nair7891e962021-11-11 12:07:21 -080086TEST_F(TransactionTracingTest, addTransactions) {
Vishnu Nair7891e962021-11-11 12:07:21 -080087 std::vector<TransactionState> transactions;
88 transactions.reserve(100);
89 for (uint64_t i = 0; i < 100; i++) {
90 TransactionState transaction;
91 transaction.id = i;
92 transaction.originPid = static_cast<int32_t>(i);
93 transactions.emplace_back(transaction);
Dominik Laskowski46471e62022-01-14 15:34:03 -080094 mTracing.addQueuedTransaction(transaction);
Vishnu Nair7891e962021-11-11 12:07:21 -080095 }
96
97 // Split incoming transactions into two and commit them in reverse order to test out of order
98 // commits.
Vishnu Nair7891e962021-11-11 12:07:21 -080099 int64_t firstTransactionSetVsyncId = 42;
Vishnu Nair81750622023-03-08 15:02:06 -0800100 frontend::Update firstUpdate;
101 firstUpdate.transactions =
102 std::vector<TransactionState>(transactions.begin() + 50, transactions.end());
103 mTracing.addCommittedTransactions(firstTransactionSetVsyncId, 0, firstUpdate, {}, false);
Vishnu Nair7891e962021-11-11 12:07:21 -0800104
105 int64_t secondTransactionSetVsyncId = 43;
Vishnu Nair81750622023-03-08 15:02:06 -0800106 frontend::Update secondUpdate;
107 secondUpdate.transactions =
Vishnu Nair7891e962021-11-11 12:07:21 -0800108 std::vector<TransactionState>(transactions.begin(), transactions.begin() + 50);
Vishnu Nair81750622023-03-08 15:02:06 -0800109 mTracing.addCommittedTransactions(secondTransactionSetVsyncId, 0, secondUpdate, {}, false);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800110 flush(secondTransactionSetVsyncId);
Vishnu Nair7891e962021-11-11 12:07:21 -0800111
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800112 proto::TransactionTraceFile proto = writeToProto();
Vishnu Nair81750622023-03-08 15:02:06 -0800113 ASSERT_EQ(proto.entry().size(), 2);
114 verifyEntry(proto.entry(0), firstUpdate.transactions, firstTransactionSetVsyncId);
115 verifyEntry(proto.entry(1), secondUpdate.transactions, secondTransactionSetVsyncId);
Vishnu Nair7891e962021-11-11 12:07:21 -0800116}
117
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800118class TransactionTracingLayerHandlingTest : public TransactionTracingTest {
119protected:
120 void SetUp() override {
Dominik Laskowski46471e62022-01-14 15:34:03 -0800121 mTracing.setBufferSize(SMALL_BUFFER_SIZE);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800122
Vishnu Nair81750622023-03-08 15:02:06 -0800123 // add layers and add some layer transaction
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800124 {
Vishnu Nair81750622023-03-08 15:02:06 -0800125 frontend::Update update;
126 update.layerCreationArgs.emplace_back(std::move(
127 getLayerCreationArgs(mParentLayerId, /*parentId=*/UNASSIGNED_LAYER_ID,
128 /*layerIdToMirror=*/UNASSIGNED_LAYER_ID, /*flags=*/123,
129 /*addToRoot=*/true)));
130 update.layerCreationArgs.emplace_back(std::move(
131 getLayerCreationArgs(mChildLayerId, mParentLayerId,
132 /*layerIdToMirror=*/UNASSIGNED_LAYER_ID, /*flags=*/456,
133 /*addToRoot=*/true)));
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800134 TransactionState transaction;
135 transaction.id = 50;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000136 ResolvedComposerState layerState;
Vishnu Nair81750622023-03-08 15:02:06 -0800137 layerState.layerId = mParentLayerId;
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800138 layerState.state.what = layer_state_t::eLayerChanged;
139 layerState.state.z = 42;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000140 transaction.states.emplace_back(layerState);
141 ResolvedComposerState childState;
Vishnu Nair81750622023-03-08 15:02:06 -0800142 childState.layerId = mChildLayerId;
Vishnu Nair473838d2021-12-08 09:46:02 -0800143 childState.state.what = layer_state_t::eLayerChanged;
144 childState.state.z = 43;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000145 transaction.states.emplace_back(childState);
Dominik Laskowski46471e62022-01-14 15:34:03 -0800146 mTracing.addQueuedTransaction(transaction);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800147
Vishnu Nair81750622023-03-08 15:02:06 -0800148 update.transactions.emplace_back(transaction);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800149 VSYNC_ID_FIRST_LAYER_CHANGE = ++mVsyncId;
Vishnu Nair81750622023-03-08 15:02:06 -0800150 mTracing.addCommittedTransactions(VSYNC_ID_FIRST_LAYER_CHANGE, 0, update, {}, false);
151
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800152 flush(VSYNC_ID_FIRST_LAYER_CHANGE);
153 }
154
155 // add transactions that modify the layer state further so we can test that layer state
156 // gets merged
157 {
158 TransactionState transaction;
159 transaction.id = 51;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000160 ResolvedComposerState layerState;
Vishnu Nair81750622023-03-08 15:02:06 -0800161 layerState.layerId = mParentLayerId;
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800162 layerState.state.what = layer_state_t::eLayerChanged | layer_state_t::ePositionChanged;
163 layerState.state.z = 41;
164 layerState.state.x = 22;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000165 transaction.states.emplace_back(layerState);
Dominik Laskowski46471e62022-01-14 15:34:03 -0800166 mTracing.addQueuedTransaction(transaction);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800167
Vishnu Nair81750622023-03-08 15:02:06 -0800168 frontend::Update update;
169 update.transactions.emplace_back(transaction);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800170 VSYNC_ID_SECOND_LAYER_CHANGE = ++mVsyncId;
Vishnu Nair81750622023-03-08 15:02:06 -0800171 mTracing.addCommittedTransactions(VSYNC_ID_SECOND_LAYER_CHANGE, 0, update, {}, false);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800172 flush(VSYNC_ID_SECOND_LAYER_CHANGE);
173 }
174
175 // remove child layer
Dominik Laskowski46471e62022-01-14 15:34:03 -0800176 mTracing.onLayerRemoved(2);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800177 VSYNC_ID_CHILD_LAYER_REMOVED = ++mVsyncId;
178 queueAndCommitTransaction(VSYNC_ID_CHILD_LAYER_REMOVED);
179
180 // remove layer
Dominik Laskowski46471e62022-01-14 15:34:03 -0800181 mTracing.onLayerRemoved(1);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800182 queueAndCommitTransaction(++mVsyncId);
183 }
184
Vishnu Nair81750622023-03-08 15:02:06 -0800185 uint32_t mParentLayerId = 1;
186 uint32_t mChildLayerId = 2;
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800187 int64_t mVsyncId = 0;
188 int64_t VSYNC_ID_FIRST_LAYER_CHANGE;
189 int64_t VSYNC_ID_SECOND_LAYER_CHANGE;
190 int64_t VSYNC_ID_CHILD_LAYER_REMOVED;
191};
192
193TEST_F(TransactionTracingLayerHandlingTest, addStartingState) {
194 // add transactions until we drop the transaction with the first layer change
195 while (bufferFront().vsync_id() <= VSYNC_ID_FIRST_LAYER_CHANGE) {
196 queueAndCommitTransaction(++mVsyncId);
197 }
198 proto::TransactionTraceFile proto = writeToProto();
199 // verify we can still retrieve the layer change from the first entry containing starting
200 // states.
201 EXPECT_GT(proto.entry().size(), 0);
Vishnu Nair685cfef2022-02-02 10:01:25 -0800202 EXPECT_EQ(proto.entry(0).transactions().size(), 1);
203 EXPECT_EQ(proto.entry(0).added_layers().size(), 2);
Vishnu Nair473838d2021-12-08 09:46:02 -0800204 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 2);
205 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).layer_id(), mParentLayerId);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800206 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).z(), 42);
Vishnu Nair473838d2021-12-08 09:46:02 -0800207 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(1).layer_id(), mChildLayerId);
208 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(1).z(), 43);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800209}
210
211TEST_F(TransactionTracingLayerHandlingTest, updateStartingState) {
212 // add transactions until we drop the transaction with the second layer change
213 while (bufferFront().vsync_id() <= VSYNC_ID_SECOND_LAYER_CHANGE) {
214 queueAndCommitTransaction(++mVsyncId);
215 }
216 proto::TransactionTraceFile proto = writeToProto();
217 // verify starting states are updated correctly
218 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).z(), 41);
219}
220
221TEST_F(TransactionTracingLayerHandlingTest, removeStartingState) {
222 // add transactions until we drop the transaction which removes the child layer
223 while (bufferFront().vsync_id() <= VSYNC_ID_CHILD_LAYER_REMOVED) {
224 queueAndCommitTransaction(++mVsyncId);
225 }
226 proto::TransactionTraceFile proto = writeToProto();
227 // verify the child layer has been removed from the trace
228 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 1);
229 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).layer_id(), mParentLayerId);
230}
231
232TEST_F(TransactionTracingLayerHandlingTest, startingStateSurvivesBufferFlush) {
233 // add transactions until we drop the transaction with the second layer change
234 while (bufferFront().vsync_id() <= VSYNC_ID_SECOND_LAYER_CHANGE) {
235 queueAndCommitTransaction(++mVsyncId);
236 }
237 proto::TransactionTraceFile proto = writeToProto();
238 // verify we have two starting states
239 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 2);
240
241 // Continue adding transactions until child layer is removed
242 while (bufferFront().vsync_id() <= VSYNC_ID_CHILD_LAYER_REMOVED) {
243 queueAndCommitTransaction(++mVsyncId);
244 }
245 proto = writeToProto();
246 // verify we still have the parent layer state
247 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 1);
248 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).layer_id(), mParentLayerId);
249}
250
Vishnu Nair84125ac2021-12-02 08:47:48 -0800251class TransactionTracingMirrorLayerTest : public TransactionTracingTest {
252protected:
253 void SetUp() override {
Dominik Laskowski46471e62022-01-14 15:34:03 -0800254 mTracing.setBufferSize(SMALL_BUFFER_SIZE);
Vishnu Nair84125ac2021-12-02 08:47:48 -0800255
Vishnu Nair81750622023-03-08 15:02:06 -0800256 // add layers and some layer transaction
Vishnu Nair84125ac2021-12-02 08:47:48 -0800257 {
Vishnu Nair81750622023-03-08 15:02:06 -0800258 frontend::Update update;
259 update.layerCreationArgs.emplace_back(
260 getLayerCreationArgs(mLayerId, /*parentId=*/UNASSIGNED_LAYER_ID,
261 /*layerIdToMirror=*/UNASSIGNED_LAYER_ID, /*flags=*/123,
262 /*addToRoot=*/true));
263 update.layerCreationArgs.emplace_back(
264 getLayerCreationArgs(mMirrorLayerId, UNASSIGNED_LAYER_ID,
265 /*layerIdToMirror=*/mLayerId, /*flags=*/0,
266 /*addToRoot=*/false));
267
Vishnu Nair84125ac2021-12-02 08:47:48 -0800268 TransactionState transaction;
269 transaction.id = 50;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000270 ResolvedComposerState layerState;
Vishnu Nair81750622023-03-08 15:02:06 -0800271 layerState.layerId = mLayerId;
Vishnu Nair84125ac2021-12-02 08:47:48 -0800272 layerState.state.what = layer_state_t::eLayerChanged;
273 layerState.state.z = 42;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000274 transaction.states.emplace_back(layerState);
275 ResolvedComposerState mirrorState;
Vishnu Nair81750622023-03-08 15:02:06 -0800276 mirrorState.layerId = mMirrorLayerId;
Vishnu Nair84125ac2021-12-02 08:47:48 -0800277 mirrorState.state.what = layer_state_t::eLayerChanged;
278 mirrorState.state.z = 43;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000279 transaction.states.emplace_back(mirrorState);
Dominik Laskowski46471e62022-01-14 15:34:03 -0800280 mTracing.addQueuedTransaction(transaction);
Vishnu Nair84125ac2021-12-02 08:47:48 -0800281
Vishnu Nair81750622023-03-08 15:02:06 -0800282 update.transactions.emplace_back(transaction);
283 mTracing.addCommittedTransactions(mVsyncId, 0, update, {}, false);
Vishnu Nair84125ac2021-12-02 08:47:48 -0800284 flush(mVsyncId);
285 }
286 }
287
Vishnu Nair81750622023-03-08 15:02:06 -0800288 uint32_t mLayerId = 5;
289 uint32_t mMirrorLayerId = 55;
Vishnu Nair84125ac2021-12-02 08:47:48 -0800290 int64_t mVsyncId = 0;
291 int64_t VSYNC_ID_FIRST_LAYER_CHANGE;
292 int64_t VSYNC_ID_SECOND_LAYER_CHANGE;
293 int64_t VSYNC_ID_CHILD_LAYER_REMOVED;
294};
295
296TEST_F(TransactionTracingMirrorLayerTest, canAddMirrorLayers) {
297 proto::TransactionTraceFile proto = writeToProto();
298 // We don't have any starting states since no layer was removed from.
Vishnu Nairb8f2a2d2022-01-13 08:10:10 -0800299 EXPECT_EQ(proto.entry().size(), 1);
Vishnu Nair84125ac2021-12-02 08:47:48 -0800300
301 // Verify the mirror layer was added
Vishnu Nairb8f2a2d2022-01-13 08:10:10 -0800302 EXPECT_EQ(proto.entry(0).transactions().size(), 1);
303 EXPECT_EQ(proto.entry(0).added_layers().size(), 2);
304 EXPECT_EQ(proto.entry(0).added_layers(1).layer_id(), mMirrorLayerId);
305 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 2);
306 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(1).z(), 43);
Vishnu Nair84125ac2021-12-02 08:47:48 -0800307}
Vishnu Nair7891e962021-11-11 12:07:21 -0800308} // namespace android