godotengine / godot

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

Severe stutter when enabling VSync while video is playing in the background (+ fps value wrong?) #80267

Open bluenote10 opened 1 year ago

bluenote10 commented 1 year ago

Godot version

v4.1.stable.official [970459615]

System information

Godot v4.1.stable - Ubuntu 22.04.2 LTS 22.04 - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 980 (nvidia; 535.54.03) - Intel(R) Core(TM) i5-4670 CPU @ 3.40GHz (4 Threads)

Issue description

I noticed that when I have a video playing in the background, enabling VSync in Godot causes extreme stutter, and much more than it should be considering the system load vs the simplicity of the scene.

Consider for instance this absolute basic scene, consisting merely of a draggable sprite:

extends Node2D

var sprite: Sprite2D
var label: Label

func _ready():
    sprite = Sprite2D.new()
    label = Label.new()

    var texture = load("res://icon.svg")
    sprite.texture = texture

    add_child(sprite)
    add_child(label)

func _input(event):
    if event is InputEventMouseMotion and Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
        sprite.position += event.relative

    if event is InputEventKey:
        if event.keycode == KEY_V and event.is_pressed() and not event.is_echo():
            if DisplayServer.window_get_vsync_mode() == DisplayServer.VSYNC_ENABLED:
                DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED)
            elif DisplayServer.window_get_vsync_mode() == DisplayServer.VSYNC_DISABLED:
                DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_ENABLED)

func _process(_delta):
    label.text = "fps: %s, vsync: %s" % [Engine.get_frames_per_second(), DisplayServer.window_get_vsync_mode()]

The following are some slow motion videos to show the issue.

Case 1: no video playing in background, vsync on

https://github.com/godotengine/godot/assets/3620703/a827f121-fbc9-4e0f-acbd-a4fb037d32b6

That's stable 144 fps, butter smooth.

Case 2: with video playing in background, vsync off

https://github.com/godotengine/godot/assets/3620703/22b29925-d145-4268-8905-3529ce2d8b02

That's 3000+ fps, also butter smooth.

Case 3: with video playing in background, vsync on

https://github.com/godotengine/godot/assets/3620703/f2282692-9459-44a4-bbc0-fb256871e373

Now the fps meter says something close to ~140 fps, which shouldn't be that bad. However, the outcome has severe stutter. It feels more like 30 fps or so.

In fact, that is also what the numbers of the process time suggest. Here are the graphs of frames per second and the process time in this case:

image

A process time of around 30 ms would correspond to ~33 fps, which is how it feels.

Somehow that doesn't seem to make sense to me: If the scene is capable of rendering at 3000+ fps without VSync -- also while playing a video in the background (!) -- activating VSync should not result in suddenly dropping down to ~30 fps. There should be more than enough headroom to render exactly at the 144 Hz my monitor is vsyncing to.

I also tried running third party games (most likely not Godot based ones), and they seem to render fully smoothly while playing the same video in the background.

Steps to reproduce

Unfortunately, reproduction is likely OS/system specific. This is under Linux (Ubuntu 22.04) running X11, NVIDIA GeForce GTX 980, NVIDIA Driver Version: 535.54.03

On such a system:

EDIT: Oh interesting, the issue seems to be related to the video player. The issue happens with GNOME Videos (totem) player, but not with vlc. Nonetheless, other games can cope with running totem videos in the background, and the frame drop probably still shouldn't happen?

Minimal reproduction project

VSyncStutter.zip

Or here on GitHub.

Calinou commented 1 year ago

Do you have variable refresh rate (G-Sync) enabled in nvidia-settings?

EDIT: Oh interesting, the issue seems to be related to the video player. The issue happens with GNOME Videos (totem) player, but not with vlc.

All roads lead to mpv :slightly_smiling_face:

bluenote10 commented 1 year ago

Do you have variable refresh rate (G-Sync) enabled in nvidia-settings?

No, it's all default. In fact, my nvidia-settings doesn't seem to offer gsync settings (as shown e.g. here). For me the settings are:

image

image

All roads lead to mpv slightly_smiling_face

Thanks for the tip!

cottatheripper commented 2 months ago

I'm having the exact same issue. Godot 4.2.1 win10, AMD ryzen 5 3600 6-core, NVIDIA Geforce RTX 2060. A super noticable de-sync/jitter appears when I watch a youtube video while the game is running and vsync is enabled.