godotengine / godot

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

DisplayServer.mouse_get_position() is really slow on X11 #94714

Open L4Vo5 opened 3 months ago

L4Vo5 commented 3 months ago

Tested versions

System information

Godot v4.2.2.stable - Manjaro Linux #1 SMP PREEMPT_DYNAMIC Mon Jul 15 21:39:34 UTC 2024 - X11 - GLES3 (Compatibility) - NVIDIA GeForce GTX 1070 Ti (nvidia; 550.100) - Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz (8 Threads)

Issue description

DisplayServer.mouse_get_position() takes around 0.08ms to run on my X11 system.

This is an issue because many functions call it directly or indirectly, like CanvasItem.get_global_mouse_position/get_local_mouse_position and Viewport.get_mouse_position(). A game that calls these functions multiple times per frame could end up having serious performance problems for some users, and it wouldn't be caught easily if the game was developed in a different platform.

It seems that other DisplayServer implementations call Input::get_singleton()->get_mouse_position(), which returns a cached value. But on X11, it runs all this instead.

Steps to reproduce

Run something like the following code:

    var start := Time.get_ticks_msec()
    for i in 3_000:
        DisplayServer.mouse_get_position()
    var end := Time.get_ticks_msec()
    print((end - start) / 3_000.0)

Minimal reproduction project (MRP)

-

Calinou commented 3 months ago

Run something like the following code:

This code prints a value around 0.02 on my end on the following PC (tested multiple times):

PC specifications - **CPU:** Intel Core i9-13900K - **GPU:** NVIDIA GeForce RTX 4090 - **RAM:** 64 GB (2×32 GB DDR5-5800 C30) - **SSD:** Solidigm P44 Pro 2 TB - **OS:** Linux (Fedora 40) / Windows 11 23H2

On Windows, I get a value of ~0.00067 instead (30 times faster than Linux).

Sch1nken commented 3 months ago

Some more data points, I get some range of results. Under X11 values range from 0.076 to 0.166.

Under Wayland (assuming it's using wayland and not some wayland-x11-wrapper?) the range is even wider: From 0.047 to 0.170

Specs - CPU: AMD Ryzen 7 4800H (Mobile) - GPU: AMD Radeon RX Vega 7 (iGPU) - RAM: 32 GB - SSD: Kingston KC2000 1TB - OS: Manjaro KDE Linux (Kernel 6.9.10-1-MANJARO)

Edit: Seems like Wayland is using a cached value (sort of): https://github.com/godotengine/godot/blob/2f2d1a7e68d315e5f26cde30532a51087536c9f6/platform/linuxbsd/wayland/display_server_wayland.cpp#L381-L389

Edit: I retested with Godot 4.3 RC1 and "prefer wayland" to true (in editor settings). Wayland results are still similiar though way more skewed towards the lower end (<0.1).

Not sure what's going on here. Since Wayland is just re-using the known mouse position from the Input-Singleton, it should be somewhat faster than X11 I'd assume? Maybe there is more to it than just the X11 implementation being slow... Or I am absolutely testing the wrong thing here... :)