rust-windowing/glutin

Android (egl) example picks wrong gl version

fr-an-k opened this issue · 10 comments

The crash of #1584 is resolved on master, but the template builder still only receives a config with GLES1 instead of the available 3.2 (as the official Java example does), causing no functionality to be available, just keeps repeating:

libEGL  : called unimplemented OpenGL ES API

It seems this limited config is picked because glutin-winit/src/lib.rs build() function does not initialize a raw window handle for egl.
Then in api/egl/display.rs new() the comment says it needs raw_display or EGL_DEFAULT_DISPLAY is used which is not recommended.

Could you try altering the value of https://docs.rs/glutin/0.30.7/src/glutin/config.rs.html#171-174 for the

ConfigTemplateBuilder::new().with_alpha_size(8).with_transparency(cfg!(cgl_backend));
(you can try Gles2/gles3, etc)? You may also try other settings of the config builder, it's not like the glutin has much to do at this point.

Be aware that display creation is sane, unless there's some unknown extension we're not handling specific to your hardware. For Android using the EGL_DEFAULT_DISPLAY is fine, you can't use it for Wayland and X11 though.

You might have some luck if you print the

NO_DISPLAY_EXTENSIONS.get_or_init(|| get_extensions(egl, egl::NO_DISPLAY));
set.

The example works when I use with_api that has GLES2 and/or GLES3 but not if GLES1 is present (then configs is empty and fails to unwrap).

This could be documented for the example, but I think it should be done by default within api/egl somewhere, although I don't know how.

If I remove with_api in the example and modify GlConfig::api (in api/egl) to insert GLES2 and GLES3, then the example fails on gl_display.create_context(), with error NotSupported "the requested context Api isn't supported."

If I remove with_api in the example and modify GlConfig::api (in api/egl) to insert GLES2 and GLES3, then the example fails on gl_display.create_context(), with error NotSupported "the requested context Api isn't supported."

Yes, because the Config must support the Api you're going to use. It's sort of strange to see configs with just Gles1.

GlContext API could only use API based on the config api, so it can't do an api not supported by the context.=

This could be documented for the example, but I think it should be done by default within api/egl somewhere, although I don't know how.

I think it's not entirely possible, but as you may see, glutin provides you with the full control over what you want, so if you match the config you can't use it's on you tbf.

We could, though, request any of the gles2, gles3, and opengl, so filtering out the gles1 all together unless you ask for it.

The supported API is 3.2, but if I only insert GLES3 (in api/egl/context.rs api() function) it still fails.

I just think glutin should pick by default whatever functional version is available, 2 or 3. Otherwise, other crates would have to handle this special case explicitly or newcomers would have failing examples and not have a clue why.

raw_api only has OPENGL_ES_BIT set, i.e. GLES1, but should be OPENGL_ES3_BIT.
So the faulty logic does seem to come from the native gles api (on my device); still glutin should handle this to just work in my opinion.

If I revert to the functional version that uses with_api, then raw_api is OPENGL_ES2_BIT | OPENGL_ES3_BIT, so the wrong context appears to be picked by default.

The thing is that they all function, they just limited to what you've asked. There's no such a thing as a maximum supported version in EGL, or anything like that, all you can do is simply try and fallback.

Maybe we need to have some ranking in the example, so you could have an idea how.

So the faulty logic does seem to come from the native gles api (on my device); still glutin should handle this to just work in my opinion.

How glutin should just work, if your library is giving garbage to it? glutin is just a low level layer between your EGL/GLX, if your EGL sucks glutin can't magically make things work.

All the config ranking and fallback logic library can safely do on top of the glutin without any issue whatsoever.

We might improve example to rank the configs based on Api version available and maybe add some debug examples to help on Android, where you can't simply call the eglinfo to understand what your device can do.

If I change the constructor of ConfigTemplateBuilder then it works by default:

impl ConfigTemplateBuilder {
    /// Create a new configuration template builder.
    #[inline]
    pub fn new() -> Self {
        let mut default:Self = Default::default();
        #[cfg(egl_backend)] {
            // Pick a sensible default for egl, see issue #1586
            default.template.api = Some(Api::GLES2);
        }
        default
    }

This just forces a sensible version in the case of egl; it will automatically pick 2 or 3 whatever is available.

Edit: I doublechecked this with a clean checkout, with only this modification

Actually it should detect EGL platform first, not just depend on compilation flags

With a clean checkout I added this at line 145 of src/api/egl/config.rs:

        else {
            // Sensible default to avoid issue on some devices (see issue #1586)
            config_attributes.push(egl::RENDERABLE_TYPE as EGLint);
            config_attributes.push(egl::OPENGL_ES2_BIT as EGLint);
        }

Then the example works and I believe this is the correct approach.