godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.54k stars 21.26k forks source link

NOTIFICATION_APPLICATION_FOCUS_IN and NOTIFICATION_APPLICATION_FOCUS_OUT Cause Engine Freeze/Stutter with Large Scene Trees #98786

Open Ryan-000 opened 4 weeks ago

Ryan-000 commented 4 weeks ago

Tested versions

4.3, 4.2.2, 4.1.3, 4.0

System information

Godot v4.3.stable.mono (97f0c76f2) - Ubuntu 24.04.1 LTS 24.04 - X11 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 2080 Ti (nvidia; 560.35.03) - AMD Ryzen 9 3900X 12-Core Processor (24 Threads)

Issue description

When the NOTIFICATION_APPLICATION_FOCUS_IN and NOTIFICATION_APPLICATION_FOCUS_OUT notifications are triggered, the Godot engine freezes or stutters noticeably if there are many nodes in the scene tree. This issue affects the engine's performance, especially in scenes with large hierarchies.

Steps to reproduce

  1. Create or open a project with a scene that contains a large number of nodes in the scene tree.
  2. Run the project.
  3. Switch the application focus away from the engine (e.g., by clicking on another window).
  4. Switch the application focus back to the engine.
  5. Observe the engine's performance during these focus changes.

Minimal reproduction project (MRP)

MRP.zip

DarkyMago commented 2 weeks ago

ran a profile on the issue : godot_98786_profile

Seems to be because the window notification mechanism is slow and maybe a lack of "opt-out" mechanism. Basically, when you get a window event as such, the whole Node hierarchy is notified recursively (Window::_propagate_window_notification), via a function with a thread guard (good).

As it's all done on a single frame (good), if you have millions of nodes into millions of others, that guarded recursion is bound to be slow.

So if Godot should handle such recursion (a voxel based-game is what comes to mind for such a case), it could be a good thing to neutralize this impact somewhat. A parameter could be introduced on Node to check if it should propagate the notification further down (propagating by default for compatibility).

DarkyMago commented 2 weeks ago

But again, in this case it might be more interesting to get into specific object management with node alternatives.