Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/core/profiling/profiling.h
14735 views
1
/**************************************************************************/
2
/* profiling.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "profiling.gen.h"
34
35
// This header provides profiling primitives (implemented as macros) for various backends.
36
// See the "No profiling" branch at the bottom for a short description of the functions.
37
38
// To configure / use the profiler, use the --profiler_path and other --profiler_* arguments
39
// when compiling Godot. You can also find details in the SCSub file (in this folder).
40
41
// Note: It is highly recommended to avoid including this header in other header files.
42
// Prefer including it in .cpp files only. The reason is that we want to keep
43
// the recompile cost of changing the profiler as low as possible.
44
45
#if defined(GODOT_USE_TRACY)
46
// Use the tracy profiler.
47
48
#include "core/string/string_name.h"
49
50
#define TRACY_ENABLE
51
52
#include <tracy/Tracy.hpp>
53
54
// Hijacking the tracy namespace so we can use their macros.
55
namespace tracy {
56
const SourceLocationData *intern_source_location(const void *p_function_ptr, const StringName &p_file, const StringName &p_function, const StringName &p_name, uint32_t p_line, bool p_is_script);
57
} //namespace tracy
58
59
// Define tracing macros.
60
#define GodotProfileFrameMark FrameMark
61
#define GodotProfileZone(m_zone_name) ZoneNamedN(GD_UNIQUE_NAME(__godot_tracy_szone_), m_zone_name, true)
62
#define GodotProfileZoneGroupedFirst(m_group_name, m_zone_name) ZoneNamedN(__godot_tracy_zone_##m_group_name, m_zone_name, true)
63
#define GodotProfileZoneGroupedEndEarly(m_group_name, m_zone_name) __godot_tracy_zone_##m_group_name.~ScopedZone();
64
#ifndef TRACY_CALLSTACK
65
#define GodotProfileZoneGrouped(m_group_name, m_zone_name) \
66
GodotProfileZoneGroupedEndEarly(m_group_name, m_zone_name); \
67
static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location, TracyLine){ m_zone_name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; \
68
new (&__godot_tracy_zone_##m_group_name) tracy::ScopedZone(&TracyConcat(__tracy_source_location, TracyLine), true)
69
#else
70
#define GodotProfileZoneGrouped(m_group_name, m_zone_name) \
71
GodotProfileZoneGroupedEndEarly(m_group_name, m_zone_name); \
72
static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location, TracyLine){ m_zone_name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; \
73
new (&__godot_tracy_zone_##m_group_name) tracy::ScopedZone(&TracyConcat(__tracy_source_location, TracyLine), TRACY_CALLSTACK, true)
74
#endif
75
76
#define GodotProfileZoneScript(m_ptr, m_file, m_function, m_name, m_line) \
77
tracy::ScopedZone __godot_tracy_script(tracy::intern_source_location(m_ptr, m_file, m_function, m_name, m_line, true))
78
#define GodotProfileZoneScriptSystemCall(m_ptr, m_file, m_function, m_name, m_line) \
79
tracy::ScopedZone __godot_tracy_zone_system_call(tracy::intern_source_location(m_ptr, m_file, m_function, m_name, m_line, false))
80
81
// Memory allocation
82
#ifdef GODOT_PROFILER_TRACK_MEMORY
83
#define GodotProfileAlloc(m_ptr, m_size) \
84
GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Wmaybe-uninitialized") \
85
TracyAlloc(m_ptr, m_size); \
86
GODOT_GCC_WARNING_POP
87
#define GodotProfileFree(m_ptr) TracyFree(m_ptr)
88
#else
89
#define GodotProfileAlloc(m_ptr, m_size)
90
#define GodotProfileFree(m_ptr)
91
#endif
92
93
void godot_init_profiler();
94
void godot_cleanup_profiler();
95
96
#elif defined(GODOT_USE_PERFETTO)
97
// Use the perfetto profiler.
98
99
#include <perfetto.h>
100
101
#include "core/typedefs.h"
102
103
PERFETTO_DEFINE_CATEGORIES(
104
perfetto::Category("godot")
105
.SetDescription("All Godot Events"), );
106
107
// See PERFETTO_INTERNAL_SCOPED_EVENT_FINALIZER
108
struct PerfettoGroupedEventEnder {
109
_FORCE_INLINE_ void _end_now() {
110
TRACE_EVENT_END("godot");
111
}
112
113
_FORCE_INLINE_ ~PerfettoGroupedEventEnder() {
114
_end_now();
115
}
116
};
117
118
#define GodotProfileFrameMark // TODO
119
#define GodotProfileZone(m_zone_name) TRACE_EVENT("godot", m_zone_name);
120
#define GodotProfileZoneGroupedFirst(m_group_name, m_zone_name) \
121
TRACE_EVENT_BEGIN("godot", m_zone_name); \
122
PerfettoGroupedEventEnder __godot_perfetto_zone_##m_group_name
123
#define GodotProfileZoneGroupedEndEarly(m_group_name, m_zone_name) __godot_perfetto_zone_##m_group_name.~PerfettoGroupedEventEnder()
124
#define GodotProfileZoneGrouped(m_group_name, m_zone_name) \
125
__godot_perfetto_zone_##m_group_name._end_now(); \
126
TRACE_EVENT_BEGIN("godot", m_zone_name);
127
128
#define GodotProfileZoneScript(m_ptr, m_file, m_function, m_name, m_line)
129
#define GodotProfileZoneScriptSystemCall(m_ptr, m_file, m_function, m_name, m_line)
130
131
#define GodotProfileAlloc(m_ptr, m_size)
132
#define GodotProfileFree(m_ptr)
133
134
void godot_init_profiler();
135
void godot_cleanup_profiler();
136
137
#elif defined(GODOT_USE_INSTRUMENTS)
138
139
#include <os/log.h>
140
#include <os/signpost.h>
141
142
namespace apple::instruments {
143
144
extern os_log_t LOG;
145
extern os_log_t LOG_TRACING;
146
147
typedef void (*DeferFunc)();
148
149
class Defer {
150
public:
151
explicit Defer(DeferFunc p_fn) :
152
_fn(p_fn) {}
153
~Defer() {
154
_fn();
155
}
156
157
private:
158
DeferFunc _fn;
159
};
160
161
} // namespace apple::instruments
162
163
#define GodotProfileFrameMark \
164
os_signpost_event_emit(apple::instruments::LOG, OS_SIGNPOST_ID_EXCLUSIVE, "Frame");
165
166
#define GodotProfileZoneGroupedFirst(m_group_name, m_zone_name) \
167
os_signpost_interval_begin(apple::instruments::LOG_TRACING, OS_SIGNPOST_ID_EXCLUSIVE, m_zone_name); \
168
apple::instruments::DeferFunc _GD_VARNAME_CONCAT_(defer__fn, _, m_group_name) = []() { \
169
os_signpost_interval_end(apple::instruments::LOG_TRACING, OS_SIGNPOST_ID_EXCLUSIVE, m_zone_name); \
170
}; \
171
apple::instruments::Defer _GD_VARNAME_CONCAT_(__instruments_defer_zone_end__, _, m_group_name)(_GD_VARNAME_CONCAT_(defer__fn, _, m_group_name));
172
173
#define GodotProfileZoneGroupedEndEarly(m_group_name, m_zone_name) \
174
_GD_VARNAME_CONCAT_(__instruments_defer_zone_end__, _, m_group_name).~Defer();
175
176
#define GodotProfileZoneGrouped(m_group_name, m_zone_name) \
177
GodotProfileZoneGroupedEndEarly(m_group_name, m_zone_name); \
178
os_signpost_interval_begin(apple::instruments::LOG_TRACING, OS_SIGNPOST_ID_EXCLUSIVE, m_zone_name); \
179
_GD_VARNAME_CONCAT_(defer__fn, _, m_group_name) = []() { \
180
os_signpost_interval_end(apple::instruments::LOG_TRACING, OS_SIGNPOST_ID_EXCLUSIVE, m_zone_name); \
181
}; \
182
new (&_GD_VARNAME_CONCAT_(__instruments_defer_zone_end__, _, m_group_name)) apple::instruments::Defer(_GD_VARNAME_CONCAT_(defer__fn, _, m_group_name));
183
184
#define GodotProfileZone(m_zone_name) \
185
GodotProfileZoneGroupedFirst(__COUNTER__, m_zone_name)
186
187
#define GodotProfileZoneScript(m_ptr, m_file, m_function, m_name, m_line)
188
#define GodotProfileZoneScriptSystemCall(m_ptr, m_file, m_function, m_name, m_line)
189
190
// Instruments has its own memory profiling, so these are no-ops.
191
#define GodotProfileAlloc(m_ptr, m_size)
192
#define GodotProfileFree(m_ptr)
193
194
void godot_init_profiler();
195
void godot_cleanup_profiler();
196
197
#else
198
// No profiling; all macros are stubs.
199
200
void godot_init_profiler();
201
void godot_cleanup_profiler();
202
203
// Tell the profiling backend that a new frame has started.
204
#define GodotProfileFrameMark
205
// Defines a profile zone from here to the end of the scope.
206
#define GodotProfileZone(m_zone_name)
207
// Defines a profile zone group. The first profile zone starts immediately,
208
// and ends either when the next zone starts, or when the scope ends.
209
#define GodotProfileZoneGroupedFirst(m_group_name, m_zone_name)
210
// End the profile zone group's current profile zone now.
211
#define GodotProfileZoneGroupedEndEarly(m_group_name, m_zone_name)
212
// Replace the profile zone group's current profile zone.
213
// The new zone ends either when the next zone starts, or when the scope ends.
214
#define GodotProfileZoneGrouped(m_group_name, m_zone_name)
215
// Tell the profiling backend that an allocation happened, with its location and size.
216
#define GodotProfileAlloc(m_ptr, m_size)
217
// Tell the profiling backend that an allocation was freed.
218
// There must be a one to one correspondence of GodotProfileAlloc and GodotProfileFree calls.
219
#define GodotProfileFree(m_ptr)
220
221
// Define a zone for a script call (dynamic source location).
222
// m_ptr is a pointer to the function instance, which will be used for the lookup.
223
// m_file, m_function, m_name are StringNames, and m_line is uint32_t
224
#define GodotProfileZoneScript(m_ptr, m_file, m_function, m_name, m_line)
225
// Define a zone for a system call from a script (dynamic source location).
226
#define GodotProfileZoneScriptSystemCall(m_ptr, m_file, m_function, m_name, m_line)
227
228
#endif
229
230