1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2019-2021 Collabora, Ltd.
3bf215546Sopenharmony_ci * Author: Antonio Caggiano <antonio.caggiano@collabora.com>
4bf215546Sopenharmony_ci * Author: Robert Beckett <bob.beckett@collabora.com>
5bf215546Sopenharmony_ci * Author: Corentin Noël <corentin.noel@collabora.com>
6bf215546Sopenharmony_ci *
7bf215546Sopenharmony_ci * SPDX-License-Identifier: MIT
8bf215546Sopenharmony_ci */
9bf215546Sopenharmony_ci
10bf215546Sopenharmony_ci#pragma once
11bf215546Sopenharmony_ci
12bf215546Sopenharmony_ci#include "pps.h"
13bf215546Sopenharmony_ci#include "pps_driver.h"
14bf215546Sopenharmony_ci
15bf215546Sopenharmony_cinamespace pps
16bf215546Sopenharmony_ci{
17bf215546Sopenharmony_cistruct GpuIncrementalState {
18bf215546Sopenharmony_ci   bool was_cleared = true;
19bf215546Sopenharmony_ci};
20bf215546Sopenharmony_ci
21bf215546Sopenharmony_cistruct GpuDataSourceTraits : public perfetto::DefaultDataSourceTraits {
22bf215546Sopenharmony_ci   using IncrementalStateType = GpuIncrementalState;
23bf215546Sopenharmony_ci};
24bf215546Sopenharmony_ci
25bf215546Sopenharmony_ciclass Driver;
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci/// @brief This datasource samples performance counters at a specified rate.
28bf215546Sopenharmony_ci/// Once the data is available, it sends a protobuf packet to the perfetto service.
29bf215546Sopenharmony_ci/// At the very beginning, it sends a description of the counters.
30bf215546Sopenharmony_ci/// After that, it sends counter values using the IDs set in the description.
31bf215546Sopenharmony_ciclass GpuDataSource : public perfetto::DataSource<GpuDataSource, GpuDataSourceTraits>
32bf215546Sopenharmony_ci{
33bf215546Sopenharmony_ci   public:
34bf215546Sopenharmony_ci   void OnSetup(const SetupArgs &args) override;
35bf215546Sopenharmony_ci   void OnStart(const StartArgs &args) override;
36bf215546Sopenharmony_ci   void OnStop(const StopArgs &args) override;
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci   /// Blocks until the data source starts
39bf215546Sopenharmony_ci   static void wait_started();
40bf215546Sopenharmony_ci
41bf215546Sopenharmony_ci   /// @brief Perfetto trace callback
42bf215546Sopenharmony_ci   static void trace_callback(TraceContext ctx);
43bf215546Sopenharmony_ci   static void register_data_source(const std::string &driver_name);
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_ci   void trace(TraceContext &ctx);
46bf215546Sopenharmony_ci
47bf215546Sopenharmony_ci   private:
48bf215546Sopenharmony_ci   State state = State::Stop;
49bf215546Sopenharmony_ci
50bf215546Sopenharmony_ci   /// Time between trace callbacks
51bf215546Sopenharmony_ci   std::chrono::nanoseconds time_to_sleep = std::chrono::nanoseconds(1000000);
52bf215546Sopenharmony_ci
53bf215546Sopenharmony_ci   /// Used to check whether the datasource is quick enough
54bf215546Sopenharmony_ci   std::chrono::nanoseconds time_to_trace;
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_ci   /// Last CPU timestamp at which we correlated CPU/GPU timestamps
57bf215546Sopenharmony_ci   uint64_t last_correlation_timestamp = 0;
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_ci   /// A data source supports one driver at a time, but if you need more
60bf215546Sopenharmony_ci   /// than one gpu datasource you can just run another producer
61bf215546Sopenharmony_ci   Driver *driver = nullptr;
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_ci   /// CPU timestamp of packet sent with counter descriptors
64bf215546Sopenharmony_ci   uint64_t descriptor_timestamp = 0;
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci   /// GPU timestamp of packet sent with counter descriptors
67bf215546Sopenharmony_ci   uint64_t descriptor_gpu_timestamp = 0;
68bf215546Sopenharmony_ci};
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_ci} // namespace pps
71