1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker * Copyright (C) 2020 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker *
4*6dbdd20aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker *
8*6dbdd20aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker *
10*6dbdd20aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker */
16*6dbdd20aSAndroid Build Coastguard Worker
17*6dbdd20aSAndroid Build Coastguard Worker // This example demonstrates in-process tracing with Perfetto.
18*6dbdd20aSAndroid Build Coastguard Worker // This program adds trace in a few example functions like DrawPlayer DrawGame
19*6dbdd20aSAndroid Build Coastguard Worker // etc. and collect the trace in file `example.pftrace`.
20*6dbdd20aSAndroid Build Coastguard Worker // This output file is not readable directly. It can be read after converting
21*6dbdd20aSAndroid Build Coastguard Worker // it to text, by running the command:
22*6dbdd20aSAndroid Build Coastguard Worker // `./tools/traceconv text example.pftrace`
23*6dbdd20aSAndroid Build Coastguard Worker // or it can be opened in UI : https://ui.perfetto.dev
24*6dbdd20aSAndroid Build Coastguard Worker //
25*6dbdd20aSAndroid Build Coastguard Worker // To compile this file, run: `./tools/ninja -C out/default sdk_example`.
26*6dbdd20aSAndroid Build Coastguard Worker
27*6dbdd20aSAndroid Build Coastguard Worker #include "trace_categories.h"
28*6dbdd20aSAndroid Build Coastguard Worker
29*6dbdd20aSAndroid Build Coastguard Worker #include <chrono>
30*6dbdd20aSAndroid Build Coastguard Worker #include <fstream>
31*6dbdd20aSAndroid Build Coastguard Worker #include <thread>
32*6dbdd20aSAndroid Build Coastguard Worker
33*6dbdd20aSAndroid Build Coastguard Worker namespace {
34*6dbdd20aSAndroid Build Coastguard Worker
InitializePerfetto()35*6dbdd20aSAndroid Build Coastguard Worker void InitializePerfetto() {
36*6dbdd20aSAndroid Build Coastguard Worker perfetto::TracingInitArgs args;
37*6dbdd20aSAndroid Build Coastguard Worker // The backends determine where trace events are recorded. For this example we
38*6dbdd20aSAndroid Build Coastguard Worker // are going to use the in-process tracing service, which only includes in-app
39*6dbdd20aSAndroid Build Coastguard Worker // events.
40*6dbdd20aSAndroid Build Coastguard Worker args.backends = perfetto::kInProcessBackend;
41*6dbdd20aSAndroid Build Coastguard Worker
42*6dbdd20aSAndroid Build Coastguard Worker perfetto::Tracing::Initialize(args);
43*6dbdd20aSAndroid Build Coastguard Worker perfetto::TrackEvent::Register();
44*6dbdd20aSAndroid Build Coastguard Worker }
45*6dbdd20aSAndroid Build Coastguard Worker
StartTracing()46*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<perfetto::TracingSession> StartTracing() {
47*6dbdd20aSAndroid Build Coastguard Worker // The trace config defines which types of data sources are enabled for
48*6dbdd20aSAndroid Build Coastguard Worker // recording. In this example we just need the "track_event" data source,
49*6dbdd20aSAndroid Build Coastguard Worker // which corresponds to the TRACE_EVENT trace points.
50*6dbdd20aSAndroid Build Coastguard Worker perfetto::TraceConfig cfg;
51*6dbdd20aSAndroid Build Coastguard Worker cfg.add_buffers()->set_size_kb(1024);
52*6dbdd20aSAndroid Build Coastguard Worker auto* ds_cfg = cfg.add_data_sources()->mutable_config();
53*6dbdd20aSAndroid Build Coastguard Worker ds_cfg->set_name("track_event");
54*6dbdd20aSAndroid Build Coastguard Worker
55*6dbdd20aSAndroid Build Coastguard Worker auto tracing_session = perfetto::Tracing::NewTrace();
56*6dbdd20aSAndroid Build Coastguard Worker tracing_session->Setup(cfg);
57*6dbdd20aSAndroid Build Coastguard Worker tracing_session->StartBlocking();
58*6dbdd20aSAndroid Build Coastguard Worker return tracing_session;
59*6dbdd20aSAndroid Build Coastguard Worker }
60*6dbdd20aSAndroid Build Coastguard Worker
StopTracing(std::unique_ptr<perfetto::TracingSession> tracing_session)61*6dbdd20aSAndroid Build Coastguard Worker void StopTracing(std::unique_ptr<perfetto::TracingSession> tracing_session) {
62*6dbdd20aSAndroid Build Coastguard Worker // Make sure the last event is closed for this example.
63*6dbdd20aSAndroid Build Coastguard Worker perfetto::TrackEvent::Flush();
64*6dbdd20aSAndroid Build Coastguard Worker
65*6dbdd20aSAndroid Build Coastguard Worker // Stop tracing and read the trace data.
66*6dbdd20aSAndroid Build Coastguard Worker tracing_session->StopBlocking();
67*6dbdd20aSAndroid Build Coastguard Worker std::vector<char> trace_data(tracing_session->ReadTraceBlocking());
68*6dbdd20aSAndroid Build Coastguard Worker
69*6dbdd20aSAndroid Build Coastguard Worker // Write the result into a file.
70*6dbdd20aSAndroid Build Coastguard Worker // Note: To save memory with longer traces, you can tell Perfetto to write
71*6dbdd20aSAndroid Build Coastguard Worker // directly into a file by passing a file descriptor into Setup() above.
72*6dbdd20aSAndroid Build Coastguard Worker std::ofstream output;
73*6dbdd20aSAndroid Build Coastguard Worker output.open("example.pftrace", std::ios::out | std::ios::binary);
74*6dbdd20aSAndroid Build Coastguard Worker output.write(&trace_data[0], std::streamsize(trace_data.size()));
75*6dbdd20aSAndroid Build Coastguard Worker output.close();
76*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_LOG(
77*6dbdd20aSAndroid Build Coastguard Worker "Trace written in example.pftrace file. To read this trace in "
78*6dbdd20aSAndroid Build Coastguard Worker "text form, run `./tools/traceconv text example.pftrace`");
79*6dbdd20aSAndroid Build Coastguard Worker }
80*6dbdd20aSAndroid Build Coastguard Worker
DrawPlayer(int player_number)81*6dbdd20aSAndroid Build Coastguard Worker void DrawPlayer(int player_number) {
82*6dbdd20aSAndroid Build Coastguard Worker TRACE_EVENT("rendering", "DrawPlayer", "player_number", player_number);
83*6dbdd20aSAndroid Build Coastguard Worker // Sleep to simulate a long computation.
84*6dbdd20aSAndroid Build Coastguard Worker std::this_thread::sleep_for(std::chrono::milliseconds(500));
85*6dbdd20aSAndroid Build Coastguard Worker }
86*6dbdd20aSAndroid Build Coastguard Worker
DrawGame()87*6dbdd20aSAndroid Build Coastguard Worker void DrawGame() {
88*6dbdd20aSAndroid Build Coastguard Worker // This is an example of an unscoped slice, which begins and ends at specific
89*6dbdd20aSAndroid Build Coastguard Worker // points (instead of at the end of the current block scope).
90*6dbdd20aSAndroid Build Coastguard Worker TRACE_EVENT_BEGIN("rendering", "DrawGame");
91*6dbdd20aSAndroid Build Coastguard Worker DrawPlayer(1);
92*6dbdd20aSAndroid Build Coastguard Worker DrawPlayer(2);
93*6dbdd20aSAndroid Build Coastguard Worker TRACE_EVENT_END("rendering");
94*6dbdd20aSAndroid Build Coastguard Worker
95*6dbdd20aSAndroid Build Coastguard Worker // Record the rendering framerate as a counter sample.
96*6dbdd20aSAndroid Build Coastguard Worker TRACE_COUNTER("rendering", "Framerate", 120);
97*6dbdd20aSAndroid Build Coastguard Worker }
98*6dbdd20aSAndroid Build Coastguard Worker
99*6dbdd20aSAndroid Build Coastguard Worker } // namespace
100*6dbdd20aSAndroid Build Coastguard Worker
main(int,const char **)101*6dbdd20aSAndroid Build Coastguard Worker int main(int, const char**) {
102*6dbdd20aSAndroid Build Coastguard Worker InitializePerfetto();
103*6dbdd20aSAndroid Build Coastguard Worker auto tracing_session = StartTracing();
104*6dbdd20aSAndroid Build Coastguard Worker
105*6dbdd20aSAndroid Build Coastguard Worker // Give a custom name for the traced process.
106*6dbdd20aSAndroid Build Coastguard Worker perfetto::ProcessTrack process_track = perfetto::ProcessTrack::Current();
107*6dbdd20aSAndroid Build Coastguard Worker perfetto::protos::gen::TrackDescriptor desc = process_track.Serialize();
108*6dbdd20aSAndroid Build Coastguard Worker desc.mutable_process()->set_process_name("Example");
109*6dbdd20aSAndroid Build Coastguard Worker perfetto::TrackEvent::SetTrackDescriptor(process_track, desc);
110*6dbdd20aSAndroid Build Coastguard Worker
111*6dbdd20aSAndroid Build Coastguard Worker // Simulate some work that emits trace events.
112*6dbdd20aSAndroid Build Coastguard Worker DrawGame();
113*6dbdd20aSAndroid Build Coastguard Worker
114*6dbdd20aSAndroid Build Coastguard Worker StopTracing(std::move(tracing_session));
115*6dbdd20aSAndroid Build Coastguard Worker return 0;
116*6dbdd20aSAndroid Build Coastguard Worker }
117