blob: 482c3a8e508599bfb7f5fb726acca561d92b4bca [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>
21
22#include "Tracing/RingBuffer.h"
23#include "Tracing/TransactionTracing.h"
24
25using namespace android::surfaceflinger;
26
27namespace android {
28
29class TransactionTracingTest : public testing::Test {
30protected:
Vishnu Nair0cc69e12021-11-18 09:05:49 -080031 static constexpr size_t SMALL_BUFFER_SIZE = 1024;
Dominik Laskowski46471e62022-01-14 15:34:03 -080032 TransactionTracing mTracing;
Vishnu Nair7891e962021-11-11 12:07:21 -080033
Dominik Laskowski46471e62022-01-14 15:34:03 -080034 void flush(int64_t vsyncId) { mTracing.flush(vsyncId); }
35 proto::TransactionTraceFile writeToProto() { return mTracing.writeToProto(); }
Vishnu Nair7891e962021-11-11 12:07:21 -080036
Dominik Laskowski46471e62022-01-14 15:34:03 -080037 proto::TransactionTraceEntry bufferFront() {
38 std::scoped_lock<std::mutex> lock(mTracing.mTraceLock);
Vishnu Nair62863552021-12-10 13:34:48 -080039 proto::TransactionTraceEntry entry;
Dominik Laskowski46471e62022-01-14 15:34:03 -080040 entry.ParseFromString(mTracing.mBuffer.front());
Vishnu Nair62863552021-12-10 13:34:48 -080041 return entry;
Vishnu Nair7891e962021-11-11 12:07:21 -080042 }
43
Vishnu Nair0cc69e12021-11-18 09:05:49 -080044 void queueAndCommitTransaction(int64_t vsyncId) {
45 TransactionState transaction;
46 transaction.id = static_cast<uint64_t>(vsyncId * 3);
47 transaction.originUid = 1;
48 transaction.originPid = 2;
Dominik Laskowski46471e62022-01-14 15:34:03 -080049 mTracing.addQueuedTransaction(transaction);
Vishnu Nair0cc69e12021-11-18 09:05:49 -080050 std::vector<TransactionState> transactions;
51 transactions.emplace_back(transaction);
Dominik Laskowski46471e62022-01-14 15:34:03 -080052 mTracing.addCommittedTransactions(transactions, vsyncId);
Vishnu Nair0cc69e12021-11-18 09:05:49 -080053 flush(vsyncId);
Vishnu Nair7891e962021-11-11 12:07:21 -080054 }
55
Vishnu Nair7891e962021-11-11 12:07:21 -080056 void verifyEntry(const proto::TransactionTraceEntry& actualProto,
Dominik Laskowski46471e62022-01-14 15:34:03 -080057 const std::vector<TransactionState>& expectedTransactions,
Vishnu Nair7891e962021-11-11 12:07:21 -080058 int64_t expectedVsyncId) {
59 EXPECT_EQ(actualProto.vsync_id(), expectedVsyncId);
60 EXPECT_EQ(actualProto.transactions().size(),
61 static_cast<int32_t>(expectedTransactions.size()));
62 for (uint32_t i = 0; i < expectedTransactions.size(); i++) {
63 EXPECT_EQ(actualProto.transactions(static_cast<int32_t>(i)).pid(),
64 expectedTransactions[i].originPid);
65 }
66 }
67};
68
Vishnu Nair7891e962021-11-11 12:07:21 -080069TEST_F(TransactionTracingTest, addTransactions) {
Vishnu Nair7891e962021-11-11 12:07:21 -080070 std::vector<TransactionState> transactions;
71 transactions.reserve(100);
72 for (uint64_t i = 0; i < 100; i++) {
73 TransactionState transaction;
74 transaction.id = i;
75 transaction.originPid = static_cast<int32_t>(i);
76 transactions.emplace_back(transaction);
Dominik Laskowski46471e62022-01-14 15:34:03 -080077 mTracing.addQueuedTransaction(transaction);
Vishnu Nair7891e962021-11-11 12:07:21 -080078 }
79
80 // Split incoming transactions into two and commit them in reverse order to test out of order
81 // commits.
82 std::vector<TransactionState> firstTransactionSet =
83 std::vector<TransactionState>(transactions.begin() + 50, transactions.end());
84 int64_t firstTransactionSetVsyncId = 42;
Dominik Laskowski46471e62022-01-14 15:34:03 -080085 mTracing.addCommittedTransactions(firstTransactionSet, firstTransactionSetVsyncId);
Vishnu Nair7891e962021-11-11 12:07:21 -080086
87 int64_t secondTransactionSetVsyncId = 43;
88 std::vector<TransactionState> secondTransactionSet =
89 std::vector<TransactionState>(transactions.begin(), transactions.begin() + 50);
Dominik Laskowski46471e62022-01-14 15:34:03 -080090 mTracing.addCommittedTransactions(secondTransactionSet, secondTransactionSetVsyncId);
Vishnu Nair0cc69e12021-11-18 09:05:49 -080091 flush(secondTransactionSetVsyncId);
Vishnu Nair7891e962021-11-11 12:07:21 -080092
Vishnu Nair0cc69e12021-11-18 09:05:49 -080093 proto::TransactionTraceFile proto = writeToProto();
Vishnu Nairb8f2a2d2022-01-13 08:10:10 -080094 EXPECT_EQ(proto.entry().size(), 2);
95 verifyEntry(proto.entry(0), firstTransactionSet, firstTransactionSetVsyncId);
96 verifyEntry(proto.entry(1), secondTransactionSet, secondTransactionSetVsyncId);
Vishnu Nair7891e962021-11-11 12:07:21 -080097}
98
Vishnu Nair0cc69e12021-11-18 09:05:49 -080099class TransactionTracingLayerHandlingTest : public TransactionTracingTest {
100protected:
101 void SetUp() override {
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800102 // add layers
Dominik Laskowski46471e62022-01-14 15:34:03 -0800103 mTracing.setBufferSize(SMALL_BUFFER_SIZE);
Ady Abrahamd11bade2022-08-01 16:18:03 -0700104 const sp<IBinder> fakeLayerHandle = sp<BBinder>::make();
Dominik Laskowski46471e62022-01-14 15:34:03 -0800105 mTracing.onLayerAdded(fakeLayerHandle->localBinder(), mParentLayerId, "parent",
106 123 /* flags */, -1 /* parentId */);
Ady Abrahamd11bade2022-08-01 16:18:03 -0700107 const sp<IBinder> fakeChildLayerHandle = sp<BBinder>::make();
Dominik Laskowski46471e62022-01-14 15:34:03 -0800108 mTracing.onLayerAdded(fakeChildLayerHandle->localBinder(), mChildLayerId, "child",
109 456 /* flags */, mParentLayerId);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800110
111 // add some layer transaction
112 {
113 TransactionState transaction;
114 transaction.id = 50;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000115 ResolvedComposerState layerState;
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800116 layerState.state.surface = fakeLayerHandle;
117 layerState.state.what = layer_state_t::eLayerChanged;
118 layerState.state.z = 42;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000119 transaction.states.emplace_back(layerState);
120 ResolvedComposerState childState;
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800121 childState.state.surface = fakeChildLayerHandle;
Vishnu Nair473838d2021-12-08 09:46:02 -0800122 childState.state.what = layer_state_t::eLayerChanged;
123 childState.state.z = 43;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000124 transaction.states.emplace_back(childState);
Dominik Laskowski46471e62022-01-14 15:34:03 -0800125 mTracing.addQueuedTransaction(transaction);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800126
127 std::vector<TransactionState> transactions;
128 transactions.emplace_back(transaction);
129 VSYNC_ID_FIRST_LAYER_CHANGE = ++mVsyncId;
Vishnu Nair286f4f92022-06-08 16:37:39 -0700130 mTracing.onLayerAddedToDrawingState(mParentLayerId, VSYNC_ID_FIRST_LAYER_CHANGE);
131 mTracing.onLayerAddedToDrawingState(mChildLayerId, VSYNC_ID_FIRST_LAYER_CHANGE);
Dominik Laskowski46471e62022-01-14 15:34:03 -0800132 mTracing.addCommittedTransactions(transactions, VSYNC_ID_FIRST_LAYER_CHANGE);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800133 flush(VSYNC_ID_FIRST_LAYER_CHANGE);
134 }
135
136 // add transactions that modify the layer state further so we can test that layer state
137 // gets merged
138 {
139 TransactionState transaction;
140 transaction.id = 51;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000141 ResolvedComposerState layerState;
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800142 layerState.state.surface = fakeLayerHandle;
143 layerState.state.what = layer_state_t::eLayerChanged | layer_state_t::ePositionChanged;
144 layerState.state.z = 41;
145 layerState.state.x = 22;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000146 transaction.states.emplace_back(layerState);
Dominik Laskowski46471e62022-01-14 15:34:03 -0800147 mTracing.addQueuedTransaction(transaction);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800148
149 std::vector<TransactionState> transactions;
150 transactions.emplace_back(transaction);
151 VSYNC_ID_SECOND_LAYER_CHANGE = ++mVsyncId;
Dominik Laskowski46471e62022-01-14 15:34:03 -0800152 mTracing.addCommittedTransactions(transactions, VSYNC_ID_SECOND_LAYER_CHANGE);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800153 flush(VSYNC_ID_SECOND_LAYER_CHANGE);
154 }
155
156 // remove child layer
Dominik Laskowski46471e62022-01-14 15:34:03 -0800157 mTracing.onLayerRemoved(2);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800158 VSYNC_ID_CHILD_LAYER_REMOVED = ++mVsyncId;
159 queueAndCommitTransaction(VSYNC_ID_CHILD_LAYER_REMOVED);
160
161 // remove layer
Dominik Laskowski46471e62022-01-14 15:34:03 -0800162 mTracing.onLayerRemoved(1);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800163 queueAndCommitTransaction(++mVsyncId);
164 }
165
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800166 int mParentLayerId = 1;
Vishnu Nair473838d2021-12-08 09:46:02 -0800167 int mChildLayerId = 2;
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800168 int64_t mVsyncId = 0;
169 int64_t VSYNC_ID_FIRST_LAYER_CHANGE;
170 int64_t VSYNC_ID_SECOND_LAYER_CHANGE;
171 int64_t VSYNC_ID_CHILD_LAYER_REMOVED;
172};
173
174TEST_F(TransactionTracingLayerHandlingTest, addStartingState) {
175 // add transactions until we drop the transaction with the first layer change
176 while (bufferFront().vsync_id() <= VSYNC_ID_FIRST_LAYER_CHANGE) {
177 queueAndCommitTransaction(++mVsyncId);
178 }
179 proto::TransactionTraceFile proto = writeToProto();
180 // verify we can still retrieve the layer change from the first entry containing starting
181 // states.
182 EXPECT_GT(proto.entry().size(), 0);
Vishnu Nair685cfef2022-02-02 10:01:25 -0800183 EXPECT_EQ(proto.entry(0).transactions().size(), 1);
184 EXPECT_EQ(proto.entry(0).added_layers().size(), 2);
Vishnu Nair473838d2021-12-08 09:46:02 -0800185 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 2);
186 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).layer_id(), mParentLayerId);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800187 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).z(), 42);
Vishnu Nair473838d2021-12-08 09:46:02 -0800188 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(1).layer_id(), mChildLayerId);
189 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(1).z(), 43);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800190}
191
192TEST_F(TransactionTracingLayerHandlingTest, updateStartingState) {
193 // add transactions until we drop the transaction with the second layer change
194 while (bufferFront().vsync_id() <= VSYNC_ID_SECOND_LAYER_CHANGE) {
195 queueAndCommitTransaction(++mVsyncId);
196 }
197 proto::TransactionTraceFile proto = writeToProto();
198 // verify starting states are updated correctly
199 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).z(), 41);
200}
201
202TEST_F(TransactionTracingLayerHandlingTest, removeStartingState) {
203 // add transactions until we drop the transaction which removes the child layer
204 while (bufferFront().vsync_id() <= VSYNC_ID_CHILD_LAYER_REMOVED) {
205 queueAndCommitTransaction(++mVsyncId);
206 }
207 proto::TransactionTraceFile proto = writeToProto();
208 // verify the child layer has been removed from the trace
209 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 1);
210 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).layer_id(), mParentLayerId);
211}
212
213TEST_F(TransactionTracingLayerHandlingTest, startingStateSurvivesBufferFlush) {
214 // add transactions until we drop the transaction with the second layer change
215 while (bufferFront().vsync_id() <= VSYNC_ID_SECOND_LAYER_CHANGE) {
216 queueAndCommitTransaction(++mVsyncId);
217 }
218 proto::TransactionTraceFile proto = writeToProto();
219 // verify we have two starting states
220 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 2);
221
222 // Continue adding transactions until child layer is removed
223 while (bufferFront().vsync_id() <= VSYNC_ID_CHILD_LAYER_REMOVED) {
224 queueAndCommitTransaction(++mVsyncId);
225 }
226 proto = writeToProto();
227 // verify we still have the parent layer state
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
Vishnu Nair84125ac2021-12-02 08:47:48 -0800232class TransactionTracingMirrorLayerTest : public TransactionTracingTest {
233protected:
234 void SetUp() override {
Vishnu Nair84125ac2021-12-02 08:47:48 -0800235 // add layers
Dominik Laskowski46471e62022-01-14 15:34:03 -0800236 mTracing.setBufferSize(SMALL_BUFFER_SIZE);
Ady Abrahamd11bade2022-08-01 16:18:03 -0700237 const sp<IBinder> fakeLayerHandle = sp<BBinder>::make();
Dominik Laskowski46471e62022-01-14 15:34:03 -0800238 mTracing.onLayerAdded(fakeLayerHandle->localBinder(), mLayerId, "Test Layer",
239 123 /* flags */, -1 /* parentId */);
Ady Abrahamd11bade2022-08-01 16:18:03 -0700240 const sp<IBinder> fakeMirrorLayerHandle = sp<BBinder>::make();
Dominik Laskowski46471e62022-01-14 15:34:03 -0800241 mTracing.onMirrorLayerAdded(fakeMirrorLayerHandle->localBinder(), mMirrorLayerId, "Mirror",
242 mLayerId);
Vishnu Nair286f4f92022-06-08 16:37:39 -0700243 mTracing.onLayerAddedToDrawingState(mLayerId, mVsyncId);
244 mTracing.onLayerAddedToDrawingState(mMirrorLayerId, mVsyncId);
Vishnu Nair84125ac2021-12-02 08:47:48 -0800245
246 // add some layer transaction
247 {
248 TransactionState transaction;
249 transaction.id = 50;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000250 ResolvedComposerState layerState;
Vishnu Nair84125ac2021-12-02 08:47:48 -0800251 layerState.state.surface = fakeLayerHandle;
252 layerState.state.what = layer_state_t::eLayerChanged;
253 layerState.state.z = 42;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000254 transaction.states.emplace_back(layerState);
255 ResolvedComposerState mirrorState;
Vishnu Nair84125ac2021-12-02 08:47:48 -0800256 mirrorState.state.surface = fakeMirrorLayerHandle;
257 mirrorState.state.what = layer_state_t::eLayerChanged;
258 mirrorState.state.z = 43;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000259 transaction.states.emplace_back(mirrorState);
Dominik Laskowski46471e62022-01-14 15:34:03 -0800260 mTracing.addQueuedTransaction(transaction);
Vishnu Nair84125ac2021-12-02 08:47:48 -0800261
262 std::vector<TransactionState> transactions;
263 transactions.emplace_back(transaction);
Vishnu Nair286f4f92022-06-08 16:37:39 -0700264 mTracing.addCommittedTransactions(transactions, mVsyncId);
Vishnu Nair84125ac2021-12-02 08:47:48 -0800265 flush(mVsyncId);
266 }
267 }
268
Vishnu Nair84125ac2021-12-02 08:47:48 -0800269 int mLayerId = 5;
270 int mMirrorLayerId = 55;
271 int64_t mVsyncId = 0;
272 int64_t VSYNC_ID_FIRST_LAYER_CHANGE;
273 int64_t VSYNC_ID_SECOND_LAYER_CHANGE;
274 int64_t VSYNC_ID_CHILD_LAYER_REMOVED;
275};
276
277TEST_F(TransactionTracingMirrorLayerTest, canAddMirrorLayers) {
278 proto::TransactionTraceFile proto = writeToProto();
279 // We don't have any starting states since no layer was removed from.
Vishnu Nairb8f2a2d2022-01-13 08:10:10 -0800280 EXPECT_EQ(proto.entry().size(), 1);
Vishnu Nair84125ac2021-12-02 08:47:48 -0800281
282 // Verify the mirror layer was added
Vishnu Nairb8f2a2d2022-01-13 08:10:10 -0800283 EXPECT_EQ(proto.entry(0).transactions().size(), 1);
284 EXPECT_EQ(proto.entry(0).added_layers().size(), 2);
285 EXPECT_EQ(proto.entry(0).added_layers(1).layer_id(), mMirrorLayerId);
286 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 2);
287 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(1).z(), 43);
Vishnu Nair84125ac2021-12-02 08:47:48 -0800288}
Vishnu Nair7891e962021-11-11 12:07:21 -0800289} // namespace android