Skip to content

Commit 5ac1faf

Browse files
committed
Hook up perfetto script and frame profiling logic
1 parent d1f2007 commit 5ac1faf

1 file changed

Lines changed: 46 additions & 4 deletions

File tree

core/profiling/profiling.h

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,15 @@ void godot_cleanup_profiler();
9797
// Use the perfetto profiler.
9898

9999
#include "core/typedefs.h"
100+
#include "main/performance.h"
100101

101102
#include <perfetto.h>
102103

103104
PERFETTO_DEFINE_CATEGORIES(
104105
perfetto::Category("godot")
105-
.SetDescription("All Godot Events"), );
106+
.SetDescription("Godot Engine Events"),
107+
perfetto::Category("godot_scripting")
108+
.SetDescription("Godot Scripting Events"), );
106109

107110
// See PERFETTO_INTERNAL_SCOPED_EVENT_FINALIZER
108111
struct PerfettoGroupedEventEnder {
@@ -115,7 +118,9 @@ struct PerfettoGroupedEventEnder {
115118
}
116119
};
117120

118-
#define GodotProfileFrameMark // TODO
121+
#define GodotProfileFrameMark \
122+
perfetto::CounterTrack __frame_time_track = perfetto::CounterTrack("Frame time", "ms").set_unit_multiplier(1000); \
123+
TRACE_COUNTER("godot", __frame_time_track, Performance::get_singleton()->get_monitor(Performance::Monitor::TIME_PROCESS));
119124
#define GodotProfileZone(m_zone_name) TRACE_EVENT("godot", m_zone_name);
120125
#define GodotProfileZoneGroupedFirst(m_group_name, m_zone_name) \
121126
TRACE_EVENT_BEGIN("godot", m_zone_name); \
@@ -125,8 +130,45 @@ struct PerfettoGroupedEventEnder {
125130
__godot_perfetto_zone_##m_group_name._end_now(); \
126131
TRACE_EVENT_BEGIN("godot", m_zone_name);
127132

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)
133+
static HashSet<StringName> __tracing_system_call;
134+
135+
/**
136+
* Script tracing may cross function boundaries (tracing started in the caller script), so the logic below only triggers
137+
* a TRACE_EVENT_BEGIN for `GodotProfileZoneScript` if tracing hasn't already been initiated by
138+
* `GodotProfileZoneScriptSystemCall` in the caller.
139+
*/
140+
struct PerfettoScriptTracer {
141+
StringName name;
142+
bool is_system_call;
143+
bool tracing;
144+
145+
PerfettoScriptTracer(const StringName &p_file, const StringName &p_function, const StringName &p_name, int p_line, bool p_system_call) : name(p_name), is_system_call(p_system_call) {
146+
if (is_system_call || !__tracing_system_call.erase(name)) {
147+
TRACE_EVENT_BEGIN("godot_scripting", perfetto::DynamicString(p_name.operator String().utf8().get_data()), "source file", p_file.operator String().utf8().get_data(), "line number", p_line);
148+
tracing = true;
149+
}
150+
151+
if (is_system_call) {
152+
__tracing_system_call.insert(name);
153+
}
154+
}
155+
156+
_FORCE_INLINE_ void _end_now() {
157+
if (tracing) {
158+
TRACE_EVENT_END("godot_scripting");
159+
}
160+
}
161+
162+
_FORCE_INLINE_ ~PerfettoScriptTracer() {
163+
_end_now();
164+
if (is_system_call) {
165+
__tracing_system_call.erase(name);
166+
}
167+
}
168+
};
169+
170+
#define GodotProfileZoneScript(m_ptr, m_file, m_function, m_name, m_line) PerfettoScriptTracer __godot_perfetto_script_tracer(m_file, m_function, m_name, m_line, false);
171+
#define GodotProfileZoneScriptSystemCall(m_ptr, m_file, m_function, m_name, m_line) PerfettoScriptTracer __godot_perfetto_script_system_call_tracer(m_file, m_function, m_name, m_line, true);
130172

131173
#define GodotProfileAlloc(m_ptr, m_size)
132174
#define GodotProfileFree(m_ptr)

0 commit comments

Comments
 (0)