Skip to content

Add VideoStreamPlayer UpdateMode to not process the invisible#114517

Open
smix8 wants to merge 1 commit intogodotengine:masterfrom
smix8:stop_doing_stuff_while_invisible
Open

Add VideoStreamPlayer UpdateMode to not process the invisible#114517
smix8 wants to merge 1 commit intogodotengine:masterfrom
smix8:stop_doing_stuff_while_invisible

Conversation

@smix8
Copy link
Copy Markdown
Contributor

@smix8 smix8 commented Jan 2, 2026

Adds UpdateMode to VideoStreamPlayer for better performance and control in gui heavy setups with lots of small video streams.

Performance

videoplayer_profiler

These performance spikes seen here are with 10+ smaller video stream players active that are all from different gui elements off-screen and not visible on a 144 hz monitor with uncapped frame rate. Part of the big jump is also caused by running into a physics death spiral due to all the senseless processing for invisible videos going on behind the scene.

The changes in this PR with visibility check is what causes the performance to reset to manageable levels because it stops processing all the videos that are in hidden menus or off-screen automatically (in this example case when the graph is at its lowest just 1 or zero videos are processing because those can actually be seen). There are other performance issues with the VideoStreamPlayer node for other PRs to fix but this is a first step.

Update modes

  • UPDATE_DISABLED
    Same as paused but without changing properties that would cause unwanted side effects in code.
  • UPDATE_WHEN_VISIBLE
    The recommended winner mode that only processes what can actually be seen on screen. Works by using the node visibility and the CanvasItem visibility notifier.
  • UPDATE_ALWAYS
    The current default that updates and processes everything all the time no matter what.

While UPDATE_ALWAYS would match with the current way the VideoStreamPlayer is behaving I recommend using the UPDATE_WHEN_VISIBLE as the new default.

It commonly does not make that much sense to process videos while not at all visible. That situation frequently is found in Control based gui menus where users park menus with video backdrops for later use. Since the video player has no dedicated debugger all users see is an increased process() time not understanding what is causing it.

I encountered these performance issues many times over in Godot projects where users would never free their menu backdrop movies because it would cause stutters when loading the (quick) menu at runtime so they entire gameplay time they would just process in the background movies that no one sees wasting performance. Sure they could add scripts to pause and un-set the Stream but they are commonly not doing that and it would be better to do it automatically.

@smix8 smix8 requested review from a team as code owners January 2, 2026 12:31
Adds UpdateMode to VideoStreamPlayer for better performance and control in gui heavy setups with lots of small video streams.
@smix8 smix8 force-pushed the stop_doing_stuff_while_invisible branch from a862bd5 to 334396e Compare January 2, 2026 12:33
@smix8 smix8 changed the title Add VideoStreamPlayer UpdateMode to stop wasting performance rendering the invisible Add VideoStreamPlayer UpdateMode to not render the invisible Jan 2, 2026
@smix8 smix8 changed the title Add VideoStreamPlayer UpdateMode to not render the invisible Add VideoStreamPlayer UpdateMode to not process the invisible Jan 2, 2026
@KoBeWi
Copy link
Copy Markdown
Member

KoBeWi commented Jan 2, 2026

Did you try VisibleOnScreenEnabler2D? Put one as child of VideoStreamPlayer and it should have the same effect.

@smix8
Copy link
Copy Markdown
Contributor Author

smix8 commented Jan 2, 2026

Did you try VisibleOnScreenEnabler2D? Put one as child of VideoStreamPlayer and it should have the same effect.

Working with extra nodes is not a viable solution because it causes node and tree related issues, especially when running tool scripts for custom video players. The node-forced video playback is flawed in many ways but that is mostly addressed by fixing the script exposed playback functions with #114515. This PR here is mostly to protect the inexperienced Godot user from running into performance issues by having a more sensible default behavior.

@Chaosus Chaosus added this to the 4.7 milestone Jan 2, 2026
@KoBeWi KoBeWi modified the milestones: 4.7, 4.x Jan 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants