/* * Copyright (C) 2019 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. */ #include #include // This source file is built in two ways: // 1. As part of the regular GN build, against standard includes. // 2. To test that the amalgmated SDK works, against the perfetto.h source. #ifdef PERFETTO_AMALGAMATED_SDK_TEST #include "perfetto.h" #else #include "perfetto/tracing.h" #include "protos/perfetto/config/gpu/gpu_counter_config.pbzero.h" #include "protos/perfetto/trace/gpu/gpu_counter_event.pbzero.h" #include "protos/perfetto/trace/test_event.pbzero.h" #include "protos/perfetto/trace/trace_packet.pbzero.h" #endif // Deliberately not pulling any non-public perfetto header to spot accidental // header public -> non-public dependency while building this file. namespace { class MyDataSource : public perfetto::DataSource { public: void OnSetup(const SetupArgs& args) override { // This can be used to access the domain-specific DataSourceConfig, via // args.config->xxx_config_raw(). const std::string& config_raw = args.config->gpu_counter_config_raw(); perfetto::protos::pbzero::GpuCounterConfig::Decoder config(config_raw); int sample_period = 0; if (config.has_counter_period_ns()) sample_period = static_cast(config.counter_period_ns()); std::vector counter_ids; for (auto it = config.counter_ids(); it; ++it) { uint32_t counter_id = it->as_uint32(); if (counter_id > 0) { counter_ids.push_back(counter_id); } } PERFETTO_ILOG( "OnSetup called, name: %s," "counter_period_ms: %d, tracing_session_id: %" PRIu64 " num counters: %zu", args.config->name().c_str(), int(sample_period / 1000000), args.config->tracing_session_id(), counter_ids.size()); } void OnStart(const StartArgs&) override { PERFETTO_ILOG("OnStart called"); } void OnStop(const StopArgs& stop_args) override { PERFETTO_ILOG("OnStop called"); auto stop_closure = stop_args.HandleStopAsynchronously(); // It is possible to trace on stop as well, but doing so requires manually // calling Flush() at the end. MyDataSource::Trace([](MyDataSource::TraceContext ctx) { PERFETTO_LOG("Tracing lambda called while stopping"); // This block here is to auto-finalize the packet before calling Flush. { auto packet = ctx.NewTracePacket(); packet->set_timestamp(999); } ctx.Flush(); }); stop_closure(); } }; } // namespace PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(MyDataSource); PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(MyDataSource); int main() { perfetto::TracingInitArgs args; args.backends = perfetto::kSystemBackend; perfetto::Tracing::Initialize(args); // DataSourceDescriptor can be used to advertise domain-specific features. perfetto::DataSourceDescriptor dsd; dsd.set_name("com.example.mytrace"); MyDataSource::Register(dsd); for (;;) { MyDataSource::Trace([](MyDataSource::TraceContext ctx) { PERFETTO_LOG("Tracing lambda called"); auto packet = ctx.NewTracePacket(); packet->set_timestamp(42); auto* gpu_packet = packet->set_gpu_counter_event(); auto* cnt = gpu_packet->add_counters(); cnt->set_counter_id(1); }); std::this_thread::sleep_for(std::chrono::seconds(1)); } }