1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2019-2021 Collabora, Ltd.
3*61046927SAndroid Build Coastguard Worker * Author: Antonio Caggiano <[email protected]>
4*61046927SAndroid Build Coastguard Worker * Author: Rohan Garg <[email protected]>
5*61046927SAndroid Build Coastguard Worker * Author: Robert Beckett <[email protected]>
6*61046927SAndroid Build Coastguard Worker * Author: Corentin Noël <[email protected]>
7*61046927SAndroid Build Coastguard Worker *
8*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
9*61046927SAndroid Build Coastguard Worker */
10*61046927SAndroid Build Coastguard Worker
11*61046927SAndroid Build Coastguard Worker #include "pps_datasource.h"
12*61046927SAndroid Build Coastguard Worker #include "pps_driver.h"
13*61046927SAndroid Build Coastguard Worker
14*61046927SAndroid Build Coastguard Worker #include <condition_variable>
15*61046927SAndroid Build Coastguard Worker #include <thread>
16*61046927SAndroid Build Coastguard Worker #include <variant>
17*61046927SAndroid Build Coastguard Worker #include <inttypes.h>
18*61046927SAndroid Build Coastguard Worker
19*61046927SAndroid Build Coastguard Worker // Minimum supported sampling period in nanoseconds
20*61046927SAndroid Build Coastguard Worker #define MIN_SAMPLING_PERIOD_NS 50000
21*61046927SAndroid Build Coastguard Worker
22*61046927SAndroid Build Coastguard Worker #define CORRELATION_TIMESTAMP_PERIOD (1000000000ull)
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker namespace pps
25*61046927SAndroid Build Coastguard Worker {
26*61046927SAndroid Build Coastguard Worker static std::string driver_name;
27*61046927SAndroid Build Coastguard Worker
28*61046927SAndroid Build Coastguard Worker /// Synchronize access to started_cv and started
29*61046927SAndroid Build Coastguard Worker static std::mutex started_m;
30*61046927SAndroid Build Coastguard Worker static std::condition_variable started_cv;
31*61046927SAndroid Build Coastguard Worker static bool started = false;
32*61046927SAndroid Build Coastguard Worker
ms(const std::chrono::nanoseconds & t)33*61046927SAndroid Build Coastguard Worker float ms(const std::chrono::nanoseconds &t)
34*61046927SAndroid Build Coastguard Worker {
35*61046927SAndroid Build Coastguard Worker return t.count() / 1000000.0f;
36*61046927SAndroid Build Coastguard Worker }
37*61046927SAndroid Build Coastguard Worker
OnSetup(const SetupArgs & args)38*61046927SAndroid Build Coastguard Worker void GpuDataSource::OnSetup(const SetupArgs &args)
39*61046927SAndroid Build Coastguard Worker {
40*61046927SAndroid Build Coastguard Worker // Create drivers for all supported devices
41*61046927SAndroid Build Coastguard Worker auto drm_devices = DrmDevice::create_all();
42*61046927SAndroid Build Coastguard Worker for (auto &drm_device : drm_devices) {
43*61046927SAndroid Build Coastguard Worker if (drm_device.name != driver_name)
44*61046927SAndroid Build Coastguard Worker continue;
45*61046927SAndroid Build Coastguard Worker
46*61046927SAndroid Build Coastguard Worker if (auto driver = Driver::get_driver(std::move(drm_device))) {
47*61046927SAndroid Build Coastguard Worker if (!driver->init_perfcnt()) {
48*61046927SAndroid Build Coastguard Worker // Skip failing driver
49*61046927SAndroid Build Coastguard Worker PPS_LOG_ERROR("Failed to initialize %s driver", driver->drm_device.name.c_str());
50*61046927SAndroid Build Coastguard Worker continue;
51*61046927SAndroid Build Coastguard Worker }
52*61046927SAndroid Build Coastguard Worker
53*61046927SAndroid Build Coastguard Worker this->driver = driver;
54*61046927SAndroid Build Coastguard Worker }
55*61046927SAndroid Build Coastguard Worker }
56*61046927SAndroid Build Coastguard Worker if (driver == nullptr) {
57*61046927SAndroid Build Coastguard Worker PPS_LOG_FATAL("No DRM devices supported");
58*61046927SAndroid Build Coastguard Worker }
59*61046927SAndroid Build Coastguard Worker
60*61046927SAndroid Build Coastguard Worker // Parse perfetto config
61*61046927SAndroid Build Coastguard Worker const std::string &config_raw = args.config->gpu_counter_config_raw();
62*61046927SAndroid Build Coastguard Worker perfetto::protos::pbzero::GpuCounterConfig::Decoder config(config_raw);
63*61046927SAndroid Build Coastguard Worker
64*61046927SAndroid Build Coastguard Worker if (config.has_counter_ids()) {
65*61046927SAndroid Build Coastguard Worker // Get enabled counters
66*61046927SAndroid Build Coastguard Worker PPS_LOG_IMPORTANT("Selecting counters");
67*61046927SAndroid Build Coastguard Worker for (auto it = config.counter_ids(); it; ++it) {
68*61046927SAndroid Build Coastguard Worker uint32_t counter_id = it->as_uint32();
69*61046927SAndroid Build Coastguard Worker driver->enable_counter(counter_id);
70*61046927SAndroid Build Coastguard Worker }
71*61046927SAndroid Build Coastguard Worker } else {
72*61046927SAndroid Build Coastguard Worker // Enable all counters
73*61046927SAndroid Build Coastguard Worker driver->enable_all_counters();
74*61046927SAndroid Build Coastguard Worker }
75*61046927SAndroid Build Coastguard Worker
76*61046927SAndroid Build Coastguard Worker // Get sampling period
77*61046927SAndroid Build Coastguard Worker auto min_sampling_period = std::chrono::nanoseconds(MIN_SAMPLING_PERIOD_NS);
78*61046927SAndroid Build Coastguard Worker
79*61046927SAndroid Build Coastguard Worker auto dev_supported = std::chrono::nanoseconds(driver->get_min_sampling_period_ns());
80*61046927SAndroid Build Coastguard Worker if (dev_supported > min_sampling_period) {
81*61046927SAndroid Build Coastguard Worker min_sampling_period = dev_supported;
82*61046927SAndroid Build Coastguard Worker }
83*61046927SAndroid Build Coastguard Worker
84*61046927SAndroid Build Coastguard Worker time_to_sleep = std::max(time_to_sleep, min_sampling_period);
85*61046927SAndroid Build Coastguard Worker
86*61046927SAndroid Build Coastguard Worker if (config.has_counter_period_ns()) {
87*61046927SAndroid Build Coastguard Worker auto requested_sampling_period = std::chrono::nanoseconds(config.counter_period_ns());
88*61046927SAndroid Build Coastguard Worker if (requested_sampling_period < min_sampling_period) {
89*61046927SAndroid Build Coastguard Worker PPS_LOG_ERROR("Sampling period should be greater than %" PRIu64 " ns (%.2f ms)",
90*61046927SAndroid Build Coastguard Worker uint64_t(min_sampling_period.count()),
91*61046927SAndroid Build Coastguard Worker ms(min_sampling_period));
92*61046927SAndroid Build Coastguard Worker } else {
93*61046927SAndroid Build Coastguard Worker time_to_sleep = requested_sampling_period;
94*61046927SAndroid Build Coastguard Worker }
95*61046927SAndroid Build Coastguard Worker }
96*61046927SAndroid Build Coastguard Worker PPS_LOG("Sampling period set to %" PRIu64 " ns", uint64_t(time_to_sleep.count()));
97*61046927SAndroid Build Coastguard Worker }
98*61046927SAndroid Build Coastguard Worker
OnStart(const StartArgs & args)99*61046927SAndroid Build Coastguard Worker void GpuDataSource::OnStart(const StartArgs &args)
100*61046927SAndroid Build Coastguard Worker {
101*61046927SAndroid Build Coastguard Worker driver->enable_perfcnt(time_to_sleep.count());
102*61046927SAndroid Build Coastguard Worker
103*61046927SAndroid Build Coastguard Worker state = State::Start;
104*61046927SAndroid Build Coastguard Worker got_first_counters = false;
105*61046927SAndroid Build Coastguard Worker
106*61046927SAndroid Build Coastguard Worker {
107*61046927SAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(started_m);
108*61046927SAndroid Build Coastguard Worker started = true;
109*61046927SAndroid Build Coastguard Worker }
110*61046927SAndroid Build Coastguard Worker started_cv.notify_all();
111*61046927SAndroid Build Coastguard Worker }
112*61046927SAndroid Build Coastguard Worker
close_callback(GpuDataSource::TraceContext ctx)113*61046927SAndroid Build Coastguard Worker void close_callback(GpuDataSource::TraceContext ctx)
114*61046927SAndroid Build Coastguard Worker {
115*61046927SAndroid Build Coastguard Worker auto packet = ctx.NewTracePacket();
116*61046927SAndroid Build Coastguard Worker packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME);
117*61046927SAndroid Build Coastguard Worker packet->set_timestamp(perfetto::base::GetBootTimeNs().count());
118*61046927SAndroid Build Coastguard Worker packet->Finalize();
119*61046927SAndroid Build Coastguard Worker ctx.Flush();
120*61046927SAndroid Build Coastguard Worker PPS_LOG("Context flushed");
121*61046927SAndroid Build Coastguard Worker }
122*61046927SAndroid Build Coastguard Worker
OnStop(const StopArgs & args)123*61046927SAndroid Build Coastguard Worker void GpuDataSource::OnStop(const StopArgs &args)
124*61046927SAndroid Build Coastguard Worker {
125*61046927SAndroid Build Coastguard Worker state = State::Stop;
126*61046927SAndroid Build Coastguard Worker auto stop_closure = args.HandleStopAsynchronously();
127*61046927SAndroid Build Coastguard Worker Trace(close_callback);
128*61046927SAndroid Build Coastguard Worker stop_closure();
129*61046927SAndroid Build Coastguard Worker
130*61046927SAndroid Build Coastguard Worker driver->disable_perfcnt();
131*61046927SAndroid Build Coastguard Worker driver = nullptr;
132*61046927SAndroid Build Coastguard Worker
133*61046927SAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(started_m);
134*61046927SAndroid Build Coastguard Worker started = false;
135*61046927SAndroid Build Coastguard Worker }
136*61046927SAndroid Build Coastguard Worker
wait_started()137*61046927SAndroid Build Coastguard Worker void GpuDataSource::wait_started()
138*61046927SAndroid Build Coastguard Worker {
139*61046927SAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(started_m);
140*61046927SAndroid Build Coastguard Worker if (!started) {
141*61046927SAndroid Build Coastguard Worker PPS_LOG("Waiting for start");
142*61046927SAndroid Build Coastguard Worker started_cv.wait(lock, [] { return started; });
143*61046927SAndroid Build Coastguard Worker }
144*61046927SAndroid Build Coastguard Worker }
145*61046927SAndroid Build Coastguard Worker
register_data_source(const std::string & _driver_name)146*61046927SAndroid Build Coastguard Worker void GpuDataSource::register_data_source(const std::string &_driver_name)
147*61046927SAndroid Build Coastguard Worker {
148*61046927SAndroid Build Coastguard Worker driver_name = _driver_name;
149*61046927SAndroid Build Coastguard Worker static perfetto::DataSourceDescriptor dsd;
150*61046927SAndroid Build Coastguard Worker dsd.set_name("gpu.counters." + driver_name);
151*61046927SAndroid Build Coastguard Worker Register(dsd);
152*61046927SAndroid Build Coastguard Worker }
153*61046927SAndroid Build Coastguard Worker
add_group(perfetto::protos::pbzero::GpuCounterDescriptor * desc,const CounterGroup & group,const std::string & prefix,int32_t gpu_num)154*61046927SAndroid Build Coastguard Worker void add_group(perfetto::protos::pbzero::GpuCounterDescriptor *desc,
155*61046927SAndroid Build Coastguard Worker const CounterGroup &group,
156*61046927SAndroid Build Coastguard Worker const std::string &prefix,
157*61046927SAndroid Build Coastguard Worker int32_t gpu_num)
158*61046927SAndroid Build Coastguard Worker {
159*61046927SAndroid Build Coastguard Worker if (!group.counters.empty()) {
160*61046927SAndroid Build Coastguard Worker // Define a block for each group containing counters
161*61046927SAndroid Build Coastguard Worker auto block_desc = desc->add_blocks();
162*61046927SAndroid Build Coastguard Worker block_desc->set_name(prefix + "." + group.name);
163*61046927SAndroid Build Coastguard Worker block_desc->set_block_id(group.id);
164*61046927SAndroid Build Coastguard Worker
165*61046927SAndroid Build Coastguard Worker // Associate counters to blocks
166*61046927SAndroid Build Coastguard Worker for (auto id : group.counters) {
167*61046927SAndroid Build Coastguard Worker block_desc->add_counter_ids(id);
168*61046927SAndroid Build Coastguard Worker }
169*61046927SAndroid Build Coastguard Worker }
170*61046927SAndroid Build Coastguard Worker
171*61046927SAndroid Build Coastguard Worker for (auto const &sub : group.subgroups) {
172*61046927SAndroid Build Coastguard Worker // Perfetto doesnt currently support nested groups.
173*61046927SAndroid Build Coastguard Worker // Flatten group hierarchy, using dot separator
174*61046927SAndroid Build Coastguard Worker add_group(desc, sub, prefix + "." + group.name, gpu_num);
175*61046927SAndroid Build Coastguard Worker }
176*61046927SAndroid Build Coastguard Worker }
177*61046927SAndroid Build Coastguard Worker
add_descriptors(perfetto::protos::pbzero::GpuCounterEvent * event,std::vector<CounterGroup> const & groups,std::vector<Counter> const & counters,Driver & driver)178*61046927SAndroid Build Coastguard Worker void add_descriptors(perfetto::protos::pbzero::GpuCounterEvent *event,
179*61046927SAndroid Build Coastguard Worker std::vector<CounterGroup> const &groups,
180*61046927SAndroid Build Coastguard Worker std::vector<Counter> const &counters,
181*61046927SAndroid Build Coastguard Worker Driver &driver)
182*61046927SAndroid Build Coastguard Worker {
183*61046927SAndroid Build Coastguard Worker // Start a counter descriptor
184*61046927SAndroid Build Coastguard Worker auto desc = event->set_counter_descriptor();
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker // Add the groups
187*61046927SAndroid Build Coastguard Worker for (auto const &group : groups) {
188*61046927SAndroid Build Coastguard Worker add_group(desc, group, driver.drm_device.name, driver.drm_device.gpu_num);
189*61046927SAndroid Build Coastguard Worker }
190*61046927SAndroid Build Coastguard Worker
191*61046927SAndroid Build Coastguard Worker // Add the counters
192*61046927SAndroid Build Coastguard Worker for (auto const &counter : counters) {
193*61046927SAndroid Build Coastguard Worker auto spec = desc->add_specs();
194*61046927SAndroid Build Coastguard Worker spec->set_counter_id(counter.id);
195*61046927SAndroid Build Coastguard Worker spec->set_name(counter.name);
196*61046927SAndroid Build Coastguard Worker
197*61046927SAndroid Build Coastguard Worker auto units = perfetto::protos::pbzero::GpuCounterDescriptor::NONE;
198*61046927SAndroid Build Coastguard Worker switch (counter.units) {
199*61046927SAndroid Build Coastguard Worker case Counter::Units::Percent:
200*61046927SAndroid Build Coastguard Worker units = perfetto::protos::pbzero::GpuCounterDescriptor::PERCENT;
201*61046927SAndroid Build Coastguard Worker break;
202*61046927SAndroid Build Coastguard Worker case Counter::Units::Byte:
203*61046927SAndroid Build Coastguard Worker units = perfetto::protos::pbzero::GpuCounterDescriptor::BYTE;
204*61046927SAndroid Build Coastguard Worker break;
205*61046927SAndroid Build Coastguard Worker case Counter::Units::Hertz:
206*61046927SAndroid Build Coastguard Worker units = perfetto::protos::pbzero::GpuCounterDescriptor::HERTZ;
207*61046927SAndroid Build Coastguard Worker break;
208*61046927SAndroid Build Coastguard Worker case Counter::Units::None:
209*61046927SAndroid Build Coastguard Worker units = perfetto::protos::pbzero::GpuCounterDescriptor::NONE;
210*61046927SAndroid Build Coastguard Worker break;
211*61046927SAndroid Build Coastguard Worker default:
212*61046927SAndroid Build Coastguard Worker assert(false && "Missing counter units type!");
213*61046927SAndroid Build Coastguard Worker break;
214*61046927SAndroid Build Coastguard Worker }
215*61046927SAndroid Build Coastguard Worker spec->add_numerator_units(units);
216*61046927SAndroid Build Coastguard Worker }
217*61046927SAndroid Build Coastguard Worker }
218*61046927SAndroid Build Coastguard Worker
add_samples(perfetto::protos::pbzero::GpuCounterEvent & event,const Driver & driver)219*61046927SAndroid Build Coastguard Worker void add_samples(perfetto::protos::pbzero::GpuCounterEvent &event, const Driver &driver)
220*61046927SAndroid Build Coastguard Worker {
221*61046927SAndroid Build Coastguard Worker if (driver.enabled_counters.size() == 0) {
222*61046927SAndroid Build Coastguard Worker PPS_LOG_FATAL("There are no counters enabled");
223*61046927SAndroid Build Coastguard Worker }
224*61046927SAndroid Build Coastguard Worker
225*61046927SAndroid Build Coastguard Worker for (const auto &counter : driver.enabled_counters) {
226*61046927SAndroid Build Coastguard Worker auto counter_event = event.add_counters();
227*61046927SAndroid Build Coastguard Worker
228*61046927SAndroid Build Coastguard Worker counter_event->set_counter_id(counter.id);
229*61046927SAndroid Build Coastguard Worker
230*61046927SAndroid Build Coastguard Worker auto value = counter.get_value(driver);
231*61046927SAndroid Build Coastguard Worker if (auto d_value = std::get_if<double>(&value)) {
232*61046927SAndroid Build Coastguard Worker counter_event->set_double_value(*d_value);
233*61046927SAndroid Build Coastguard Worker } else if (auto i_value = std::get_if<int64_t>(&value)) {
234*61046927SAndroid Build Coastguard Worker counter_event->set_int_value(*i_value);
235*61046927SAndroid Build Coastguard Worker } else {
236*61046927SAndroid Build Coastguard Worker PPS_LOG_ERROR("Failed to get value for counter %s", counter.name.c_str());
237*61046927SAndroid Build Coastguard Worker }
238*61046927SAndroid Build Coastguard Worker }
239*61046927SAndroid Build Coastguard Worker }
240*61046927SAndroid Build Coastguard Worker
add_timestamp(perfetto::protos::pbzero::ClockSnapshot * event,const Driver * driver)241*61046927SAndroid Build Coastguard Worker void add_timestamp(perfetto::protos::pbzero::ClockSnapshot *event, const Driver *driver)
242*61046927SAndroid Build Coastguard Worker {
243*61046927SAndroid Build Coastguard Worker uint32_t gpu_clock_id = driver->gpu_clock_id();
244*61046927SAndroid Build Coastguard Worker if (perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME == gpu_clock_id)
245*61046927SAndroid Build Coastguard Worker return;
246*61046927SAndroid Build Coastguard Worker
247*61046927SAndroid Build Coastguard Worker // Send a correlation event between GPU & CPU timestamps
248*61046927SAndroid Build Coastguard Worker uint64_t cpu_ts, gpu_ts;
249*61046927SAndroid Build Coastguard Worker
250*61046927SAndroid Build Coastguard Worker // Try to use the optimized driver correlation if available, otherwise do a
251*61046927SAndroid Build Coastguard Worker // separate CPU & GPU sample
252*61046927SAndroid Build Coastguard Worker if (!driver->cpu_gpu_timestamp(cpu_ts, gpu_ts)) {
253*61046927SAndroid Build Coastguard Worker cpu_ts = perfetto::base::GetBootTimeNs().count();
254*61046927SAndroid Build Coastguard Worker gpu_ts = driver->gpu_timestamp();
255*61046927SAndroid Build Coastguard Worker }
256*61046927SAndroid Build Coastguard Worker
257*61046927SAndroid Build Coastguard Worker {
258*61046927SAndroid Build Coastguard Worker auto clock = event->add_clocks();
259*61046927SAndroid Build Coastguard Worker
260*61046927SAndroid Build Coastguard Worker clock->set_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME);
261*61046927SAndroid Build Coastguard Worker clock->set_timestamp(cpu_ts);
262*61046927SAndroid Build Coastguard Worker }
263*61046927SAndroid Build Coastguard Worker
264*61046927SAndroid Build Coastguard Worker {
265*61046927SAndroid Build Coastguard Worker auto clock = event->add_clocks();
266*61046927SAndroid Build Coastguard Worker
267*61046927SAndroid Build Coastguard Worker clock->set_clock_id(gpu_clock_id);
268*61046927SAndroid Build Coastguard Worker clock->set_timestamp(gpu_ts);
269*61046927SAndroid Build Coastguard Worker }
270*61046927SAndroid Build Coastguard Worker }
271*61046927SAndroid Build Coastguard Worker
trace(TraceContext & ctx)272*61046927SAndroid Build Coastguard Worker void GpuDataSource::trace(TraceContext &ctx)
273*61046927SAndroid Build Coastguard Worker {
274*61046927SAndroid Build Coastguard Worker using namespace perfetto::protos::pbzero;
275*61046927SAndroid Build Coastguard Worker
276*61046927SAndroid Build Coastguard Worker if (auto state = ctx.GetIncrementalState(); state->was_cleared) {
277*61046927SAndroid Build Coastguard Worker descriptor_timestamp = perfetto::base::GetBootTimeNs().count();
278*61046927SAndroid Build Coastguard Worker
279*61046927SAndroid Build Coastguard Worker {
280*61046927SAndroid Build Coastguard Worker // Mark any incremental state before this point invalid
281*61046927SAndroid Build Coastguard Worker auto packet = ctx.NewTracePacket();
282*61046927SAndroid Build Coastguard Worker packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME);
283*61046927SAndroid Build Coastguard Worker packet->set_timestamp(descriptor_timestamp);
284*61046927SAndroid Build Coastguard Worker packet->set_sequence_flags(TracePacket::SEQ_INCREMENTAL_STATE_CLEARED);
285*61046927SAndroid Build Coastguard Worker }
286*61046927SAndroid Build Coastguard Worker
287*61046927SAndroid Build Coastguard Worker descriptor_timestamp = perfetto::base::GetBootTimeNs().count();
288*61046927SAndroid Build Coastguard Worker {
289*61046927SAndroid Build Coastguard Worker // Counter descriptions
290*61046927SAndroid Build Coastguard Worker auto packet = ctx.NewTracePacket();
291*61046927SAndroid Build Coastguard Worker packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME);
292*61046927SAndroid Build Coastguard Worker packet->set_timestamp(descriptor_timestamp);
293*61046927SAndroid Build Coastguard Worker auto event = packet->set_gpu_counter_event();
294*61046927SAndroid Build Coastguard Worker event->set_gpu_id(driver->drm_device.gpu_num);
295*61046927SAndroid Build Coastguard Worker
296*61046927SAndroid Build Coastguard Worker auto &groups = driver->groups;
297*61046927SAndroid Build Coastguard Worker auto &counters = driver->enabled_counters;
298*61046927SAndroid Build Coastguard Worker add_descriptors(event, groups, counters, *driver);
299*61046927SAndroid Build Coastguard Worker }
300*61046927SAndroid Build Coastguard Worker
301*61046927SAndroid Build Coastguard Worker {
302*61046927SAndroid Build Coastguard Worker // Initial timestamp correlation event
303*61046927SAndroid Build Coastguard Worker auto packet = ctx.NewTracePacket();
304*61046927SAndroid Build Coastguard Worker packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME);
305*61046927SAndroid Build Coastguard Worker packet->set_timestamp(descriptor_timestamp);
306*61046927SAndroid Build Coastguard Worker last_correlation_timestamp = perfetto::base::GetBootTimeNs().count();
307*61046927SAndroid Build Coastguard Worker auto event = packet->set_clock_snapshot();
308*61046927SAndroid Build Coastguard Worker add_timestamp(event, driver);
309*61046927SAndroid Build Coastguard Worker }
310*61046927SAndroid Build Coastguard Worker
311*61046927SAndroid Build Coastguard Worker // Capture GPU timestamp of the first packet. Anything prior to this can
312*61046927SAndroid Build Coastguard Worker // be discarded.
313*61046927SAndroid Build Coastguard Worker descriptor_gpu_timestamp = driver->gpu_timestamp();
314*61046927SAndroid Build Coastguard Worker state->was_cleared = false;
315*61046927SAndroid Build Coastguard Worker }
316*61046927SAndroid Build Coastguard Worker
317*61046927SAndroid Build Coastguard Worker if (driver->dump_perfcnt()) {
318*61046927SAndroid Build Coastguard Worker while (auto gpu_timestamp = driver->next()) {
319*61046927SAndroid Build Coastguard Worker if (gpu_timestamp <= descriptor_gpu_timestamp) {
320*61046927SAndroid Build Coastguard Worker // Do not send counter values before counter descriptors
321*61046927SAndroid Build Coastguard Worker PPS_LOG_ERROR("Skipping counter values coming before descriptors");
322*61046927SAndroid Build Coastguard Worker continue;
323*61046927SAndroid Build Coastguard Worker }
324*61046927SAndroid Build Coastguard Worker
325*61046927SAndroid Build Coastguard Worker if (!got_first_counters) {
326*61046927SAndroid Build Coastguard Worker PPS_LOG("Got first counters at gpu_ts=0x%016" PRIx64, gpu_timestamp);
327*61046927SAndroid Build Coastguard Worker got_first_counters = true;
328*61046927SAndroid Build Coastguard Worker }
329*61046927SAndroid Build Coastguard Worker
330*61046927SAndroid Build Coastguard Worker auto packet = ctx.NewTracePacket();
331*61046927SAndroid Build Coastguard Worker packet->set_timestamp_clock_id(driver->gpu_clock_id());
332*61046927SAndroid Build Coastguard Worker packet->set_timestamp(gpu_timestamp);
333*61046927SAndroid Build Coastguard Worker
334*61046927SAndroid Build Coastguard Worker auto event = packet->set_gpu_counter_event();
335*61046927SAndroid Build Coastguard Worker event->set_gpu_id(driver->drm_device.gpu_num);
336*61046927SAndroid Build Coastguard Worker
337*61046927SAndroid Build Coastguard Worker add_samples(*event, *driver);
338*61046927SAndroid Build Coastguard Worker }
339*61046927SAndroid Build Coastguard Worker }
340*61046927SAndroid Build Coastguard Worker
341*61046927SAndroid Build Coastguard Worker uint64_t cpu_ts = perfetto::base::GetBootTimeNs().count();
342*61046927SAndroid Build Coastguard Worker if ((cpu_ts - last_correlation_timestamp) > CORRELATION_TIMESTAMP_PERIOD) {
343*61046927SAndroid Build Coastguard Worker auto packet = ctx.NewTracePacket();
344*61046927SAndroid Build Coastguard Worker packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME);
345*61046927SAndroid Build Coastguard Worker packet->set_timestamp(cpu_ts);
346*61046927SAndroid Build Coastguard Worker auto event = packet->set_clock_snapshot();
347*61046927SAndroid Build Coastguard Worker add_timestamp(event, driver);
348*61046927SAndroid Build Coastguard Worker last_correlation_timestamp = cpu_ts;
349*61046927SAndroid Build Coastguard Worker }
350*61046927SAndroid Build Coastguard Worker }
351*61046927SAndroid Build Coastguard Worker
trace_callback(TraceContext ctx)352*61046927SAndroid Build Coastguard Worker void GpuDataSource::trace_callback(TraceContext ctx)
353*61046927SAndroid Build Coastguard Worker {
354*61046927SAndroid Build Coastguard Worker using namespace std::chrono;
355*61046927SAndroid Build Coastguard Worker
356*61046927SAndroid Build Coastguard Worker nanoseconds sleep_time = nanoseconds(0);
357*61046927SAndroid Build Coastguard Worker
358*61046927SAndroid Build Coastguard Worker if (auto data_source = ctx.GetDataSourceLocked()) {
359*61046927SAndroid Build Coastguard Worker if (data_source->time_to_sleep > data_source->time_to_trace) {
360*61046927SAndroid Build Coastguard Worker sleep_time = data_source->time_to_sleep - data_source->time_to_trace;
361*61046927SAndroid Build Coastguard Worker }
362*61046927SAndroid Build Coastguard Worker }
363*61046927SAndroid Build Coastguard Worker
364*61046927SAndroid Build Coastguard Worker // Wait sampling period before tracing
365*61046927SAndroid Build Coastguard Worker std::this_thread::sleep_for(sleep_time);
366*61046927SAndroid Build Coastguard Worker
367*61046927SAndroid Build Coastguard Worker auto time_zero = perfetto::base::GetBootTimeNs();
368*61046927SAndroid Build Coastguard Worker if (auto data_source = ctx.GetDataSourceLocked()) {
369*61046927SAndroid Build Coastguard Worker // Check data source is still running
370*61046927SAndroid Build Coastguard Worker if (data_source->state == pps::State::Start) {
371*61046927SAndroid Build Coastguard Worker data_source->trace(ctx);
372*61046927SAndroid Build Coastguard Worker data_source->time_to_trace = perfetto::base::GetBootTimeNs() - time_zero;
373*61046927SAndroid Build Coastguard Worker }
374*61046927SAndroid Build Coastguard Worker } else {
375*61046927SAndroid Build Coastguard Worker PPS_LOG("Tracing finished");
376*61046927SAndroid Build Coastguard Worker }
377*61046927SAndroid Build Coastguard Worker }
378*61046927SAndroid Build Coastguard Worker
379*61046927SAndroid Build Coastguard Worker } // namespace pps
380