egui icon indicating copy to clipboard operation
egui copied to clipboard

Fallback on GLX when EGL initialization fails

Open sphaerophoria opened this issue 2 years ago • 6 comments

On my machine eframe fails to initialize after commit 8eb687cf04dd2b68dfe467d142db6b8759425e16

This seems to be a result of a bad EGL configuration. With EGL_LOG_LEVEL=debug

libEGL debug: EGL user error 0x3003 (EGL_BAD_ALLOC) in eglCreateWindowSurface: dri3_surface_create Error: Glutin(Error { raw_code: Some(12291), raw_os_message: None, kind: OutOfMemory })

This seems to happen because the GLX fallback only kicks in when the display fails to initialize. In my case the display initializes fine but we fail to create the window surface.

Implement a more aggressive fallback where we try to fully initialize the glutin window context with EGL then GLX separately.

Although there is not a satisfying root cause to why EGL fails to initialize here, I believe it is reasonable behaviour to do our best to initialize the app if possible.

sphaerophoria avatar Jan 04 '23 04:01 sphaerophoria

there exists an issue for this at https://github.com/emilk/egui/issues/2457

can you see if https://github.com/emilk/egui/pull/2526 fixes your problem (repo/branch link in that issue)?

coderedart avatar Jan 04 '23 06:01 coderedart

#2526 fixes it, but only because of https://github.com/emilk/egui/pull/2526/commits/37d66630e3a905c47448a23cb8f2e412d91a7195

If I revert that commit I get the same behavior. Makes sense as my PR effectively does the same thing (GLX works, EGL does not)

sphaerophoria avatar Jan 04 '23 08:01 sphaerophoria

I'll also note that I'll also note that with the following diff to glutin I see the same behavior using their window example

diff --git a/glutin_examples/src/lib.rs b/glutin_examples/src/lib.rs
index b3e2581..27ad808 100644
--- a/glutin_examples/src/lib.rs
+++ b/glutin_examples/src/lib.rs
@@ -37,9 +37,9 @@ pub fn main() {
     // The template will match only the configurations supporting rendering to
     // windows.
     let template = ConfigTemplateBuilder::new().with_alpha_size(8);

-    let display_builder = DisplayBuilder::new().with_window_builder(window_builder);
+    let display_builder = DisplayBuilder::new().with_window_builder(window_builder).with_preference(glutin_winit::ApiPrefence::PreferEgl);

     let (mut window, gl_config) = display_builder
         .build(&event_loop, template, |configs| {
             // Find the config with the maximum number of samples, so our triangle will

Haven't worked through the glutin docs yet, but IMO it indicates that something is wrong pretty far down the stack.

I'll also argue that switching the order from GLX -> EGL vs EGL -> GLX isn't as robust a solution as what I've provided here. If on some systems we get the reverse behavior we're just failing the other way. Maybe that doesn't matter and in practice no one will hit that, but it's worth considering.

sphaerophoria avatar Jan 04 '23 08:01 sphaerophoria

I'll also argue that switching the order from GLX -> EGL vs EGL -> GLX isn't as robust a solution as what I've provided here. If on some systems we get the reverse behavior we're just failing the other way.

I agree. but it means we have to bring back platform gated code for egl/wgl/glx/cgl etc..

@kchibisov I wonder if this should be something glutin-winit should be dealing with behind the scenes.

coderedart avatar Jan 04 '23 10:01 coderedart

The suggestions how to improve that are welcomed, and be aware that previous glutin had exactly the same issue, but I don't remember how far it was initializing...

Be aware that glutin right now can't automate that, since everything has its own step and you may fail later on. For example on android you'll only fail once you Resume, which may happen long after you setup the context.

If you want an aggressive fallback to GLX like that you'd need to go back at the moment of query for such thing. And also do a EGL termination and unloading, which glutin doesn't have right now (and never had) before.

In general GLX works more often then EGL and the same applies to WGL, since both of them are native solutions existed on the platforms. On Wayland you'll have just EGL. That's for example what was before, glutin was simply always trying GLX first and for most users it was just working.

kchibisov avatar Jan 04 '23 10:01 kchibisov

Be aware that glutin right now can't automate that, since everything has its own step and you may fail later on. For example on android you'll only fail once you Resume, which may happen long after you setup the context. If you want an aggressive fallback to GLX like that you'd need to go back at the moment of query for such thing. And also do a EGL termination and unloading, which glutin doesn't have right now (and never had) before.

understood. I will just leave it as FallbackEgl for now. @emilk can make the final decision if he feels the complexity of dealing with retries is worth it.

coderedart avatar Jan 04 '23 11:01 coderedart

Feedback applied, thanks!

sphaerophoria avatar Jan 28 '23 23:01 sphaerophoria

This needs cargo fmt

emilk avatar Feb 04 '23 15:02 emilk

I tried pushing new commits to this branch, but I messed up somehow. I'm sorry!

Tip: don't make PRs from your master branch 😬

emilk avatar Feb 08 '23 08:02 emilk