1
0
mirror of https://github.com/godotengine/godot.git synced 2025-12-04 17:04:49 +00:00

Add some important profiling hooks.

This commit is contained in:
Lukas Tenbrink
2025-04-01 19:00:57 +02:00
parent e80194e31f
commit c3747884da
14 changed files with 118 additions and 10 deletions

View File

@@ -50,6 +50,7 @@
#include "core/object/script_language.h"
#include "core/os/os.h"
#include "core/os/time.h"
#include "core/profiling/profiling.h"
#include "core/register_core_types.h"
#include "core/string/translation_server.h"
#include "core/version.h"
@@ -975,6 +976,7 @@ int Main::test_entrypoint(int argc, char *argv[], bool &tests_need_run) {
*/
Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_phase) {
GodotProfileZone("setup");
Thread::make_main_thread();
set_current_thread_safe_for_nodes(true);
@@ -2852,6 +2854,7 @@ Error _parse_resource_dummy(void *p_data, VariantParser::Stream *p_stream, Ref<R
}
Error Main::setup2(bool p_show_boot_logo) {
GodotProfileZone("setup2");
OS::get_singleton()->benchmark_begin_measure("Startup", "Main::Setup2");
Thread::make_main_thread(); // Make whatever thread call this the main thread.
@@ -3687,6 +3690,7 @@ Error Main::setup2(bool p_show_boot_logo) {
}
void Main::setup_boot_logo() {
GodotProfileZone("setup_boot_logo");
MAIN_PRINT("Main: Load Boot Image");
#if !defined(TOOLS_ENABLED) && defined(WEB_ENABLED)
@@ -3782,6 +3786,7 @@ static MainTimerSync main_timer_sync;
// and should move on to `OS::run`, and EXIT_FAILURE otherwise for
// an early exit with that error code.
int Main::start() {
GodotProfileZone("start");
OS::get_singleton()->benchmark_begin_measure("Startup", "Main::Start");
ERR_FAIL_COND_V(!_start_success, EXIT_FAILURE);
@@ -4641,6 +4646,8 @@ static uint64_t navigation_process_max = 0;
// will terminate the program. In case of failure, the OS exit code needs
// to be set explicitly here (defaults to EXIT_SUCCESS).
bool Main::iteration() {
GodotProfileZone("Main::iteration");
GodotProfileZoneGroupedFirst(_profile_zone, "prepare");
iterating++;
const uint64_t ticks = OS::get_singleton()->get_ticks_usec();
@@ -4686,6 +4693,8 @@ bool Main::iteration() {
#endif // XR_DISABLED
for (int iters = 0; iters < advance.physics_steps; ++iters) {
GodotProfileZone("Physics Step");
GodotProfileZoneGroupedFirst(_physics_zone, "setup");
if (Input::get_singleton()->is_agile_input_event_flushing()) {
Input::get_singleton()->flush_buffered_events();
}
@@ -4698,18 +4707,22 @@ bool Main::iteration() {
// Prepare the fixed timestep interpolated nodes BEFORE they are updated
// by the physics server, otherwise the current and previous transforms
// may be the same, and no interpolation takes place.
GodotProfileZoneGrouped(_physics_zone, "main loop iteration prepare");
OS::get_singleton()->get_main_loop()->iteration_prepare();
#ifndef PHYSICS_3D_DISABLED
GodotProfileZoneGrouped(_physics_zone, "PhysicsServer3D::sync");
PhysicsServer3D::get_singleton()->sync();
PhysicsServer3D::get_singleton()->flush_queries();
#endif // PHYSICS_3D_DISABLED
#ifndef PHYSICS_2D_DISABLED
GodotProfileZoneGrouped(_physics_zone, "PhysicsServer2D::sync");
PhysicsServer2D::get_singleton()->sync();
PhysicsServer2D::get_singleton()->flush_queries();
#endif // PHYSICS_2D_DISABLED
GodotProfileZoneGrouped(_physics_zone, "physics_process");
if (OS::get_singleton()->get_main_loop()->physics_process(physics_step * time_scale)) {
#ifndef PHYSICS_3D_DISABLED
PhysicsServer3D::get_singleton()->end_sync();
@@ -4727,9 +4740,11 @@ bool Main::iteration() {
uint64_t navigation_begin = OS::get_singleton()->get_ticks_usec();
#ifndef NAVIGATION_2D_DISABLED
GodotProfileZoneGrouped(_profile_zone, "NavigationServer2D::physics_process");
NavigationServer2D::get_singleton()->physics_process(physics_step * time_scale);
#endif // NAVIGATION_2D_DISABLED
#ifndef NAVIGATION_3D_DISABLED
GodotProfileZoneGrouped(_profile_zone, "NavigationServer3D::physics_process");
NavigationServer3D::get_singleton()->physics_process(physics_step * time_scale);
#endif // NAVIGATION_3D_DISABLED
@@ -4740,17 +4755,20 @@ bool Main::iteration() {
#endif // !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED)
#ifndef PHYSICS_3D_DISABLED
GodotProfileZoneGrouped(_profile_zone, "3D physics");
PhysicsServer3D::get_singleton()->end_sync();
PhysicsServer3D::get_singleton()->step(physics_step * time_scale);
#endif // PHYSICS_3D_DISABLED
#ifndef PHYSICS_2D_DISABLED
GodotProfileZoneGrouped(_profile_zone, "2D physics");
PhysicsServer2D::get_singleton()->end_sync();
PhysicsServer2D::get_singleton()->step(physics_step * time_scale);
#endif // PHYSICS_2D_DISABLED
message_queue->flush();
GodotProfileZoneGrouped(_profile_zone, "main loop iteration end");
OS::get_singleton()->get_main_loop()->iteration_end();
physics_process_ticks = MAX(physics_process_ticks, OS::get_singleton()->get_ticks_usec() - physics_begin); // keep the largest one for reference
@@ -4765,20 +4783,25 @@ bool Main::iteration() {
uint64_t process_begin = OS::get_singleton()->get_ticks_usec();
GodotProfileZoneGrouped(_profile_zone, "process");
if (OS::get_singleton()->get_main_loop()->process(process_step * time_scale)) {
exit = true;
}
message_queue->flush();
#ifndef NAVIGATION_2D_DISABLED
GodotProfileZoneGrouped(_profile_zone, "process 2D navigation");
NavigationServer2D::get_singleton()->process(process_step * time_scale);
#endif // NAVIGATION_2D_DISABLED
#ifndef NAVIGATION_3D_DISABLED
GodotProfileZoneGrouped(_profile_zone, "process 3D navigation");
NavigationServer3D::get_singleton()->process(process_step * time_scale);
#endif // NAVIGATION_3D_DISABLED
GodotProfileZoneGrouped(_profile_zone, "RenderingServer::sync");
RenderingServer::get_singleton()->sync(); //sync if still drawing from previous frames.
GodotProfileZoneGrouped(_profile_zone, "RenderingServer::draw");
const bool has_pending_resources_for_processing = RD::get_singleton() && RD::get_singleton()->has_pending_resources_for_processing();
bool wants_present = (DisplayServer::get_singleton()->can_any_window_draw() ||
DisplayServer::get_singleton()->has_additional_outputs()) &&
@@ -4802,12 +4825,15 @@ bool Main::iteration() {
process_max = MAX(process_ticks, process_max);
uint64_t frame_time = OS::get_singleton()->get_ticks_usec() - ticks;
GodotProfileZoneGrouped(_profile_zone, "GDExtensionManager::frame");
GDExtensionManager::get_singleton()->frame();
GodotProfileZoneGrouped(_profile_zone, "ScriptServer::frame");
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
ScriptServer::get_language(i)->frame();
}
GodotProfileZoneGrouped(_profile_zone, "AudioServer::update");
AudioServer::get_singleton()->update();
if (EngineDebugger::is_active()) {
@@ -4846,6 +4872,7 @@ bool Main::iteration() {
iterating--;
if (movie_writer) {
GodotProfileZoneGrouped(_profile_zone, "movie_writer->add_frame");
movie_writer->add_frame();
}
@@ -4872,6 +4899,7 @@ bool Main::iteration() {
SceneTree *scene_tree = SceneTree::get_singleton();
bool wake_for_events = scene_tree && scene_tree->is_accessibility_enabled();
GodotProfileZoneGrouped(_profile_zone, "OS::add_frame_delay");
OS::get_singleton()->add_frame_delay(DisplayServer::get_singleton()->window_can_draw(), wake_for_events);
#ifdef TOOLS_ENABLED
@@ -4911,6 +4939,7 @@ void Main::force_redraw() {
* The order matters as some of those steps are linked with each other.
*/
void Main::cleanup(bool p_force) {
GodotProfileZone("cleanup");
OS::get_singleton()->benchmark_begin_measure("Shutdown", "Main::Cleanup");
if (!p_force) {
ERR_FAIL_COND(!_start_success);