blob: c334bcf85d18577e9f9f4827d7232c9ec1189341 [file] [log] [blame]
Mikael Pessa90092f42019-08-26 17:22:04 -07001/*
2 * Copyright 2019 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 "LibSurfaceFlingerUnittests"
19
20#include <FrameTracer/FrameTracer.h>
21#include <gmock/gmock.h>
22#include <gtest/gtest.h>
23#include <log/log.h>
24#include <perfetto/trace/trace.pb.h>
25
26#include "libsurfaceflinger_unittest_main.h"
27
28using namespace google::protobuf;
29
30namespace android {
31namespace {
32
33class FrameTracerTest : public testing::Test {
34public:
35 FrameTracerTest() {
36 const ::testing::TestInfo* const test_info =
37 ::testing::UnitTest::GetInstance()->current_test_info();
38 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
39
40 // Need to initialize tracing in process for testing, and only once per test suite.
41 static bool wasInitialized = false;
42 if (!wasInitialized) {
43 perfetto::TracingInitArgs args;
44 args.backends = perfetto::kInProcessBackend;
45 perfetto::Tracing::Initialize(args);
46 wasInitialized = true;
47 }
48 }
49
50 ~FrameTracerTest() {
51 const ::testing::TestInfo* const test_info =
52 ::testing::UnitTest::GetInstance()->current_test_info();
53 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
54 }
55
56 void SetUp() override {
57 mFrameTracer = std::make_unique<FrameTracer>();
58 mFrameTracer->registerDataSource();
59 }
60
61 void TearDown() override { mFrameTracer.reset(); }
62
63 // Each tracing session can be used for a single block of Start -> Stop.
64 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
65 perfetto::TraceConfig cfg;
66 cfg.set_duration_ms(500);
67 cfg.add_buffers()->set_size_kb(1024);
68 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
69 ds_cfg->set_name(FrameTracer::kFrameTracerDataSource);
70
71 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
72 tracingSession->Setup(cfg);
73 return tracingSession;
74 }
75
76 std::unique_ptr<FrameTracer> mFrameTracer;
77 FenceToFenceTimeMap fenceFactory;
78};
79
80TEST_F(FrameTracerTest, traceNewLayerStartsTrackingLayerWhenTracing) {
81 EXPECT_EQ(mFrameTracer->miniDump(),
82 "FrameTracer miniDump:\nNumber of layers currently being traced is 0\n");
83
84 const std::string layerName = "co.layername#0";
Yiwei Zhang1a88c402019-11-18 10:43:58 -080085 const int32_t layerId = 5;
86 mFrameTracer->traceNewLayer(layerId, layerName);
Mikael Pessa90092f42019-08-26 17:22:04 -070087
88 EXPECT_EQ(mFrameTracer->miniDump(),
89 "FrameTracer miniDump:\nNumber of layers currently being traced is 0\n");
90
91 auto tracingSession = getTracingSessionForTest();
92 tracingSession->StartBlocking();
93 EXPECT_EQ(mFrameTracer->miniDump(),
94 "FrameTracer miniDump:\nNumber of layers currently being traced is 0\n");
Yiwei Zhang1a88c402019-11-18 10:43:58 -080095 mFrameTracer->traceNewLayer(layerId, layerName);
Mikael Pessa90092f42019-08-26 17:22:04 -070096 EXPECT_EQ(mFrameTracer->miniDump(),
97 "FrameTracer miniDump:\nNumber of layers currently being traced is 1\n");
98 tracingSession->StopBlocking();
99}
100
101TEST_F(FrameTracerTest, onDestroyRemovesTheTrackedLayer) {
102 EXPECT_EQ(mFrameTracer->miniDump(),
103 "FrameTracer miniDump:\nNumber of layers currently being traced is 0\n");
104
105 const std::string layerName = "co.layername#0";
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800106 const int32_t layerId = 5;
107 const int32_t secondlayerId = 6;
Mikael Pessa90092f42019-08-26 17:22:04 -0700108
109 auto tracingSession = getTracingSessionForTest();
110 tracingSession->StartBlocking();
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800111 mFrameTracer->traceNewLayer(layerId, layerName);
112 mFrameTracer->traceNewLayer(secondlayerId, layerName);
Mikael Pessa90092f42019-08-26 17:22:04 -0700113 EXPECT_EQ(mFrameTracer->miniDump(),
114 "FrameTracer miniDump:\nNumber of layers currently being traced is 2\n");
115 tracingSession->StopBlocking();
116
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800117 mFrameTracer->onDestroy(layerId);
Mikael Pessa90092f42019-08-26 17:22:04 -0700118 EXPECT_EQ(mFrameTracer->miniDump(),
119 "FrameTracer miniDump:\nNumber of layers currently being traced is 1\n");
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800120 mFrameTracer->onDestroy(layerId);
Mikael Pessa90092f42019-08-26 17:22:04 -0700121 EXPECT_EQ(mFrameTracer->miniDump(),
122 "FrameTracer miniDump:\nNumber of layers currently being traced is 1\n");
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800123 mFrameTracer->onDestroy(secondlayerId);
Mikael Pessa90092f42019-08-26 17:22:04 -0700124 EXPECT_EQ(mFrameTracer->miniDump(),
125 "FrameTracer miniDump:\nNumber of layers currently being traced is 0\n");
126}
127
128TEST_F(FrameTracerTest, canTraceAfterAddingLayer) {
129 const std::string layerName = "co.layername#0";
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800130 const int32_t layerId = 1;
Mikael Pessa90092f42019-08-26 17:22:04 -0700131 const uint32_t bufferID = 2;
132 const uint64_t frameNumber = 3;
133 const nsecs_t timestamp = 4;
134 const nsecs_t duration = 5;
135 const auto type = FrameTracer::FrameEvent::POST;
136
137 {
138 auto tracingSession = getTracingSessionForTest();
139
140 tracingSession->StartBlocking();
141 // Clean up irrelevant traces.
142 tracingSession->ReadTraceBlocking();
143
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800144 mFrameTracer->traceTimestamp(layerId, bufferID, frameNumber, timestamp, type, duration);
Mikael Pessa90092f42019-08-26 17:22:04 -0700145 // Create second trace packet to finalize the previous one.
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800146 mFrameTracer->traceTimestamp(layerId, 0, 0, 0, FrameTracer::FrameEvent::UNSPECIFIED);
Mikael Pessa90092f42019-08-26 17:22:04 -0700147 tracingSession->StopBlocking();
148
149 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
150 EXPECT_EQ(raw_trace.size(), 0);
151 }
152
153 {
154 auto tracingSession = getTracingSessionForTest();
155
156 tracingSession->StartBlocking();
157 // Clean up irrelevant traces.
158 tracingSession->ReadTraceBlocking();
159
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800160 mFrameTracer->traceNewLayer(layerId, layerName);
161 mFrameTracer->traceTimestamp(layerId, bufferID, frameNumber, timestamp, type, duration);
Mikael Pessa90092f42019-08-26 17:22:04 -0700162 // Create second trace packet to finalize the previous one.
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800163 mFrameTracer->traceTimestamp(layerId, 0, 0, 0, FrameTracer::FrameEvent::UNSPECIFIED);
Mikael Pessa90092f42019-08-26 17:22:04 -0700164 tracingSession->StopBlocking();
165
166 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
167 ASSERT_GT(raw_trace.size(), 0);
168
169 perfetto::protos::Trace trace;
170 ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
171 ASSERT_FALSE(trace.packet().empty());
172 EXPECT_EQ(trace.packet().size(), 1);
173
174 const auto& packet = trace.packet().Get(0);
175 ASSERT_TRUE(packet.has_timestamp());
176 EXPECT_EQ(packet.timestamp(), timestamp);
177 ASSERT_TRUE(packet.has_graphics_frame_event());
178 const auto& frame_event = packet.graphics_frame_event();
179 ASSERT_TRUE(frame_event.has_buffer_event());
180 const auto& buffer_event = frame_event.buffer_event();
181 ASSERT_TRUE(buffer_event.has_buffer_id());
182 EXPECT_EQ(buffer_event.buffer_id(), bufferID);
183 ASSERT_TRUE(buffer_event.has_frame_number());
184 EXPECT_EQ(buffer_event.frame_number(), frameNumber);
185 ASSERT_TRUE(buffer_event.has_type());
186 EXPECT_EQ(buffer_event.type(), perfetto::protos::GraphicsFrameEvent_BufferEventType(type));
187 ASSERT_TRUE(buffer_event.has_duration_ns());
188 EXPECT_EQ(buffer_event.duration_ns(), duration);
189 }
190}
191
192TEST_F(FrameTracerTest, traceFenceTriggersOnNextTraceAfterFenceFired) {
193 const std::string layerName = "co.layername#0";
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800194 const int32_t layerId = 5;
Mikael Pessa90092f42019-08-26 17:22:04 -0700195 const uint32_t bufferID = 4;
196 const uint64_t frameNumber = 3;
197 const auto type = FrameTracer::FrameEvent::ACQUIRE_FENCE;
198
199 {
200 auto fenceTime = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
201 fenceFactory.signalAllForTest(Fence::NO_FENCE, Fence::SIGNAL_TIME_PENDING);
202 auto tracingSession = getTracingSessionForTest();
203 tracingSession->StartBlocking();
204 // Clean up irrelevant traces.
205 tracingSession->ReadTraceBlocking();
206 // Trace.
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800207 mFrameTracer->traceNewLayer(layerId, layerName);
208 mFrameTracer->traceFence(layerId, bufferID, frameNumber, fenceTime, type);
Mikael Pessa90092f42019-08-26 17:22:04 -0700209 // Create extra trace packet to (hopefully not) trigger and finalize the fence packet.
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800210 mFrameTracer->traceTimestamp(layerId, bufferID, 0, 0, FrameTracer::FrameEvent::UNSPECIFIED);
Mikael Pessa90092f42019-08-26 17:22:04 -0700211 tracingSession->StopBlocking();
212 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
213 EXPECT_EQ(raw_trace.size(), 0);
214 }
215
216 {
217 auto fenceTime = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
218 auto tracingSession = getTracingSessionForTest();
219 tracingSession->StartBlocking();
220 // Clean up irrelevant traces.
221 tracingSession->ReadTraceBlocking();
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800222 mFrameTracer->traceNewLayer(layerId, layerName);
223 mFrameTracer->traceFence(layerId, bufferID, frameNumber, fenceTime, type);
Mikael Pessa90092f42019-08-26 17:22:04 -0700224 const nsecs_t timestamp = systemTime();
225 fenceFactory.signalAllForTest(Fence::NO_FENCE, timestamp);
226 // Create extra trace packet to trigger and finalize fence trace packets.
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800227 mFrameTracer->traceTimestamp(layerId, bufferID, 0, 0, FrameTracer::FrameEvent::UNSPECIFIED);
Mikael Pessa90092f42019-08-26 17:22:04 -0700228 tracingSession->StopBlocking();
229
230 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
231 ASSERT_GT(raw_trace.size(), 0);
232
233 perfetto::protos::Trace trace;
234 ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
235 ASSERT_FALSE(trace.packet().empty());
236 EXPECT_EQ(trace.packet().size(), 2); // Two packets because of the extra trace made above.
237
238 const auto& packet = trace.packet().Get(1);
239 ASSERT_TRUE(packet.has_timestamp());
240 EXPECT_EQ(packet.timestamp(), timestamp);
241 ASSERT_TRUE(packet.has_graphics_frame_event());
242 const auto& frame_event = packet.graphics_frame_event();
243 ASSERT_TRUE(frame_event.has_buffer_event());
244 const auto& buffer_event = frame_event.buffer_event();
245 ASSERT_TRUE(buffer_event.has_buffer_id());
246 EXPECT_EQ(buffer_event.buffer_id(), bufferID);
247 ASSERT_TRUE(buffer_event.has_frame_number());
248 EXPECT_EQ(buffer_event.frame_number(), frameNumber);
249 ASSERT_TRUE(buffer_event.has_type());
250 EXPECT_EQ(buffer_event.type(), perfetto::protos::GraphicsFrameEvent_BufferEventType(type));
251 EXPECT_FALSE(buffer_event.has_duration_ns());
252 }
253}
254
255TEST_F(FrameTracerTest, traceFenceWithStartTimeAfterSignalTime_ShouldHaveNoDuration) {
256 const std::string layerName = "co.layername#0";
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800257 const int32_t layerId = 5;
Mikael Pessa90092f42019-08-26 17:22:04 -0700258 const uint32_t bufferID = 4;
259 const uint64_t frameNumber = 3;
260 const auto type = FrameTracer::FrameEvent::ACQUIRE_FENCE;
261
262 auto tracingSession = getTracingSessionForTest();
263
264 tracingSession->StartBlocking();
265 // Clean up irrelevant traces.
266 tracingSession->ReadTraceBlocking();
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800267 mFrameTracer->traceNewLayer(layerId, layerName);
Mikael Pessa90092f42019-08-26 17:22:04 -0700268
269 // traceFence called after fence signalled.
270 const nsecs_t signalTime1 = systemTime();
271 const nsecs_t startTime1 = signalTime1 + 100000;
272 auto fence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
273 fenceFactory.signalAllForTest(Fence::NO_FENCE, signalTime1);
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800274 mFrameTracer->traceFence(layerId, bufferID, frameNumber, fence1, type, startTime1);
Mikael Pessa90092f42019-08-26 17:22:04 -0700275
276 // traceFence called before fence signalled.
277 const nsecs_t signalTime2 = systemTime();
278 const nsecs_t startTime2 = signalTime2 + 100000;
279 auto fence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800280 mFrameTracer->traceFence(layerId, bufferID, frameNumber, fence2, type, startTime2);
Mikael Pessa90092f42019-08-26 17:22:04 -0700281 fenceFactory.signalAllForTest(Fence::NO_FENCE, signalTime2);
282
283 // Create extra trace packet to trigger and finalize fence trace packets.
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800284 mFrameTracer->traceTimestamp(layerId, bufferID, 0, 0, FrameTracer::FrameEvent::UNSPECIFIED);
Mikael Pessa90092f42019-08-26 17:22:04 -0700285 tracingSession->StopBlocking();
286
287 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
288 ASSERT_GT(raw_trace.size(), 0);
289
290 perfetto::protos::Trace trace;
291 ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
292 ASSERT_FALSE(trace.packet().empty());
293 EXPECT_EQ(trace.packet().size(), 2);
294
295 const auto& packet1 = trace.packet().Get(0);
296 ASSERT_TRUE(packet1.has_timestamp());
297 EXPECT_EQ(packet1.timestamp(), signalTime1);
298 ASSERT_TRUE(packet1.has_graphics_frame_event());
299 ASSERT_TRUE(packet1.graphics_frame_event().has_buffer_event());
300 ASSERT_FALSE(packet1.graphics_frame_event().buffer_event().has_duration_ns());
301
302 const auto& packet2 = trace.packet().Get(1);
303 ASSERT_TRUE(packet2.has_timestamp());
304 EXPECT_EQ(packet2.timestamp(), signalTime2);
305 ASSERT_TRUE(packet2.has_graphics_frame_event());
306 ASSERT_TRUE(packet2.graphics_frame_event().has_buffer_event());
307 ASSERT_FALSE(packet2.graphics_frame_event().buffer_event().has_duration_ns());
308}
309
310TEST_F(FrameTracerTest, traceFenceOlderThanDeadline_ShouldBeIgnored) {
311 const std::string layerName = "co.layername#0";
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800312 const int32_t layerId = 5;
Mikael Pessa90092f42019-08-26 17:22:04 -0700313 const uint32_t bufferID = 4;
314 const uint64_t frameNumber = 3;
315 const auto type = FrameTracer::FrameEvent::ACQUIRE_FENCE;
316 const nsecs_t signalTime = systemTime() - FrameTracer::kFenceSignallingDeadline;
317
318 auto tracingSession = getTracingSessionForTest();
319 auto fence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
320
321 tracingSession->StartBlocking();
322 // Clean up irrelevant traces.
323 tracingSession->ReadTraceBlocking();
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800324 mFrameTracer->traceNewLayer(layerId, layerName);
325 mFrameTracer->traceFence(layerId, bufferID, frameNumber, fence, type);
Mikael Pessa90092f42019-08-26 17:22:04 -0700326 fenceFactory.signalAllForTest(Fence::NO_FENCE, signalTime);
327 // Create extra trace packet to trigger and finalize any previous fence packets.
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800328 mFrameTracer->traceTimestamp(layerId, bufferID, 0, 0, FrameTracer::FrameEvent::UNSPECIFIED);
Mikael Pessa90092f42019-08-26 17:22:04 -0700329 tracingSession->StopBlocking();
330
331 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
332 EXPECT_EQ(raw_trace.size(), 0);
333}
334
335TEST_F(FrameTracerTest, traceFenceWithValidStartTime_ShouldHaveCorrectDuration) {
336 const std::string layerName = "co.layername#0";
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800337 const int32_t layerId = 5;
Mikael Pessa90092f42019-08-26 17:22:04 -0700338 const uint32_t bufferID = 4;
339 const uint64_t frameNumber = 3;
340 const auto type = FrameTracer::FrameEvent::ACQUIRE_FENCE;
341 const nsecs_t duration = 1234;
342
343 auto tracingSession = getTracingSessionForTest();
344
345 tracingSession->StartBlocking();
346 // Clean up irrelevant traces.
347 tracingSession->ReadTraceBlocking();
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800348 mFrameTracer->traceNewLayer(layerId, layerName);
Mikael Pessa90092f42019-08-26 17:22:04 -0700349
350 // traceFence called after fence signalled.
351 const nsecs_t signalTime1 = systemTime();
352 const nsecs_t startTime1 = signalTime1 - duration;
353 auto fence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
354 fenceFactory.signalAllForTest(Fence::NO_FENCE, signalTime1);
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800355 mFrameTracer->traceFence(layerId, bufferID, frameNumber, fence1, type, startTime1);
Mikael Pessa90092f42019-08-26 17:22:04 -0700356
357 // traceFence called before fence signalled.
358 const nsecs_t signalTime2 = systemTime();
359 const nsecs_t startTime2 = signalTime2 - duration;
360 auto fence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800361 mFrameTracer->traceFence(layerId, bufferID, frameNumber, fence2, type, startTime2);
Mikael Pessa90092f42019-08-26 17:22:04 -0700362 fenceFactory.signalAllForTest(Fence::NO_FENCE, signalTime2);
363
364 // Create extra trace packet to trigger and finalize fence trace packets.
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800365 mFrameTracer->traceTimestamp(layerId, bufferID, 0, 0, FrameTracer::FrameEvent::UNSPECIFIED);
Mikael Pessa90092f42019-08-26 17:22:04 -0700366 tracingSession->StopBlocking();
367
368 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
369 ASSERT_GT(raw_trace.size(), 0);
370
371 perfetto::protos::Trace trace;
372 ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
373 ASSERT_FALSE(trace.packet().empty());
374 EXPECT_EQ(trace.packet().size(), 2);
375
376 const auto& packet1 = trace.packet().Get(0);
377 ASSERT_TRUE(packet1.has_timestamp());
378 EXPECT_EQ(packet1.timestamp(), startTime1);
379 ASSERT_TRUE(packet1.has_graphics_frame_event());
380 ASSERT_TRUE(packet1.graphics_frame_event().has_buffer_event());
381 ASSERT_TRUE(packet1.graphics_frame_event().buffer_event().has_duration_ns());
382 const auto& buffer_event1 = packet1.graphics_frame_event().buffer_event();
383 EXPECT_EQ(buffer_event1.duration_ns(), duration);
384
385 const auto& packet2 = trace.packet().Get(1);
386 ASSERT_TRUE(packet2.has_timestamp());
387 EXPECT_EQ(packet2.timestamp(), startTime2);
388 ASSERT_TRUE(packet2.has_graphics_frame_event());
389 ASSERT_TRUE(packet2.graphics_frame_event().has_buffer_event());
390 ASSERT_TRUE(packet2.graphics_frame_event().buffer_event().has_duration_ns());
391 const auto& buffer_event2 = packet2.graphics_frame_event().buffer_event();
392 EXPECT_EQ(buffer_event2.duration_ns(), duration);
393}
394
395} // namespace
396} // namespace android