Closed fluolite closed 1 day ago
Hmm, this is in get_platform_display_ext
, but before that function is called, get_platform_display
should've matched:
RawDisplayHandle::Gbm(handle) if extensions.contains("EGL_KHR_platform_gbm") => {
(egl::PLATFORM_GBM_KHR, handle.gbm_device.as_ptr())
},
Differently put: EGL_KHR_platform_gbm
should patch to (egl::PLATFORM_GBM_KHR, handle.gbm_device.as_ptr())
and not (egl::PLATFORM_GBM_MESA, handle.gbm_device.as_ptr())
.
Could you try to see why that didn't work?
@fluolite can you clarify what the issue is? You provided a list of extensions including EGL_KHR_platform_gbm
and a screenshot showing that that's part of the match, but didn't detail what is meant by In my project, get_platform_display_ext get failed
.
Specifically, can you clarify if you actually have a RawDisplayHandle::Gbm(..)
variant? How are you calling into glutin
, and what's the result?
@fluolite is using Slint IIRC and there we do create a RawDisplayHandle::Gbm
and eventually call glutin::display::Display::new(display_handle.as_raw(), glutin::display::DisplayApiPreference::Egl
).
Hmm, this is in
get_platform_display_ext
, but before that function is called,get_platform_display
should've matched:RawDisplayHandle::Gbm(handle) if extensions.contains("EGL_KHR_platform_gbm") => { (egl::PLATFORM_GBM_KHR, handle.gbm_device.as_ptr()) },
Differently put:
EGL_KHR_platform_gbm
should patch to(egl::PLATFORM_GBM_KHR, handle.gbm_device.as_ptr())
and not(egl::PLATFORM_GBM_MESA, handle.gbm_device.as_ptr())
.Could you try to see why that didn't work?
The get_platform_display did not matched! I guess is some platform implementation did not abide by EGL extensions. And I review qt source code, it look like always use eglGetProcAddress("eglGetPlatformDisplayEXT")
@fluolite can you clarify what the issue is? You provided a list of extensions including
EGL_KHR_platform_gbm
and a screenshot showing that that's part of the match, but didn't detail what is meant byIn my project, get_platform_display_ext get failed
.Specifically, can you clarify if you actually have a
RawDisplayHandle::Gbm(..)
variant? How are you calling intoglutin
, and what's the result?
I didn't use it directly but use slint ui, and slint backend is linuxkms-skia-opengl. The following is EGL extensions from glutin get_platform_display_ext println!.
Thanks @tronical, I see no way how I should have inferred that from @fluolite's minimal description 😅.
@fluolite please share snippets of code in backticks instead of screenshots, they are unnecessarily hard to read and digest.
Please debug-print the value of display: RawDisplayHandle
. I want to confirm if you truly have a Gbm
handle and not something else.
EDIT: Not to mention, @tronical is correct here that EGL_KHR_platform_gbm
should only be used with eglGetPlatformDisplay()
and not with eglGetPlatformDisplayExt()
(even if the constants PLATFORM_GBM_KHR
and PLATFORM_GBM_MESA
are the same value) so a subsequent failure that you did not provide in any message thus far is expected:
We should instead debug why egl.GetPlatformDisplay
(not the Ext
version) isn't being loaded, which is available since EGL 1.5 and a requirement for EGL_KHR_platform_gbm
to exist.
This is the debug output.
[root@TW02:/userdata/alien/bin]# export SLINT_BACKEND=linuxkms-skia-opengl
[root@TW02:/userdata/alien/bin]# ./slintprimer
============================I am fix
=====================Display new
=====================get_platform_display
=====================get_platform_display is not supported
=====================get_platform_display_ext
=====================get_platform_display_ext, extensions: {"EGL_EXT_platform_wayland", "EGL_EXT_client_extensions", "EGL_EXT_platform_base", "EGL_KHR_platform_gbm", "EGL_KHR_platform_wayland", "EGL_KHR_client_get_all_proc_addresses"}
=====================get_display
Error: Other("Error creating glutin display for native display Gbm(\n GbmDisplayHandle {\n gbm_device: 0x000000557db98990,\n },\n): failed to create EGLDisplay without a reason")
2. fix "extensions.contains("EGL_KHR_platform_gbm")" in get_platform_display_ext
[root@TW02:/userdata/alien/bin]# export SLINT_BACKEND=linuxkms-skia-opengl [root@TW02:/userdata/alien/bin]# ./slintprimer ============================I am fix =====================Display new =====================get_platform_display =====================get_platform_display is not supported =====================get_platform_display_ext =====================get_platform_display_ext, extensions: {"EGL_KHR_client_get_all_proc_addresses", "EGL_EXT_platform_base", "EGL_KHR_platform_wayland", "EGL_EXT_platform_wayland", "EGL_EXT_client_extensions", "EGL_KHR_platform_gbm"} =====================initialize_display Using Skia OpenGL renderer Rendering at 1920x1080 Slint: Build config: debug; Backend: Skia renderer (skia backend opengl; surface: 24 bpp)
Thanks! In your initialize_display
logs, can you debug-print the version
that is returned by egl.Initialize()
?
Is scenario 2 working for you? I'm curious if eglGetPlatformDisplayExt()
is allowed to work if EGL_KHR_platform_gbm
is available, which inidcates EGL 1.5 and support/requirement for eglGetPlatformDisplay()
.
Thanks! In your
initialize_display
logs, can you debug-print theversion
that is returned byegl.Initialize()
?Is scenario 2 working for you? I'm curious if
eglGetPlatformDisplayExt()
is allowed to work ifEGL_KHR_platform_gbm
is available, which inidcates EGL 1.5 and support/requirement foreglGetPlatformDisplay()
.
The logs
[root@TW02:/userdata/alien/bin]# ./slintprimer
============================I am fix
=====================Display new
=====================get_platform_display
=====================get_platform_display is not supported
=====================get_platform_display_ext
=====================get_platform_display_ext, extensions: {"EGL_KHR_platform_wayland", "EGL_EXT_platform_base", "EGL_EXT_platform_wayland", "EGL_EXT_client_extensions", "EGL_KHR_client_get_all_proc_addresses", "EGL_KHR_platform_gbm"}
=====================initialize_display
=====================initialize_display success, version major: 1, minor: 4
Using FemtoVG OpenGL renderer
Rendering at 1920x1080
Slint: Build config: debug; Backend: FemtoVG renderer
Scenario 2 working well for me, I don't know why. I'll follow it when I can.
So that's a broken EGL driver, if it advertises EGL 1.4 but also EGL_KHR_platform_gbm
which requires 1.5. You should probably report this to the respective driver vendor - they should instead advertise EGL_MESA_platform_gbm
.
AFAIK this is in the context of a Rockchip RK3568 with a Mali-G52 GPU. That's not too exotic. Would you be open to a workaround in glutin?
I think @fluolite is correct in his observation that Qt treats EGL_KHR_platform_gbm
and EGL_MESA_platform_gbm
the same.
That doesn't use the Mesa driver stack, right? I found that it should expose both MESA
and KHR
otherwise:
The commit that added the KHR
variant also explains that presence of the extension determines whether there is support for EGL 1.5 and the non-EXT
eglGetPlatformDisplay
function can be loaded:
https://gitlab.freedesktop.org/mesa/mesa/-/commit/a3fb064e000a8706319dc996788159bf84a13f0f
Neither of which is the case here, again detailing that this driver should've exposed MESA
.
I'm not the one to sign off on having workarounds in glutin
and it'd be hard to have one if there is no upstream bug report to link to in the first place. In any case this issue feels similar to the one in #1689 where libglvnd
was the culprit: is libglvnd
used here?
And as detailed above, while the value of egl::PLATFORM_GBM_KHR
is equal to that of egl::PLATFORM_GBM_MESA
, the extensions technically only specify that its values are valid for eglGetPlatformDisplay()
and eglGetPlatformDisplayEXT()
respectively so they are theoretically allowed to reject it because the combination of platform extension and function is not "allowed"?
Maybe if you link the Qt source code (which would anyway be useful when referencing something...) that does this, we could reverse-search whether that followed up with an upstream report and justification of this workaround.
I'm trying to come up with a title that is more descriptive about the actual issue at hand, since get_platform_display_ext failed
is counter what you said that get_platform_display_ext
actually works (because get_platform_display
cannot be loaded) when we allow it to handle EGL_KHR_platform_gbm
, even though the client driver should've exposed EGL_MESA_platform_gbm
. (and/or switched to EGL 1.5 which is a requirement for EGL_KHR_platform_gbm
, but that's a much bigger change to make)
Note that I am now reading from https://gitlab.freedesktop.org/glvnd/libglvnd/-/issues/251#note_2553412:
By the spec, it is allowed to support EGL 1.5 at the client level (so you can use eglGetPlatformDisplay to get your EGLDisplay), but for that to still return an EGLDisplay that only supports EGL 1.4 or earlier. So, checking the EGLDisplay's version (as returned by eglInitialize) is technically the correct thing for an application to do.
Not that that changes much. While we can't say from the result of eglInitialize()
that the client implementation should have behaved as 1.4 (that only applies to the returned EGLDisplay
), the original findings still hold that by exposing EGL_KHR_platform_gbm
we can expect the client to minimally support 1.5, yet it doesn't behave like that by not providing the eglGetPlatformDisplay()
symbol.
And as detailed above, while the value of egl::PLATFORM_GBM_KHR is equal to that of egl::PLATFORM_GBM_MESA, the extensions technically only specify that its values are valid for eglGetPlatformDisplay() and eglGetPlatformDisplayEXT() respectively so they are theoretically allowed to reject it because the combination of platform extension and function is not "allowed"?
Given that they are all the same and that EGLDisplay is the same no matter which path you take, it'll probably be fine to workaround here.
And yes, KHR
without eglGetPlatformDisplay
doesn't make any sense at all...
@fluolite I'd assume that
diff --git a/glutin/src/api/egl/display.rs b/glutin/src/api/egl/display.rs
index 4c2454d..ffe7cb0 100644
--- a/glutin/src/api/egl/display.rs
+++ b/glutin/src/api/egl/display.rs
@@ -362,7 +362,10 @@ impl Display {
handle.connection.map_or(egl::DEFAULT_DISPLAY as *mut _, |c| c.as_ptr()),
)
},
- RawDisplayHandle::Gbm(handle) if extensions.contains("EGL_MESA_platform_gbm") => {
+ RawDisplayHandle::Gbm(handle)
+ if extensions.contains("EGL_MESA_platform_gbm")
+ || extensions.contains("EGL_KHR_platform_gbm") =>
+ {
(egl::PLATFORM_GBM_MESA, handle.gbm_device.as_ptr())
},
RawDisplayHandle::Drm(_) => {
works?
I generally don't mind working around stuff like that, since usually nothing can be done in some cases other than that, and it's not like we can fail here, since if KHR
worked, we'd used it, and if e.g. mesa not present but khr present, using khr will be fine, since it's the same constant.
Though, a link with justification for stuff like that would be nice.
Maybe if you link the Qt source code (which would anyway be useful when referencing something...) that does this, we could reverse-search whether that followed up with an upstream report and justification of this workaround.
These are the two places I was looking at earlier:
https://github.com/qt/qtbase/blob/b429da48bed8cfa58f361ae85503c412919c3dd6/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp#L41 https://github.com/qt/qtbase/blob/b429da48bed8cfa58f361ae85503c412919c3dd6/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp#L28
Hm, just to make it clear, does creating surface actually work with EXT function here? Or you'd need a KHR as well for it, if that's the case it could be a bit more weird?
@kchibisov it seems yes, per the answer to my question 2 here.
(After all the enum value is the same, and the underlying function implementation likely behaves the same, even it the combination of extension version and "inferred EGL client version" is wrong)
One can try this https://github.com/rust-windowing/glutin/pull/1716 , from what I've understood in QT code it should be enough...
In my project, get_platform_display_ext get failed because egl client extensions mismatch。