glutin icon indicating copy to clipboard operation
glutin copied to clipboard

window example fails on Weston and Mesa 17.3.0 (and a workaround)

Open antonycourtney opened this issue 7 years ago • 1 comments

If I build glutin at HEAD and run the window example on Ubuntu (16.04) using Mesa 17.3.0 and Weston 1.11.90, it fails with:

$ ./target/debug/examples/window
thread 'main' panicked at 'eglCreateContext failed: 0x3009', src/api/egl/mod.rs:775:18

Digging in a bit and doing some printf debugging, I found this failing because the call to eglCreateContext from create_context in mod.rs is attempting to pass (3,2) as the (major,minor) version pair for ffi::egl::CONTEXT_MAJOR_VERSION and ffi::egl::CONTEXT_MINOR_VERSION. Mesa returns ffi::egl::BAD_MATCH in this case, but the error handler in create_context() in api/egl/mod.rs only handles ffi::egl::BAD_ATTRIBUTE and panics otherwise.

Tracking down where these version numbers are coming from, I found the following: First, in Context::new, we attempt to get the EGL version numbers (egl_version) via a call to egl.Initialize: https://github.com/tomaka/glutin/blob/master/src/api/egl/mod.rs#L187

Then, based on this EGL version number, we attempt to bind to different variants of OpenGL APIs, based on the specific OpenGL API requested in opengl.version: https://github.com/tomaka/glutin/blob/master/src/api/egl/mod.rs#L211

In the current example, we end up getting 1.4 back from EGL, opengl.version is GlRequest::Latest, and the call to egl.BindAPI(ffi::egl::OPENGL_API) succeeds, so (version,api) is bound to (None, Api::OpenGl). The value GLRequest::Latest bound to opengl.version appears to be the default value for self.gl_attr.version for ContextBuilder.

My straightforward workaround is to request OpenGlEs instead of OpenGL and specify (2, 0) as the version pair by changing this line of window.rs so it reads:

    let context = glutin::ContextBuilder::new().with_gl(GlRequest::Specific(Api::OpenGlEs, (2, 0)));

(Of course I also added the appropriate use calls). With this tiny change, the example works again.

But, of course, this is just a workaround. I'm new to GL programming, EGL and Rust, so I'm not entirely sure what the correct fix would be, but a couple of speculative ideas:

  1. Perhaps the error handler in create_context() should handle BAD_MATCH in addition to BAD_ATTRIBUTE, so that the call to eglCreateContext returns an error instead of calling panic. I think that would let the logic in ContextPrototype::finish_impl here make a couple of more tries which would eventually call create_context with (1, 0) as the version pair.

  2. Perhaps the version numbers being passed to eglCreateContext are just off, or are being passed in the wrong way? One thing I noticed during printf debugging that seems a bit suspect to me is that ffi::egl::CONTEXT_CLIENT_VERSION and ffi::egl::CONTEXT_MAJOR_VERSION have the same value.

I notice that #988 seems to fail in the same way (panic during Egl context creation), so perhaps it is the same issue and could possibly use the same workaround.

antonycourtney avatar Mar 13 '18 04:03 antonycourtney

Hey, could you post the results of glxinfo && glinfo && lspci?

goddessfreya avatar Mar 19 '19 05:03 goddessfreya