• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 // This example demonstrates in-process tracing with Perfetto.
18 // This program adds trace in a few example functions like DrawPlayer DrawGame
19 // etc. and collect the trace in file `example.pftrace`.
20 //
21 // This file was copied from 'examples/sdk/example.cc' and migrated
22 // to use the 'libperfetto_c' API.
23 
24 #include "src/java_sdk/main/cpp/example.h"
25 
26 #include "src/java_sdk/main/cpp/utils.h"
27 
28 #include "perfetto/public/producer.h"
29 #include "perfetto/public/te_category_macros.h"
30 #include "perfetto/public/te_macros.h"
31 #include "perfetto/public/track_event.h"
32 
33 #include <chrono>
34 #include <fstream>
35 #include <string>
36 #include <thread>
37 
38 namespace {
39 #define EXAMPLE_CATEGORIES(C)                                    \
40   C(rendering, "rendering", "Rendering and graphics events")     \
41   C(network, "network.debug", "Verbose network events", "debug") \
42   C(audio, "audio.latency", "Detailed audio latency metrics", "verbose")
43 
PERFETTO_TE_CATEGORIES_DEFINE(EXAMPLE_CATEGORIES)44 PERFETTO_TE_CATEGORIES_DEFINE(EXAMPLE_CATEGORIES)
45 
46 void InitializePerfetto() {
47   PerfettoProducerInitArgs args = PERFETTO_PRODUCER_INIT_ARGS_INIT();
48   args.backends = PERFETTO_BACKEND_IN_PROCESS;
49   PerfettoProducerInit(args);
50   PerfettoTeInit();
51   PERFETTO_TE_REGISTER_CATEGORIES(EXAMPLE_CATEGORIES);
52 }
53 
StartTracing()54 std::unique_ptr<perfetto::java_sdk::utils::TracingSession> StartTracing() {
55   using perfetto::java_sdk::utils::TracingSession;
56   TracingSession tracing_session = TracingSession::Builder()
57                                        .set_data_source_name("track_event")
58                                        .add_enabled_category("*")
59                                        .Build();
60   return std::make_unique<TracingSession>(std::move(tracing_session));
61 }
62 
StopTracing(std::unique_ptr<perfetto::java_sdk::utils::TracingSession> tracing_session,const std::string & output_file_path)63 void StopTracing(
64     std::unique_ptr<perfetto::java_sdk::utils::TracingSession> tracing_session,
65     const std::string& output_file_path) {
66   // Stop tracing and read the trace data.
67   tracing_session->StopBlocking();
68   std::vector<uint8_t> trace_data(tracing_session->ReadBlocking());
69 
70   // Write the result into a file.
71   // Note: To save memory with longer traces, you can tell Perfetto to write
72   // directly into a file by passing a file descriptor into Setup() above.
73   std::ofstream output;
74   output.open(output_file_path, std::ios::out | std::ios::binary);
75   output.write(reinterpret_cast<const std::ostream::char_type*>(&trace_data[0]),
76                static_cast<std::streamsize>(trace_data.size()));
77   output.close();
78   printf(
79       "Trace written in %s file. To read this trace in "
80       "text form, run `./tools/traceconv text example.pftrace`\n",
81       output_file_path.c_str());
82 }
83 
DrawPlayer(int player_number)84 void DrawPlayer(int player_number) {
85   PERFETTO_TE_SCOPED(rendering, PERFETTO_TE_SLICE("DrawPlayer"),
86                      PERFETTO_TE_ARG_INT64("player_number", player_number));
87   // Sleep to simulate a long computation.
88   std::this_thread::sleep_for(std::chrono::milliseconds(500));
89 }
90 
DrawGame()91 void DrawGame() {
92   // This is an example of an unscoped slice, which begins and ends at specific
93   // points (instead of at the end of the current block scope).
94   PERFETTO_TE(rendering, PERFETTO_TE_SLICE_BEGIN("DrawGame"));
95   DrawPlayer(1);
96   DrawPlayer(2);
97   PERFETTO_TE(rendering, PERFETTO_TE_SLICE_END());
98 
99   // Record the rendering framerate as a counter sample.
100   PERFETTO_TE(
101       rendering, PERFETTO_TE_COUNTER(),
102       PERFETTO_TE_COUNTER_TRACK("Framerate", PerfettoTeProcessTrackUuid()),
103       PERFETTO_TE_INT_COUNTER(120));
104 }
105 }  // namespace
106 
run_main(const std::string & output_file_path)107 int run_main(const std::string& output_file_path) {
108   InitializePerfetto();
109   auto tracing_session = StartTracing();
110 
111   // Simulate some work that emits trace events.
112   DrawGame();
113 
114   StopTracing(std::move(tracing_session), output_file_path);
115   return 0;
116 }
117