blob: 3911715882e567d6756eb1b4a17af1a46fee6d22 [file] [log] [blame]
Avi Drissman05dfbc822022-09-13 21:25:341// Copyright 2012 The Chromium Authors
dsinclair@chromium.orgfb97b662013-02-20 23:02:142// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// This file contains the GPUTrace class.
6#ifndef GPU_COMMAND_BUFFER_SERVICE_GPU_TRACER_H_
7#define GPU_COMMAND_BUFFER_SERVICE_GPU_TRACER_H_
8
avif15d60a2015-12-21 17:06:339#include <stdint.h>
10
Kalvin Lee9e2c2e82025-04-16 22:37:4211#include <array>
mostynb6682b1c42016-04-19 10:17:3012#include <memory>
dsinclair@chromium.orgfb97b662013-02-20 23:02:1413#include <string>
dcastagna82922f82015-02-12 19:21:3014#include <vector>
dsinclair@chromium.orgfb97b662013-02-20 23:02:1415
Brett Wilson55ff1475e2017-09-26 00:28:4816#include "base/containers/circular_deque.h"
Brett Wilson1f07f20e2017-10-02 18:55:2817#include "base/containers/stack.h"
Keishi Hattori0e45c022021-11-27 09:25:5218#include "base/memory/raw_ptr.h"
vmiura@chromium.orgf71dc362014-01-08 21:50:5019#include "base/threading/thread.h"
Gabriel Charetted87f10f2022-03-31 00:44:2220#include "base/time/time.h"
Antoine Labour83a0aed12018-01-10 04:52:3821#include "gpu/gpu_gles2_export.h"
dsinclair@chromium.orgfb97b662013-02-20 23:02:1422
kylechar7a463842016-05-26 14:46:1223namespace gl {
24class GPUTimingClient;
25class GPUTimer;
Jonathan Backere26739c2018-05-15 13:27:0726} // namespace gl
dyen5b1c02ff2015-02-26 01:54:0027
dsinclair@chromium.orgfb97b662013-02-20 23:02:1428namespace gpu {
Jonathan Backere26739c2018-05-15 13:27:0729
30class DecoderContext;
31
dsinclair@chromium.orgfb97b662013-02-20 23:02:1432namespace gles2 {
33
dyen@chromium.orgb4af07d2014-08-20 00:11:5734class Outputter;
35class GPUTrace;
36
vmiura@chromium.orgcac16542014-01-15 17:53:5137// Id used to keep trace namespaces separate
38enum GpuTracerSource {
dyen@chromium.orgb4af07d2014-08-20 00:11:5739 kTraceGroupInvalid = -1,
40
dyen53749b42015-06-12 20:53:1141 kTraceCHROMIUM,
42 kTraceDecoder,
Jonathan Backere26739c2018-05-15 13:27:0743 kTraceDisjoint, // Used internally.
dyen@chromium.orgb4af07d2014-08-20 00:11:5744
45 NUM_TRACER_SOURCES
46};
47
48// Marker structure for a Trace.
49struct TraceMarker {
dyencb86f2f2014-12-09 18:35:4150 TraceMarker(const std::string& category, const std::string& name);
vmpstr3b7b8b22016-03-01 23:00:2051 TraceMarker(const TraceMarker& other);
dyen@chromium.orgb4af07d2014-08-20 00:11:5752 ~TraceMarker();
53
dyencb86f2f2014-12-09 18:35:4154 std::string category_;
dyen@chromium.orgb4af07d2014-08-20 00:11:5755 std::string name_;
56 scoped_refptr<GPUTrace> trace_;
vmiura@chromium.orgcac16542014-01-15 17:53:5157};
58
dsinclair@chromium.orgfb97b662013-02-20 23:02:1459// Traces GPU Commands.
Antoine Labour83a0aed12018-01-10 04:52:3860class GPU_GLES2_EXPORT GPUTracer {
dsinclair@chromium.orgfb97b662013-02-20 23:02:1461 public:
Kramer Ge254a8ff2020-02-03 20:01:5862 explicit GPUTracer(DecoderContext* decoder, bool context_is_gl = true);
Peter BostrΓΆmdbacdc22021-09-23 22:11:4663
64 GPUTracer(const GPUTracer&) = delete;
65 GPUTracer& operator=(const GPUTracer&) = delete;
66
dyen75755fa2015-01-07 22:55:0767 virtual ~GPUTracer();
dsinclair@chromium.orgfb97b662013-02-20 23:02:1468
dyendbfb90d2015-03-26 02:41:4669 void Destroy(bool have_context);
70
vmiura@chromium.orgcac16542014-01-15 17:53:5171 // Scheduled processing in decoder begins.
dyen@chromium.orgb4af07d2014-08-20 00:11:5772 bool BeginDecoding();
dsinclair@chromium.orgfb97b662013-02-20 23:02:1473
vmiura@chromium.orgcac16542014-01-15 17:53:5174 // Scheduled processing in decoder ends.
dyen@chromium.orgb4af07d2014-08-20 00:11:5775 bool EndDecoding();
vmiura@chromium.orgcac16542014-01-15 17:53:5176
77 // Begin a trace marker.
dyencb86f2f2014-12-09 18:35:4178 bool Begin(const std::string& category, const std::string& name,
79 GpuTracerSource source);
vmiura@chromium.orgcac16542014-01-15 17:53:5180
81 // End the last started trace marker.
dyen@chromium.orgb4af07d2014-08-20 00:11:5782 bool End(GpuTracerSource source);
vmiura@chromium.orgcac16542014-01-15 17:53:5183
dyened04ca3e2015-08-26 21:05:0184 bool HasTracesToProcess();
85 void ProcessTraces();
86
dyen75755fa2015-01-07 22:55:0787 virtual bool IsTracing();
dsinclair@chromium.orgfb97b662013-02-20 23:02:1488
89 // Retrieve the name of the current open trace.
90 // Returns empty string if no current open trace.
dyen4bb43282015-01-08 01:09:5691 const std::string& CurrentCategory(GpuTracerSource source) const;
92 const std::string& CurrentName(GpuTracerSource source) const;
dsinclair@chromium.orgfb97b662013-02-20 23:02:1493
dyen75755fa2015-01-07 22:55:0794 protected:
Kramer Ge254a8ff2020-02-03 20:01:5895 bool is_gpu_service_tracing_enabled() {
96 return *gpu_trace_srv_category_ != 0;
97 }
98 bool is_gpu_device_tracing_enabled() {
99 return *gpu_trace_dev_category_ != 0 && can_trace_dev_;
100 }
101
Chandan Padhi07f05c02017-09-19 02:52:53102 scoped_refptr<gl::GPUTimingClient> gpu_timing_client_;
Ali Hijazif5d8b742024-05-29 16:10:43103 raw_ptr<const unsigned char> gpu_trace_srv_category_;
104 raw_ptr<const unsigned char> gpu_trace_dev_category_;
Kramer Ge254a8ff2020-02-03 20:01:58105 // Disable gpu.device tracing if context is corrupted or not GL.
106 bool can_trace_dev_;
dyen75755fa2015-01-07 22:55:07107
Chandan Padhi07f05c02017-09-19 02:52:53108 private:
dyen53749b42015-06-12 20:53:11109 bool CheckDisjointStatus();
110 void ClearOngoingTraces(bool have_context);
dyen@chromium.orgb4af07d2014-08-20 00:11:57111
Keishi Hattori0e45c022021-11-27 09:25:52112 raw_ptr<Outputter> outputter_ = nullptr;
Kalvin Lee9e2c2e82025-04-16 22:37:42113 std::array<std::vector<TraceMarker>, NUM_TRACER_SOURCES> markers_;
Brett Wilson55ff1475e2017-09-26 00:28:48114 base::circular_deque<scoped_refptr<GPUTrace>> finished_traces_;
Keishi Hattori0e45c022021-11-27 09:25:52115 raw_ptr<DecoderContext> decoder_;
avif15d60a2015-12-21 17:06:33116 int64_t disjoint_time_ = 0;
dyen53749b42015-06-12 20:53:11117 bool gpu_executing_ = false;
dyena56208c2015-06-25 01:43:40118 bool began_device_traces_ = false;
dsinclair@chromium.orgfb97b662013-02-20 23:02:14119};
120
Antoine Labour83a0aed12018-01-10 04:52:38121class GPU_GLES2_EXPORT Outputter {
vmiura@chromium.orgf71dc362014-01-08 21:50:50122 public:
Chris Watkins81030772017-12-07 01:20:56123 virtual ~Outputter() = default;
Chandan Padhi07f05c02017-09-19 02:52:53124
dyen06ae0b22015-05-07 03:45:52125 virtual void TraceDevice(GpuTracerSource source,
126 const std::string& category,
dyen75755fa2015-01-07 22:55:07127 const std::string& name,
avif15d60a2015-12-21 17:06:33128 int64_t start_time,
129 int64_t end_time) = 0;
dyen75755fa2015-01-07 22:55:07130
dyen06ae0b22015-05-07 03:45:52131 virtual void TraceServiceBegin(GpuTracerSource source,
132 const std::string& category,
dyen81aaafd2015-01-16 21:51:11133 const std::string& name) = 0;
dyen75755fa2015-01-07 22:55:07134
dyen06ae0b22015-05-07 03:45:52135 virtual void TraceServiceEnd(GpuTracerSource source,
136 const std::string& category,
dyen81aaafd2015-01-16 21:51:11137 const std::string& name) = 0;
vmiura@chromium.orgf71dc362014-01-08 21:50:50138};
139
Antoine Labour83a0aed12018-01-10 04:52:38140class GPU_GLES2_EXPORT TraceOutputter : public Outputter {
vmiura@chromium.orgf71dc362014-01-08 21:50:50141 public:
Chandan Padhi07f05c02017-09-19 02:52:53142 TraceOutputter();
143 explicit TraceOutputter(const std::string& name);
Peter BostrΓΆmdbacdc22021-09-23 22:11:46144
145 TraceOutputter(const TraceOutputter&) = delete;
146 TraceOutputter& operator=(const TraceOutputter&) = delete;
147
Chandan Padhi07f05c02017-09-19 02:52:53148 ~TraceOutputter() override;
149
dyen06ae0b22015-05-07 03:45:52150 void TraceDevice(GpuTracerSource source,
151 const std::string& category,
dyen75755fa2015-01-07 22:55:07152 const std::string& name,
avif15d60a2015-12-21 17:06:33153 int64_t start_time,
154 int64_t end_time) override;
dyen75755fa2015-01-07 22:55:07155
dyen06ae0b22015-05-07 03:45:52156 void TraceServiceBegin(GpuTracerSource source,
157 const std::string& category,
dyen81aaafd2015-01-16 21:51:11158 const std::string& name) override;
dyen75755fa2015-01-07 22:55:07159
dyen06ae0b22015-05-07 03:45:52160 void TraceServiceEnd(GpuTracerSource source,
161 const std::string& category,
dyen81aaafd2015-01-16 21:51:11162 const std::string& name) override;
vmiura@chromium.orgf71dc362014-01-08 21:50:50163
Chandan Padhi07f05c02017-09-19 02:52:53164 private:
vmiura@chromium.orgf71dc362014-01-08 21:50:50165 base::Thread named_thread_;
Chandan Padhida9202172018-06-05 19:02:20166 base::PlatformThreadId named_thread_id_ = base::kInvalidThreadId;
avif15d60a2015-12-21 17:06:33167 uint64_t local_trace_device_id_ = 0;
168 uint64_t local_trace_service_id_ = 0;
dyen151b6d692015-05-11 16:30:21169
Kalvin Lee9e2c2e82025-04-16 22:37:42170 std::array<base::stack<uint64_t>, NUM_TRACER_SOURCES> trace_service_id_stack_;
vmiura@chromium.orgf71dc362014-01-08 21:50:50171};
172
Antoine Labour83a0aed12018-01-10 04:52:38173class GPU_GLES2_EXPORT GPUTrace : public base::RefCounted<GPUTrace> {
vmiura@chromium.orgf71dc362014-01-08 21:50:50174 public:
Chandan Padhi07f05c02017-09-19 02:52:53175 GPUTrace(Outputter* outputter,
kylechar7a463842016-05-26 14:46:12176 gl::GPUTimingClient* gpu_timing_client,
dyen06ae0b22015-05-07 03:45:52177 const GpuTracerSource source,
dyencb86f2f2014-12-09 18:35:41178 const std::string& category,
dyen@chromium.orgfde50c72014-07-29 23:26:32179 const std::string& name,
dyen052dacb2015-04-11 01:09:04180 const bool tracing_service,
181 const bool tracing_device);
dyencb86f2f2014-12-09 18:35:41182
Peter BostrΓΆm1ab741d2021-10-05 22:49:41183 GPUTrace(const GPUTrace&) = delete;
184 GPUTrace& operator=(const GPUTrace&) = delete;
185
dyendbfb90d2015-03-26 02:41:46186 void Destroy(bool have_context);
187
dyen052dacb2015-04-11 01:09:04188 void Start();
189 void End();
dyen@chromium.orgfde50c72014-07-29 23:26:32190 bool IsAvailable();
dyen052dacb2015-04-11 01:09:04191 bool IsServiceTraceEnabled() const { return service_enabled_; }
192 bool IsDeviceTraceEnabled() const { return device_enabled_; }
dyen@chromium.orgfde50c72014-07-29 23:26:32193 void Process();
vmiura@chromium.orgf71dc362014-01-08 21:50:50194
195 private:
dyen@chromium.orgfde50c72014-07-29 23:26:32196 ~GPUTrace();
vmiura@chromium.orgf71dc362014-01-08 21:50:50197
198 void Output();
199
dyen@chromium.orgfde50c72014-07-29 23:26:32200 friend class base::RefCounted<GPUTrace>;
201
dyen06ae0b22015-05-07 03:45:52202 const GpuTracerSource source_ = kTraceGroupInvalid;
203 const std::string category_;
204 const std::string name_;
Keishi Hattori0e45c022021-11-27 09:25:52205 raw_ptr<Outputter> outputter_ = nullptr;
kylechar7a463842016-05-26 14:46:12206 std::unique_ptr<gl::GPUTimer> gpu_timer_;
dyen052dacb2015-04-11 01:09:04207 const bool service_enabled_ = false;
208 const bool device_enabled_ = false;
vmiura@chromium.orgf71dc362014-01-08 21:50:50209};
210
dyenb547eff62015-01-17 00:14:56211class ScopedGPUTrace {
dcastagna82922f82015-02-12 19:21:30212 public:
213 ScopedGPUTrace(GPUTracer* gpu_tracer,
214 GpuTracerSource source,
215 const std::string& category,
216 const std::string& name)
217 : gpu_tracer_(gpu_tracer), source_(source) {
218 gpu_tracer_->Begin(category, name, source_);
219 }
dyenb547eff62015-01-17 00:14:56220
dcastagna82922f82015-02-12 19:21:30221 ~ScopedGPUTrace() { gpu_tracer_->End(source_); }
dyenb547eff62015-01-17 00:14:56222
dcastagna82922f82015-02-12 19:21:30223 private:
Keishi Hattori0e45c022021-11-27 09:25:52224 raw_ptr<GPUTracer> gpu_tracer_;
dcastagna82922f82015-02-12 19:21:30225 GpuTracerSource source_;
dyenb547eff62015-01-17 00:14:56226};
227
dsinclair@chromium.orgfb97b662013-02-20 23:02:14228} // namespace gles2
229} // namespace gpu
230
231#endif // GPU_COMMAND_BUFFER_SERVICE_GPU_TRACER_H_