glutin icon indicating copy to clipboard operation
glutin copied to clipboard

Enabling v-sync doesn't work on X11 but works on Wayland

Open DragonSWDev opened this issue 1 year ago • 8 comments

Hello, so basically after creating window surface and context from display I'm enabling or disabling v-sync based on flag passed to the function. Code looks like this:

match vsync_enabled {
            false => gl_surface.set_swap_interval(&gl_context, glutin::surface::SwapInterval::DontWait).unwrap(),
            true => gl_surface.set_swap_interval(&gl_context, glutin::surface::SwapInterval::Wait(NonZeroU32::new(1).unwrap())).unwrap()
        }

it works as expected on Wayland but doesn't work on X11 where v-sync is always disabled. I'm on Fedora 40 with NVIDIA GPU. "Sync to VBlank" option is enabled in NVIDIA Settings. Other OpenGL applications (e.g. glxgears) are running with FPS blocked to refresh rate. Am I missing something?

DragonSWDev avatar May 01 '24 20:05 DragonSWDev

Are you using EGL or GLX here?

kchibisov avatar Jun 06 '24 12:06 kchibisov

@kchibisov How can I check this?

DragonSWDev avatar Jun 10 '24 14:06 DragonSWDev

Print https://docs.rs/glutin/latest/glutin/display/trait.GlDisplay.html#tymethod.version_string .

kchibisov avatar Jun 10 '24 15:06 kchibisov

I have the same issue (GLX)

Just confirmed that vsync was working with glutin v0.29 (using ContextBuilder.with_vsync(true))

I've tried calling SwapIntervalEXT with a NULL pointer for the display here and there was no error: https://github.com/rust-windowing/glutin/blob/73ce4f91543a008b501985e065b5bb0ae4ae2c44/glutin/src/api/glx/surface.rs#L257

Also if I bypass the SwapIntervalEXT call it will go on to call SwapIntervalSGI and "succeed" (applied = true) but there is still no vsync.

spearman avatar Apr 06 '25 01:04 spearman

You can have vsync force disabled inside the driver itself.

kchibisov avatar Apr 06 '25 03:04 kchibisov

You can have vsync force disabled inside the driver itself.

It's probably not the case though if running glutin v0.29.1 with ContextBuilder.with_vsync(true) has vsync enabled?

spearman avatar Apr 06 '25 03:04 spearman

Querying the SWAP_INTERVAL_EXT segfaults:

                self.display.inner.glx.QueryDrawable(                            
                     self.display.inner.raw.cast(),                               
                     self.raw,                                                    
                     glx_extra::SWAP_INTERVAL_EXT as i32,                         
                     &mut swap,                                                   
                 );

Querying normal GLX attributes (e.g. GLX_WIDTH) works fine.

spearman avatar Apr 06 '25 18:04 spearman

You can have vsync force disabled inside the driver itself.

It's probably not the case though if running glutin v0.29.1 with ContextBuilder.with_vsync(true) has vsync enabled?

So it looks like with glutin v0.29.1 creating the GLX prototype context fails with "NoAvailablePixelFormat" so it actually falls back to EGL. With EGL it says that the default is to have Vsync enabled, and building with ContextBuilder.with_vsync(false) successfully disables it.

Confirmed that vsync does work with EGL on glutin v0.32.1 and setting the swap interval to DontWait also successfully disables it. So it seems to be a problem with GLX.

spearman avatar Apr 07 '25 00:04 spearman