Skip to content

Commit f15ea5f

Browse files
committed
Add some important profiling hooks.
1 parent 9867875 commit f15ea5f

File tree

13 files changed

+110
-10
lines changed

13 files changed

+110
-10
lines changed

core/profiling.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,13 @@
3030

3131
#include "profiling.h"
3232

33-
#ifdef GODOT_USE_PERFETTO
33+
#if defined(GODOT_USE_TRACY)
34+
void godot_init_profiler() {
35+
// Send our first event to tracy; otherwise it doesn't start collecting data.
36+
// FrameMark is kind of fitting because it communicates "this is where we started tracing".
37+
FrameMark;
38+
}
39+
#elif defined(GODOT_USE_PERFETTO)
3440
PERFETTO_TRACK_EVENT_STATIC_STORAGE();
3541

3642
void godot_init_profiler() {
@@ -41,5 +47,8 @@ void godot_init_profiler() {
4147
perfetto::Tracing::Initialize(args);
4248
perfetto::TrackEvent::Register();
4349
}
44-
50+
#else
51+
void godot_init_profiler() {
52+
// Stub
53+
}
4554
#endif

core/profiling.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,7 @@
5757
static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location, TracyLine){ m_zone_name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; \
5858
new (&__godot_tracy_zone_##m_group_name) tracy::ScopedZone(&TracyConcat(__tracy_source_location, TracyLine), TRACY_CALLSTACK, true)
5959

60-
static void godot_init_profiler() {
61-
// Send our first event to tracy; otherwise it doesn't start collecting data.
62-
// FrameMark is kind of fitting because it communicates "this is where we started tracing".
63-
FrameMark;
64-
}
60+
void godot_init_profiler();
6561

6662
#elif defined(GODOT_USE_PERFETTO)
6763
// Use the perfetto profiler.
@@ -98,8 +94,7 @@ void godot_init_profiler();
9894
#else
9995
// No profiling; all macros are stubs.
10096

101-
static void godot_init_profiler() {
102-
}
97+
void godot_init_profiler();
10398

10499
#define GodotProfileFrameMark
105100
#define GodotProfileZone(m_zone_name)

main/main.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#include "core/object/script_language.h"
5151
#include "core/os/os.h"
5252
#include "core/os/time.h"
53+
#include "core/profiling.h"
5354
#include "core/register_core_types.h"
5455
#include "core/string/translation_server.h"
5556
#include "core/version.h"
@@ -957,6 +958,7 @@ int Main::test_entrypoint(int argc, char *argv[], bool &tests_need_run) {
957958
*/
958959

959960
Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_phase) {
961+
GodotProfileZone("setup");
960962
Thread::make_main_thread();
961963
set_current_thread_safe_for_nodes(true);
962964

@@ -2882,6 +2884,7 @@ Error _parse_resource_dummy(void *p_data, VariantParser::Stream *p_stream, Ref<R
28822884
}
28832885

28842886
Error Main::setup2(bool p_show_boot_logo) {
2887+
GodotProfileZone("setup2");
28852888
OS::get_singleton()->benchmark_begin_measure("Startup", "Main::Setup2");
28862889

28872890
Thread::make_main_thread(); // Make whatever thread call this the main thread.
@@ -3693,6 +3696,7 @@ Error Main::setup2(bool p_show_boot_logo) {
36933696
}
36943697

36953698
void Main::setup_boot_logo() {
3699+
GodotProfileZone("setup_boot_logo");
36963700
MAIN_PRINT("Main: Load Boot Image");
36973701

36983702
#if !defined(TOOLS_ENABLED) && defined(WEB_ENABLED)
@@ -3783,6 +3787,7 @@ static MainTimerSync main_timer_sync;
37833787
// and should move on to `OS::run`, and EXIT_FAILURE otherwise for
37843788
// an early exit with that error code.
37853789
int Main::start() {
3790+
GodotProfileZone("start");
37863791
OS::get_singleton()->benchmark_begin_measure("Startup", "Main::Start");
37873792

37883793
ERR_FAIL_COND_V(!_start_success, false);
@@ -4601,6 +4606,8 @@ static uint64_t navigation_process_max = 0;
46014606
// will terminate the program. In case of failure, the OS exit code needs
46024607
// to be set explicitly here (defaults to EXIT_SUCCESS).
46034608
bool Main::iteration() {
4609+
GodotProfileZone("Main::iteration");
4610+
GodotProfileZoneGroupedFirst(_profile_zone, "prepare");
46044611
iterating++;
46054612

46064613
const uint64_t ticks = OS::get_singleton()->get_ticks_usec();
@@ -4646,6 +4653,8 @@ bool Main::iteration() {
46464653
#endif // XR_DISABLED
46474654

46484655
for (int iters = 0; iters < advance.physics_steps; ++iters) {
4656+
GodotProfileZone("Physics Step");
4657+
GodotProfileZoneGroupedFirst(_physics_zone, "setup");
46494658
if (Input::get_singleton()->is_agile_input_event_flushing()) {
46504659
Input::get_singleton()->flush_buffered_events();
46514660
}
@@ -4658,18 +4667,22 @@ bool Main::iteration() {
46584667
// Prepare the fixed timestep interpolated nodes BEFORE they are updated
46594668
// by the physics server, otherwise the current and previous transforms
46604669
// may be the same, and no interpolation takes place.
4670+
GodotProfileZoneGrouped(_physics_zone, "main loop iteration prepare");
46614671
OS::get_singleton()->get_main_loop()->iteration_prepare();
46624672

46634673
#ifndef PHYSICS_3D_DISABLED
4674+
GodotProfileZoneGrouped(_physics_zone, "PhysicsServer3D::sync");
46644675
PhysicsServer3D::get_singleton()->sync();
46654676
PhysicsServer3D::get_singleton()->flush_queries();
46664677
#endif // PHYSICS_3D_DISABLED
46674678

46684679
#ifndef PHYSICS_2D_DISABLED
4680+
GodotProfileZoneGrouped(_physics_zone, "PhysicsServer2D::sync");
46694681
PhysicsServer2D::get_singleton()->sync();
46704682
PhysicsServer2D::get_singleton()->flush_queries();
46714683
#endif // PHYSICS_2D_DISABLED
46724684

4685+
GodotProfileZoneGrouped(_physics_zone, "physics_process");
46734686
if (OS::get_singleton()->get_main_loop()->physics_process(physics_step * time_scale)) {
46744687
#ifndef PHYSICS_3D_DISABLED
46754688
PhysicsServer3D::get_singleton()->end_sync();
@@ -4687,9 +4700,11 @@ bool Main::iteration() {
46874700
uint64_t navigation_begin = OS::get_singleton()->get_ticks_usec();
46884701

46894702
#ifndef NAVIGATION_2D_DISABLED
4703+
GodotProfileZoneGrouped(_profile_zone, "NavigationServer2D::physics_process");
46904704
NavigationServer2D::get_singleton()->physics_process(physics_step * time_scale);
46914705
#endif // NAVIGATION_2D_DISABLED
46924706
#ifndef NAVIGATION_3D_DISABLED
4707+
GodotProfileZoneGrouped(_profile_zone, "NavigationServer3D::physics_process");
46934708
NavigationServer3D::get_singleton()->physics_process(physics_step * time_scale);
46944709
#endif // NAVIGATION_3D_DISABLED
46954710

@@ -4700,17 +4715,20 @@ bool Main::iteration() {
47004715
#endif // !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED)
47014716

47024717
#ifndef PHYSICS_3D_DISABLED
4718+
GodotProfileZoneGrouped(_profile_zone, "3D physics");
47034719
PhysicsServer3D::get_singleton()->end_sync();
47044720
PhysicsServer3D::get_singleton()->step(physics_step * time_scale);
47054721
#endif // PHYSICS_3D_DISABLED
47064722

47074723
#ifndef PHYSICS_2D_DISABLED
4724+
GodotProfileZoneGrouped(_profile_zone, "2D physics");
47084725
PhysicsServer2D::get_singleton()->end_sync();
47094726
PhysicsServer2D::get_singleton()->step(physics_step * time_scale);
47104727
#endif // PHYSICS_2D_DISABLED
47114728

47124729
message_queue->flush();
47134730

4731+
GodotProfileZoneGrouped(_profile_zone, "main loop iteration end");
47144732
OS::get_singleton()->get_main_loop()->iteration_end();
47154733

47164734
physics_process_ticks = MAX(physics_process_ticks, OS::get_singleton()->get_ticks_usec() - physics_begin); // keep the largest one for reference
@@ -4725,20 +4743,25 @@ bool Main::iteration() {
47254743

47264744
uint64_t process_begin = OS::get_singleton()->get_ticks_usec();
47274745

4746+
GodotProfileZoneGrouped(_profile_zone, "process");
47284747
if (OS::get_singleton()->get_main_loop()->process(process_step * time_scale)) {
47294748
exit = true;
47304749
}
47314750
message_queue->flush();
47324751

47334752
#ifndef NAVIGATION_2D_DISABLED
4753+
GodotProfileZoneGrouped(_profile_zone, "process 2D navigation");
47344754
NavigationServer2D::get_singleton()->process(process_step * time_scale);
47354755
#endif // NAVIGATION_2D_DISABLED
47364756
#ifndef NAVIGATION_3D_DISABLED
4757+
GodotProfileZoneGrouped(_profile_zone, "process 3D navigation");
47374758
NavigationServer3D::get_singleton()->process(process_step * time_scale);
47384759
#endif // NAVIGATION_3D_DISABLED
47394760

4761+
GodotProfileZoneGrouped(_profile_zone, "RenderingServer::sync");
47404762
RenderingServer::get_singleton()->sync(); //sync if still drawing from previous frames.
47414763

4764+
GodotProfileZoneGrouped(_profile_zone, "RenderingServer::draw");
47424765
const bool has_pending_resources_for_processing = RD::get_singleton() && RD::get_singleton()->has_pending_resources_for_processing();
47434766
bool wants_present = (DisplayServer::get_singleton()->can_any_window_draw() ||
47444767
DisplayServer::get_singleton()->has_additional_outputs()) &&
@@ -4762,10 +4785,12 @@ bool Main::iteration() {
47624785
process_max = MAX(process_ticks, process_max);
47634786
uint64_t frame_time = OS::get_singleton()->get_ticks_usec() - ticks;
47644787

4788+
GodotProfileZoneGrouped(_profile_zone, "ScriptServer::frame");
47654789
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
47664790
ScriptServer::get_language(i)->frame();
47674791
}
47684792

4793+
GodotProfileZoneGrouped(_profile_zone, "AudioServer::update");
47694794
AudioServer::get_singleton()->update();
47704795

47714796
if (EngineDebugger::is_active()) {
@@ -4804,6 +4829,7 @@ bool Main::iteration() {
48044829
iterating--;
48054830

48064831
if (movie_writer) {
4832+
GodotProfileZoneGrouped(_profile_zone, "movie_writer->add_frame");
48074833
movie_writer->add_frame();
48084834
}
48094835

@@ -4831,6 +4857,7 @@ bool Main::iteration() {
48314857
bool skip_delay = scene_tree && scene_tree->is_accessibility_enabled();
48324858

48334859
if (!skip_delay) {
4860+
GodotProfileZoneGrouped(_profile_zone, "OS::add_frame_delay");
48344861
OS::get_singleton()->add_frame_delay(DisplayServer::get_singleton()->window_can_draw());
48354862
}
48364863

@@ -4871,6 +4898,7 @@ void Main::force_redraw() {
48714898
* The order matters as some of those steps are linked with each other.
48724899
*/
48734900
void Main::cleanup(bool p_force) {
4901+
GodotProfileZone("cleanup");
48744902
OS::get_singleton()->benchmark_begin_measure("Shutdown", "Main::Cleanup");
48754903
if (!p_force) {
48764904
ERR_FAIL_COND(!_start_success);

platform/android/os_android.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "core/config/project_settings.h"
4242
#include "core/extension/gdextension_manager.h"
4343
#include "core/io/xml_parser.h"
44+
#include "core/profiling.h"
4445
#include "drivers/unix/dir_access_unix.h"
4546
#include "drivers/unix/file_access_unix.h"
4647
#ifdef TOOLS_ENABLED
@@ -347,6 +348,8 @@ void OS_Android::main_loop_begin() {
347348
}
348349

349350
bool OS_Android::main_loop_iterate(bool *r_should_swap_buffers) {
351+
GodotProfileFrameMark;
352+
GodotProfileZone("OS_Android::main_loop_iterate");
350353
if (!main_loop) {
351354
return false;
352355
}

platform/ios/os_ios.mm

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "core/io/dir_access.h"
4343
#include "core/io/file_access.h"
4444
#include "core/io/file_access_pack.h"
45+
#include "core/profiling.h"
4546
#include "drivers/unix/syslog_logger.h"
4647
#include "main/main.h"
4748

@@ -203,6 +204,8 @@ Rect2 fit_keep_aspect_covered(const Vector2 &p_container, const Vector2 &p_rect)
203204
}
204205

205206
bool OS_IOS::iterate() {
207+
GodotProfileFrameMark;
208+
GodotProfileZone("OS_IOS::iterate");
206209
if (!main_loop) {
207210
return true;
208211
}

platform/linuxbsd/os_linuxbsd.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
#include "core/io/certs_compressed.gen.h"
3434
#include "core/io/dir_access.h"
35+
#include "core/profiling.h"
3536
#include "main/main.h"
3637
#include "servers/display_server.h"
3738
#include "servers/rendering_server.h"
@@ -960,6 +961,8 @@ String OS_LinuxBSD::get_system_dir(SystemDir p_dir, bool p_shared_storage) const
960961
}
961962

962963
void OS_LinuxBSD::run() {
964+
GodotProfileFrameMark;
965+
GodotProfileZone("OS_LinuxBSD::run");
963966
if (!main_loop) {
964967
return;
965968
}

platform/macos/os_macos.mm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#import "macos_terminal_logger.h"
3838

3939
#include "core/crypto/crypto_core.h"
40+
#include "core/profiling.h"
4041
#include "core/version_generated.gen.h"
4142
#include "main/main.h"
4243

@@ -51,6 +52,9 @@
5152

5253
@autoreleasepool {
5354
@try {
55+
GodotProfileFrameMark;
56+
GodotProfileZone("OS_MacOS::pre_wait_observer_cb");
57+
5458
// Get rid of pending events.
5559
DisplayServer *ds = DisplayServer::get_singleton();
5660
DisplayServerMacOS *ds_mac = Object::cast_to<DisplayServerMacOS>(ds);

platform/web/os_web.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
#include "core/config/project_settings.h"
4040
#include "core/debugger/engine_debugger.h"
41+
#include "core/profiling.h"
4142
#include "drivers/unix/dir_access_unix.h"
4243
#include "drivers/unix/file_access_unix.h"
4344
#include "main/main.h"
@@ -77,6 +78,8 @@ void OS_Web::fs_sync_callback() {
7778
}
7879

7980
bool OS_Web::main_loop_iterate() {
81+
GodotProfileFrameMark;
82+
GodotProfileZone("OS_Web::main_loop_iterate");
8083
if (is_userfs_persistent() && idb_needs_sync && !idb_is_syncing) {
8184
idb_is_syncing = true;
8285
idb_needs_sync = false;

platform/windows/os_windows.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "core/debugger/engine_debugger.h"
4040
#include "core/debugger/script_debugger.h"
4141
#include "core/io/marshalls.h"
42+
#include "core/profiling.h"
4243
#include "core/version_generated.gen.h"
4344
#include "drivers/windows/dir_access_windows.h"
4445
#include "drivers/windows/file_access_windows.h"
@@ -2268,6 +2269,8 @@ void OS_Windows::run() {
22682269
main_loop->initialize();
22692270

22702271
while (true) {
2272+
GodotProfileFrameMark;
2273+
GodotProfileZone("OS_Windows::run");
22712274
DisplayServer::get_singleton()->process_events(); // get rid of pending events
22722275
if (Main::iteration()) {
22732276
break;

scene/main/scene_tree.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "core/object/message_queue.h"
3838
#include "core/object/worker_thread_pool.h"
3939
#include "core/os/os.h"
40+
#include "core/profiling.h"
4041
#include "node.h"
4142
#include "scene/animation/tween.h"
4243
#include "scene/debugger/scene_debugger.h"
@@ -570,6 +571,7 @@ void SceneTree::set_group(const StringName &p_group, const String &p_name, const
570571
}
571572

572573
void SceneTree::initialize() {
574+
GodotProfileZone("SceneTree::initialize");
573575
ERR_FAIL_NULL(root);
574576
MainLoop::initialize();
575577
root->_set_tree(this);

0 commit comments

Comments
 (0)