| /* |
| * Copyright (C) 2025 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| // This example demonstrates in-process tracing with Perfetto. |
| // This program adds trace in a few example functions like DrawPlayer DrawGame |
| // etc. and collect the trace in file `example.pftrace`. |
| // |
| // This file was copied from 'examples/sdk/example.cc' and migrated |
| // to use the 'libperfetto_c' API. |
| |
| #include "src/java_sdk/main/cpp/example.h" |
| |
| #include "src/java_sdk/main/cpp/utils.h" |
| |
| #include "perfetto/public/producer.h" |
| #include "perfetto/public/te_category_macros.h" |
| #include "perfetto/public/te_macros.h" |
| #include "perfetto/public/track_event.h" |
| |
| #include <chrono> |
| #include <fstream> |
| #include <string> |
| #include <thread> |
| |
| namespace { |
| #define EXAMPLE_CATEGORIES(C) \ |
| C(rendering, "rendering", "Rendering and graphics events") \ |
| C(network, "network.debug", "Verbose network events", "debug") \ |
| C(audio, "audio.latency", "Detailed audio latency metrics", "verbose") |
| |
| PERFETTO_TE_CATEGORIES_DEFINE(EXAMPLE_CATEGORIES) |
| |
| void InitializePerfetto() { |
| PerfettoProducerInitArgs args = PERFETTO_PRODUCER_INIT_ARGS_INIT(); |
| args.backends = PERFETTO_BACKEND_IN_PROCESS; |
| PerfettoProducerInit(args); |
| PerfettoTeInit(); |
| PERFETTO_TE_REGISTER_CATEGORIES(EXAMPLE_CATEGORIES); |
| } |
| |
| std::unique_ptr<perfetto::java_sdk::utils::TracingSession> StartTracing() { |
| using perfetto::java_sdk::utils::TracingSession; |
| TracingSession tracing_session = TracingSession::Builder() |
| .set_data_source_name("track_event") |
| .add_enabled_category("*") |
| .Build(); |
| return std::make_unique<TracingSession>(std::move(tracing_session)); |
| } |
| |
| void StopTracing( |
| std::unique_ptr<perfetto::java_sdk::utils::TracingSession> tracing_session, |
| const std::string& output_file_path) { |
| // Stop tracing and read the trace data. |
| tracing_session->StopBlocking(); |
| std::vector<uint8_t> trace_data(tracing_session->ReadBlocking()); |
| |
| // Write the result into a file. |
| // Note: To save memory with longer traces, you can tell Perfetto to write |
| // directly into a file by passing a file descriptor into Setup() above. |
| std::ofstream output; |
| output.open(output_file_path, std::ios::out | std::ios::binary); |
| output.write(reinterpret_cast<const std::ostream::char_type*>(&trace_data[0]), |
| static_cast<std::streamsize>(trace_data.size())); |
| output.close(); |
| printf( |
| "Trace written in %s file. To read this trace in " |
| "text form, run `./tools/traceconv text example.pftrace`\n", |
| output_file_path.c_str()); |
| } |
| |
| void DrawPlayer(int player_number) { |
| PERFETTO_TE_SCOPED(rendering, PERFETTO_TE_SLICE("DrawPlayer"), |
| PERFETTO_TE_ARG_INT64("player_number", player_number)); |
| // Sleep to simulate a long computation. |
| std::this_thread::sleep_for(std::chrono::milliseconds(500)); |
| } |
| |
| void DrawGame() { |
| // This is an example of an unscoped slice, which begins and ends at specific |
| // points (instead of at the end of the current block scope). |
| PERFETTO_TE(rendering, PERFETTO_TE_SLICE_BEGIN("DrawGame")); |
| DrawPlayer(1); |
| DrawPlayer(2); |
| PERFETTO_TE(rendering, PERFETTO_TE_SLICE_END()); |
| |
| // Record the rendering framerate as a counter sample. |
| PERFETTO_TE( |
| rendering, PERFETTO_TE_COUNTER(), |
| PERFETTO_TE_COUNTER_TRACK("Framerate", PerfettoTeProcessTrackUuid()), |
| PERFETTO_TE_INT_COUNTER(120)); |
| } |
| } // namespace |
| |
| int run_main(const std::string& output_file_path) { |
| InitializePerfetto(); |
| auto tracing_session = StartTracing(); |
| |
| // Simulate some work that emits trace events. |
| DrawGame(); |
| |
| StopTracing(std::move(tracing_session), output_file_path); |
| return 0; |
| } |