| /* | |
| * 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 <chrono> | |
| #include <thread> | |
| // 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" // no-include-violation-check | |
| #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<MyDataSource> { | |
| 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<int>(config.counter_period_ns()); | |
| std::vector<uint32_t> 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)); | |
| } | |
| } |