Repository: godotengine/godot
File: main/main.cpp (C++)

Code before:
	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()) &&
			RenderingServer::get_singleton()->is_render_loop_enabled();

	if (wants_present || has_pending_resources_for_processing) {
		wants_present |= force_redraw_requested;
		if ((!force_redraw_requested) && OS::get_singleton()->is_in_low_processor_usage_mode()) {
			if (RenderingServer::get_singleton()->has_changed()) {
				RenderingServer::get_singleton()->draw(wants_present, scaled_step); // flush visual commands
				Engine::get_singleton()->increment_frames_drawn();
			}
		} else {
			RenderingServer::get_singleton()->draw(wants_present, scaled_step); // flush visual commands
			Engine::get_singleton()->increment_frames_drawn();
			force_redraw_requested = false;
		}
	}

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

	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();

Review comment (suggestion):
GitHub only lets me comment around the specific changes, so I can put this here:

my suggestion is to expand a bit on the physics processing hooks. The advantage is that we can see each physics step separately. This partial code comes from 4.4.1, so it might require a slight upgrade for current master:

```cpp
	GodotProfileZoneGrouped(_profile_zone, "NavigationServer2D::sync");
	NavigationServer2D::get_singleton()->sync();
	GodotProfileZoneGrouped(_profile_zone, "NavigationServer3D::sync");
	NavigationServer3D::get_singleton()->sync();

	GodotProfileZoneGrouped(_profile_zone, "Physics Handling");
	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();
		}

		Engine::get_singleton()->_in_physics = true;
		Engine::get_singleton()->_physics_frames++;

		uint64_t physics_begin = OS::get_singleton()->get_ticks_usec();

		// 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 _3D_DISABLED
		GodotProfileZoneGrouped(_physics_zone, "PhysicsServer3D::sync");
		PhysicsServer3D::get_singleton()->sync();
		PhysicsServer3D::get_singleton()->flush_queries();
#endif // _3D_DISABLED
		GodotProfileZoneGrouped(_physics_zone, "PhysicsServer2D::sync");
		PhysicsServer2D::get_singleton()->sync();
		PhysicsServer2D::get_singleton()->flush_queries();

		GodotProfileZoneGrouped(_physics_zone, "physics_process");
		if (OS::get_singleton()->get_main_loop()->physics_process(physics_step * time_scale)) {
#ifndef _3D_DISABLED
			PhysicsServer3D::get_singleton()->end_sync();
#endif // _3D_DISABLED
			PhysicsServer2D::get_singleton()->end_sync();

			Engine::get_singleton()->_in_physics = false;
			exit = true;
			break;
		}

		GodotProfileZoneGrouped(_physics_zone, "navigation");
		uint64_t navigation_begin = OS::get_singleton()->get_ticks_usec();

		GodotProfileZoneGrouped(_physics_zone, "process 3D navigation");
		NavigationServer3D::get_singleton()->process(physics_step * time_scale);

		navigation_process_ticks = MAX(navigation_process_ticks, OS::get_singleton()->get_ticks_usec() - navigation_begin); // keep the largest one for reference
		navigation_process_max = MAX(OS::get_singleton()->get_ticks_usec() - navigation_begin, navigation_process_max);

		message_queue->flush();

#ifndef _3D_DISABLED
		GodotProfileZoneGrouped(_physics_zone, "3D physics");
		PhysicsServer3D::get_singleton()->end_sync();
		PhysicsServer3D::get_singleton()->step(physics_step * time_scale);
#endif // _3D_DISABLED

		GodotProfileZoneGrouped(_physics_zone, "2D physics");
		PhysicsServer2D::get_singleton()->end_sync();
		PhysicsServer2D::get_singleton()->step(physics_step * time_scale);

		message_queue->flush();

		GodotProfileZoneGrouped(_physics_zone, "main loop iteration end");
		OS::get_singleton()->get_main_loop()->iteration_end();
```


Code after:
			Input::get_singleton()->flush_buffered_events();
		}

		Engine::get_singleton()->_in_physics = true;
		Engine::get_singleton()->_physics_frames++;

		uint64_t physics_begin = OS::get_singleton()->get_ticks_usec();

		// 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();
#endif // PHYSICS_3D_DISABLED
#ifndef PHYSICS_2D_DISABLED
			PhysicsServer2D::get_singleton()->end_sync();
#endif // PHYSICS_2D_DISABLED

			Engine::get_singleton()->_in_physics = false;
			exit = true;
			break;
		}

#if !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED)
		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