Skip to content

Commit 8b5cdfb

Browse files
authored
Merge pull request #7 from Ryan-000/add_tracy_module
wip
2 parents 29a6e53 + 4bd9c40 commit 8b5cdfb

File tree

11 files changed

+280
-0
lines changed

11 files changed

+280
-0
lines changed

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "modules/godot_tracy"]
2+
path = modules/godot_tracy
3+
url = https://github.com/AndreaCatania/godot_tracy.git

core/object/message_queue.cpp

+34
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,40 @@ void CallQueue::_call_function(const Callable &p_callable, const Variant *p_args
226226
Error CallQueue::flush() {
227227
LOCK_MUTEX;
228228

229+
#ifdef MODULE_GODOT_TRACY_ENABLED
230+
ZoneScoped; // Trace the entire push operation
231+
232+
// Start constructing the identifier
233+
String identifier = "Callable::";
234+
Object *obj = p_callable.get_object(); // Get the object associated with the callable
235+
236+
if (obj) {
237+
// Check if it's a standard method (not from a script)
238+
if (p_callable.is_standard()) {
239+
// Append the standard method name and class name
240+
identifier += obj->get_class() + "::" + p_callable.get_method();
241+
} else {
242+
// It's a script callable, so get the script instance
243+
ScriptInstance *script = obj->get_script_instance();
244+
if (script) {
245+
// Get the script path and append it to the identifier along with the method name
246+
identifier = "Script::" + script->get_script()->get_path() + "::" + p_callable.get_method();
247+
} else {
248+
// Fallback to using just the class name and method if no script instance is found
249+
identifier += "Custom::" + obj->get_class() + "::" + p_callable.get_method();
250+
}
251+
}
252+
} else {
253+
// No object, use just the method name
254+
identifier += p_callable.get_method();
255+
}
256+
257+
// Convert the identifier to a char array for Tracy
258+
CharString c = identifier.utf8();
259+
ZoneName(c.get_data(), c.length()); // Set the zone name with the constructed identifier
260+
#endif
261+
262+
229263
if (pages.size() == 0) {
230264
// Never allocated
231265
UNLOCK_MUTEX;

core/object/object.cpp

+36
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@
4242
#include "core/templates/local_vector.h"
4343
#include "core/variant/typed_array.h"
4444

45+
#include "modules/modules_enabled.gen.h"
46+
47+
#ifdef MODULE_GODOT_TRACY_ENABLED
48+
#include "modules/godot_tracy/profiler.h"
49+
#endif // MODULE_GODOT_TRACY_ENABLED
50+
4551
#ifdef DEBUG_ENABLED
4652

4753
struct _ObjectDebugLock {
@@ -751,6 +757,12 @@ Variant Object::callv(const StringName &p_method, const Array &p_args) {
751757
}
752758

753759
Variant Object::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
760+
#ifdef MODULE_GODOT_TRACY_ENABLED
761+
ZoneScoped;
762+
CharString c = Profiler::stringify_method(p_method, p_args, p_argcount);
763+
ZoneName(c.ptr(), c.size());
764+
#endif // MODULE_GODOT_TRACY_ENABLED
765+
754766
r_error.error = Callable::CallError::CALL_OK;
755767

756768
if (p_method == CoreStringName(free_)) {
@@ -814,6 +826,12 @@ Variant Object::callp(const StringName &p_method, const Variant **p_args, int p_
814826
}
815827

816828
Variant Object::call_const(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
829+
#ifdef MODULE_GODOT_TRACY_ENABLED
830+
ZoneScoped;
831+
CharString c = Profiler::stringify_method(p_method, p_args, p_argcount);
832+
ZoneName(c.ptr(), c.size());
833+
#endif // MODULE_GODOT_TRACY_ENABLED
834+
817835
r_error.error = Callable::CallError::CALL_OK;
818836

819837
if (p_method == CoreStringName(free_)) {
@@ -862,6 +880,24 @@ Variant Object::call_const(const StringName &p_method, const Variant **p_args, i
862880
}
863881

864882
void Object::notification(int p_notification, bool p_reversed) {
883+
#ifdef MODULE_GODOT_TRACY_ENABLED
884+
ZoneScoped; // Start a Tracy zone to track the entire notification process
885+
String identifier = "Notification::" + String::num(p_notification); // Start building the identifier
886+
887+
if (script_instance) {
888+
// If it's a script-based notification, include the script path and notification number
889+
identifier = "Script::" + script_instance->get_script()->get_path() + "::Notification::" + String::num(p_notification);
890+
} else {
891+
// For standard objects, include the class name
892+
identifier = "Class::" + String(get_class()) + "::Notification::" + String::num(p_notification);
893+
}
894+
895+
// Set the identifier for the Tracy zone
896+
CharString c = identifier.utf8();
897+
ZoneName(c.get_data(), c.length());
898+
#endif
899+
900+
865901
if (p_reversed) {
866902
if (script_instance) {
867903
script_instance->notification(p_notification, p_reversed);

core/os/memory.cpp

+31
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <stdio.h>
3737
#include <stdlib.h>
3838

39+
3940
void *operator new(size_t p_size, const char *p_description) {
4041
return Memory::alloc_static(p_size, false);
4142
}
@@ -73,6 +74,9 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
7374
#endif
7475

7576
void *mem = malloc(p_bytes + (prepad ? DATA_OFFSET : 0));
77+
#if MODULE_GODOT_TRACY_ENABLED
78+
TracyAlloc(mem, p_bytes);
79+
#endif
7680

7781
ERR_FAIL_NULL_V(mem, nullptr);
7882

@@ -121,9 +125,16 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) {
121125
#endif
122126

123127
if (p_bytes == 0) {
128+
#if MODULE_GODOT_TRACY_ENABLED
129+
TracyFree(mem);
130+
#endif
124131
free(mem);
125132
return nullptr;
126133
} else {
134+
#if MODULE_GODOT_TRACY_ENABLED
135+
TracyFree(mem + DATA_OFFSET); // Free old memory
136+
#endif
137+
127138
*s = p_bytes;
128139

129140
mem = (uint8_t *)realloc(mem, p_bytes + DATA_OFFSET);
@@ -133,13 +144,25 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) {
133144

134145
*s = p_bytes;
135146

147+
#if MODULE_GODOT_TRACY_ENABLED
148+
TracyAlloc(mem + DATA_OFFSET, p_bytes); // Allocate new memory
149+
#endif
150+
136151
return mem + DATA_OFFSET;
137152
}
138153
} else {
154+
#if MODULE_GODOT_TRACY_ENABLED
155+
TracyFree(mem); // Free old memory
156+
#endif
157+
139158
mem = (uint8_t *)realloc(mem, p_bytes);
140159

141160
ERR_FAIL_COND_V(mem == nullptr && p_bytes > 0, nullptr);
142161

162+
#if MODULE_GODOT_TRACY_ENABLED
163+
TracyAlloc(mem, p_bytes); // Allocate new memory
164+
#endif
165+
143166
return mem;
144167
}
145168
}
@@ -165,8 +188,16 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) {
165188
mem_usage.sub(*s);
166189
#endif
167190

191+
#if MODULE_GODOT_TRACY_ENABLED
192+
TracyFree(mem);
193+
#endif
168194
free(mem);
169195
} else {
196+
197+
#if MODULE_GODOT_TRACY_ENABLED
198+
TracyFree(mem);
199+
#endif
200+
170201
free(mem);
171202
}
172203
}

core/variant/variant_call.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@
3939
#include "core/templates/local_vector.h"
4040
#include "core/templates/oa_hash_map.h"
4141

42+
#include "modules/modules_enabled.gen.h"
43+
44+
#ifdef MODULE_GODOT_TRACY_ENABLED
45+
#include "modules/godot_tracy/profiler.h"
46+
#endif // MODULE_GODOT_TRACY_ENABLED
47+
4248
typedef void (*VariantFunc)(Variant &r_ret, Variant &p_self, const Variant **p_args);
4349
typedef void (*VariantConstructFunc)(Variant &r_ret, const Variant **p_args);
4450

@@ -1194,6 +1200,12 @@ static void register_builtin_method(const Vector<String> &p_argnames, const Vect
11941200
}
11951201

11961202
void Variant::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
1203+
#ifdef MODULE_GODOT_TRACY_ENABLED
1204+
ZoneScoped;
1205+
CharString c = Profiler::stringify_method(p_method, p_args, p_argcount);
1206+
ZoneName(c.ptr(), c.size());
1207+
#endif // MODULE_GODOT_TRACY_ENABLED
1208+
11971209
if (type == Variant::OBJECT) {
11981210
//call object
11991211
Object *obj = _get_obj().obj;

main/main.cpp

+46
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,14 @@
131131
#endif // TOOLS_ENABLED && !GDSCRIPT_NO_LSP
132132
#endif // MODULE_GDSCRIPT_ENABLED
133133

134+
#ifdef MODULE_GODOT_TRACY_ENABLED
135+
#include "modules/godot_tracy/profiler.h"
136+
#else
137+
// Dummy defines to allow compiling without tracy.
138+
#define ZoneScoped
139+
#define ZoneScopedN(a)
140+
#endif // MODULE_GODOT_TRACY_ENABLED
141+
134142
/* Static members */
135143

136144
// Singletons
@@ -3999,6 +4007,7 @@ static uint64_t navigation_process_max = 0;
39994007
// will terminate the program. In case of failure, the OS exit code needs
40004008
// to be set explicitly here (defaults to EXIT_SUCCESS).
40014009
bool Main::iteration() {
4010+
ZoneScoped;
40024011
iterating++;
40034012

40044013
const uint64_t ticks = OS::get_singleton()->get_ticks_usec();
@@ -4044,6 +4053,8 @@ bool Main::iteration() {
40444053
NavigationServer2D::get_singleton()->sync();
40454054
NavigationServer3D::get_singleton()->sync();
40464055

4056+
{
4057+
ZoneScopedN("PHYSICS LOOP");
40474058
for (int iters = 0; iters < advance.physics_steps; ++iters) {
40484059
if (Input::get_singleton()->is_agile_input_event_flushing()) {
40494060
Input::get_singleton()->flush_buffered_events();
@@ -4055,17 +4066,26 @@ bool Main::iteration() {
40554066
uint64_t physics_begin = OS::get_singleton()->get_ticks_usec();
40564067

40574068
#ifndef _3D_DISABLED
4069+
{
4070+
ZoneScopedN("Godot physics 3D - sync");
40584071
PhysicsServer3D::get_singleton()->sync();
40594072
PhysicsServer3D::get_singleton()->flush_queries();
4073+
}
40604074
#endif // _3D_DISABLED
40614075

40624076
// Prepare the fixed timestep interpolated nodes BEFORE they are updated
40634077
// by the physics server, otherwise the current and previous transforms
40644078
// may be the same, and no interpolation takes place.
40654079
OS::get_singleton()->get_main_loop()->iteration_prepare();
40664080

4081+
{
4082+
ZoneScopedN("Godot physics 2D - sync");
40674083
PhysicsServer2D::get_singleton()->sync();
40684084
PhysicsServer2D::get_singleton()->flush_queries();
4085+
}
4086+
4087+
{
4088+
ZoneScopedN("physics_process");
40694089

40704090
if (OS::get_singleton()->get_main_loop()->physics_process(physics_step * time_scale)) {
40714091
#ifndef _3D_DISABLED
@@ -4076,23 +4096,33 @@ bool Main::iteration() {
40764096
exit = true;
40774097
break;
40784098
}
4099+
}
40794100

40804101
uint64_t navigation_begin = OS::get_singleton()->get_ticks_usec();
40814102

4103+
{
4104+
ZoneScopedN("Navigation process");
40824105
NavigationServer3D::get_singleton()->process(physics_step * time_scale);
4106+
}
40834107

40844108
navigation_process_ticks = MAX(navigation_process_ticks, OS::get_singleton()->get_ticks_usec() - navigation_begin); // keep the largest one for reference
40854109
navigation_process_max = MAX(OS::get_singleton()->get_ticks_usec() - navigation_begin, navigation_process_max);
40864110

40874111
message_queue->flush();
40884112

40894113
#ifndef _3D_DISABLED
4114+
{
4115+
ZoneScopedN("Godot physics 3D - step");
40904116
PhysicsServer3D::get_singleton()->end_sync();
40914117
PhysicsServer3D::get_singleton()->step(physics_step * time_scale);
4118+
}
40924119
#endif // _3D_DISABLED
40934120

4121+
{
4122+
ZoneScopedN("Godot physics 2D - step");
40944123
PhysicsServer2D::get_singleton()->end_sync();
40954124
PhysicsServer2D::get_singleton()->step(physics_step * time_scale);
4125+
}
40964126

40974127
message_queue->flush();
40984128

@@ -4101,18 +4131,24 @@ bool Main::iteration() {
41014131

41024132
Engine::get_singleton()->_in_physics = false;
41034133
}
4134+
}
41044135

41054136
if (Input::get_singleton()->is_agile_input_event_flushing()) {
41064137
Input::get_singleton()->flush_buffered_events();
41074138
}
41084139

41094140
uint64_t process_begin = OS::get_singleton()->get_ticks_usec();
41104141

4142+
{
4143+
ZoneScopedN("Main process");
41114144
if (OS::get_singleton()->get_main_loop()->process(process_step * time_scale)) {
41124145
exit = true;
41134146
}
4147+
}
41144148
message_queue->flush();
41154149

4150+
{
4151+
ZoneScopedN("Main::iteration - Draw");
41164152
RenderingServer::get_singleton()->sync(); //sync if still drawing from previous frames.
41174153

41184154
if ((DisplayServer::get_singleton()->can_any_window_draw() || DisplayServer::get_singleton()->has_additional_outputs()) &&
@@ -4128,16 +4164,23 @@ bool Main::iteration() {
41284164
force_redraw_requested = false;
41294165
}
41304166
}
4167+
}
41314168

41324169
process_ticks = OS::get_singleton()->get_ticks_usec() - process_begin;
41334170
process_max = MAX(process_ticks, process_max);
41344171
uint64_t frame_time = OS::get_singleton()->get_ticks_usec() - ticks;
41354172

4173+
{
4174+
ZoneScopedN("Languages update");
41364175
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
41374176
ScriptServer::get_language(i)->frame();
41384177
}
4178+
}
41394179

4180+
{
4181+
ZoneScopedN("Audio update");
41404182
AudioServer::get_singleton()->update();
4183+
}
41414184

41424185
if (EngineDebugger::is_active()) {
41434186
EngineDebugger::get_singleton()->iteration(frame_time, process_ticks, physics_process_ticks, physics_step);
@@ -4198,7 +4241,10 @@ bool Main::iteration() {
41984241
return exit;
41994242
}
42004243

4244+
{
4245+
ZoneScopedN("Frame delay");
42014246
OS::get_singleton()->add_frame_delay(DisplayServer::get_singleton()->window_can_draw());
4247+
}
42024248

42034249
#ifdef TOOLS_ENABLED
42044250
if (auto_build_solutions) {

modules/gdscript/gdscript.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@
6161

6262
#include <stdint.h>
6363

64+
#include "modules/modules_enabled.gen.h"
65+
66+
#ifdef MODULE_GODOT_TRACY_ENABLED
67+
#include "modules/godot_tracy/profiler.h"
68+
#endif // MODULE_GODOT_TRACY_ENABLED
69+
6470
///////////////////////////
6571

6672
GDScriptNativeClass::GDScriptNativeClass(const StringName &p_name) {
@@ -2020,6 +2026,19 @@ void GDScriptInstance::_call_implicit_ready_recursively(GDScript *p_script) {
20202026
}
20212027

20222028
Variant GDScriptInstance::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
2029+
#ifdef MODULE_GODOT_TRACY_ENABLED
2030+
ZoneScoped;
2031+
2032+
// get the script path.
2033+
String identifier = script->path;
2034+
// get the file name.
2035+
// identifier = identifier.get_file().get_basename();
2036+
identifier += "::" + p_method;
2037+
2038+
CharString c = Profiler::stringify_method(identifier, p_args, p_argcount);
2039+
ZoneName(c.ptr(), c.size());
2040+
#endif // MODULE_GODOT_TRACY_ENABLED
2041+
20232042
GDScript *sptr = script.ptr();
20242043
if (unlikely(p_method == SceneStringName(_ready))) {
20252044
// Call implicit ready first, including for the super classes recursively.

0 commit comments

Comments
 (0)