1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
gpu / command_buffer / service / gpu_tracer.h [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file contains the GPUTrace class.
#ifndef GPU_COMMAND_BUFFER_SERVICE_GPU_TRACER_H_
#define GPU_COMMAND_BUFFER_SERVICE_GPU_TRACER_H_
#include <stdint.h>
#include <memory>
#include <string>
#include <vector>
#include "base/containers/circular_deque.h"
#include "base/containers/stack.h"
#include "base/memory/raw_ptr.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "gpu/gpu_gles2_export.h"
namespace gl {
class GPUTimingClient;
class GPUTimer;
} // namespace gl
namespace gpu {
class DecoderContext;
namespace gles2 {
class Outputter;
class GPUTrace;
// Id used to keep trace namespaces separate
enum GpuTracerSource {
kTraceGroupInvalid = -1,
kTraceCHROMIUM,
kTraceDecoder,
kTraceDisjoint, // Used internally.
NUM_TRACER_SOURCES
};
// Marker structure for a Trace.
struct TraceMarker {
TraceMarker(const std::string& category, const std::string& name);
TraceMarker(const TraceMarker& other);
~TraceMarker();
std::string category_;
std::string name_;
scoped_refptr<GPUTrace> trace_;
};
// Traces GPU Commands.
class GPU_GLES2_EXPORT GPUTracer {
public:
explicit GPUTracer(DecoderContext* decoder, bool context_is_gl = true);
GPUTracer(const GPUTracer&) = delete;
GPUTracer& operator=(const GPUTracer&) = delete;
virtual ~GPUTracer();
void Destroy(bool have_context);
// Scheduled processing in decoder begins.
bool BeginDecoding();
// Scheduled processing in decoder ends.
bool EndDecoding();
// Begin a trace marker.
bool Begin(const std::string& category, const std::string& name,
GpuTracerSource source);
// End the last started trace marker.
bool End(GpuTracerSource source);
bool HasTracesToProcess();
void ProcessTraces();
virtual bool IsTracing();
// Retrieve the name of the current open trace.
// Returns empty string if no current open trace.
const std::string& CurrentCategory(GpuTracerSource source) const;
const std::string& CurrentName(GpuTracerSource source) const;
protected:
bool is_gpu_service_tracing_enabled() {
return *gpu_trace_srv_category_ != 0;
}
bool is_gpu_device_tracing_enabled() {
return *gpu_trace_dev_category_ != 0 && can_trace_dev_;
}
scoped_refptr<gl::GPUTimingClient> gpu_timing_client_;
raw_ptr<const unsigned char> gpu_trace_srv_category_;
raw_ptr<const unsigned char> gpu_trace_dev_category_;
// Disable gpu.device tracing if context is corrupted or not GL.
bool can_trace_dev_;
private:
bool CheckDisjointStatus();
void ClearOngoingTraces(bool have_context);
raw_ptr<Outputter> outputter_ = nullptr;
std::vector<TraceMarker> markers_[NUM_TRACER_SOURCES];
base::circular_deque<scoped_refptr<GPUTrace>> finished_traces_;
raw_ptr<DecoderContext> decoder_;
int64_t disjoint_time_ = 0;
bool gpu_executing_ = false;
bool began_device_traces_ = false;
};
class GPU_GLES2_EXPORT Outputter {
public:
virtual ~Outputter() = default;
virtual void TraceDevice(GpuTracerSource source,
const std::string& category,
const std::string& name,
int64_t start_time,
int64_t end_time) = 0;
virtual void TraceServiceBegin(GpuTracerSource source,
const std::string& category,
const std::string& name) = 0;
virtual void TraceServiceEnd(GpuTracerSource source,
const std::string& category,
const std::string& name) = 0;
};
class GPU_GLES2_EXPORT TraceOutputter : public Outputter {
public:
TraceOutputter();
explicit TraceOutputter(const std::string& name);
TraceOutputter(const TraceOutputter&) = delete;
TraceOutputter& operator=(const TraceOutputter&) = delete;
~TraceOutputter() override;
void TraceDevice(GpuTracerSource source,
const std::string& category,
const std::string& name,
int64_t start_time,
int64_t end_time) override;
void TraceServiceBegin(GpuTracerSource source,
const std::string& category,
const std::string& name) override;
void TraceServiceEnd(GpuTracerSource source,
const std::string& category,
const std::string& name) override;
private:
base::Thread named_thread_;
base::PlatformThreadId named_thread_id_ = base::kInvalidThreadId;
uint64_t local_trace_device_id_ = 0;
uint64_t local_trace_service_id_ = 0;
base::stack<uint64_t> trace_service_id_stack_[NUM_TRACER_SOURCES];
};
class GPU_GLES2_EXPORT GPUTrace : public base::RefCounted<GPUTrace> {
public:
GPUTrace(Outputter* outputter,
gl::GPUTimingClient* gpu_timing_client,
const GpuTracerSource source,
const std::string& category,
const std::string& name,
const bool tracing_service,
const bool tracing_device);
GPUTrace(const GPUTrace&) = delete;
GPUTrace& operator=(const GPUTrace&) = delete;
void Destroy(bool have_context);
void Start();
void End();
bool IsAvailable();
bool IsServiceTraceEnabled() const { return service_enabled_; }
bool IsDeviceTraceEnabled() const { return device_enabled_; }
void Process();
private:
~GPUTrace();
void Output();
friend class base::RefCounted<GPUTrace>;
const GpuTracerSource source_ = kTraceGroupInvalid;
const std::string category_;
const std::string name_;
raw_ptr<Outputter> outputter_ = nullptr;
std::unique_ptr<gl::GPUTimer> gpu_timer_;
const bool service_enabled_ = false;
const bool device_enabled_ = false;
};
class ScopedGPUTrace {
public:
ScopedGPUTrace(GPUTracer* gpu_tracer,
GpuTracerSource source,
const std::string& category,
const std::string& name)
: gpu_tracer_(gpu_tracer), source_(source) {
gpu_tracer_->Begin(category, name, source_);
}
~ScopedGPUTrace() { gpu_tracer_->End(source_); }
private:
raw_ptr<GPUTracer> gpu_tracer_;
GpuTracerSource source_;
};
} // namespace gles2
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_SERVICE_GPU_TRACER_H_