Skip to content

Conversation

kkwpsv
Copy link
Contributor

@kkwpsv kkwpsv commented Jul 10, 2025

What does the pull request do?

Fix window cannot be transparent when using EGL.

What is the current behavior?

If using EGL, visualInfo will be null. Then the window will be 24-bit depth, so it cannot be transparent.

What is the updated/expected behavior with this PR?

Window can be transparent when using EGL.

How was the solution implemented (if it's not obvious)?

Using _x11.TransparentVisualInfo.

Checklist

Breaking changes

Obsoletions / Deprecations

Fixed issues

@avaloniaui-bot
Copy link

You can test this PR using the following package version. 12.0.999-cibuild0057680-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@kekekeks
Copy link
Member

kekekeks commented Jul 10, 2025

IIRC that would break rendering with nvidia driver.

@kekekeks
Copy link
Member

With recent Linux distros there is a new API for querying a proper X11 visual, but we need a MESA version check + we need to verify if that works with NVIDIA.

@kkwpsv
Copy link
Contributor Author

kkwpsv commented Jul 11, 2025

I thought this was just a bug caused by missing logic of EGL in the code. So I just set the TransparentVisualInfo.

I tested this change on the Fantasy 2 GPU (an uncommon GPU from Innosilicon), and this change works correctly. Its driver has bugs when using GLX, which causes program to crash with a SIGSEGV, but it can works with EGL.

So maybe we should add a config to control whether transparency is enabled when using EGL?

@kekekeks
Copy link
Member

EGL code should check for EGL_NATIVE_VISUAL_ID when choosing configs. If there is a matching X11 visual for the chosen config it should be used.

@kekekeks
Copy link
Member

We'll probably need to replace this code with eglGetConfigs/eglGetConfigAttrib calls and add some callbacks in EglDisplayOptions to reorder configs based on some property (X11 visual type in our case).

@kkwpsv
Copy link
Contributor Author

kkwpsv commented Jul 14, 2025

We'll probably need to replace this code with eglGetConfigs/eglGetConfigAttrib calls and add some callbacks in EglDisplayOptions to reorder configs based on some property (X11 visual type in our case).

I tried add EGL_NATIVE_VISUAL_ID with _x11.TransparentVisualInfo.visualid here, nothing happened.
It still success. Then I called GetConfigAttrib with EGL_NATIVE_VISUAL_ID, i got the default x11 visual (24-bit depth), instead of what i passed in.

It seems that only the color depth of the X11 Window affects the result.

@kkwpsv
Copy link
Contributor Author

kkwpsv commented Jul 14, 2025

The attribs now is like this (I made a simple change here to quickly test):
image

@kekekeks
Copy link
Member

EGL_NATIVE_VISUAL_ID is not a valid value to be passed to eglChooseConfig.

@kekekeks
Copy link
Member

@kkwpsv
Copy link
Contributor Author

kkwpsv commented Jul 14, 2025

In EGL_MESA_x11_native_visual_id.txt, it says This extension allows EGL_NATIVE_VISUAL_ID to be used in eglChooseConfig() for a display of type EGL_PLATFORM_X11_EXT.

@kekekeks
Copy link
Member

I'd still suggest to attempt enumerating configs manually and find one with 32 bit X11 visual

@kkwpsv
Copy link
Contributor Author

kkwpsv commented Jul 14, 2025

I'd still suggest to attempt enumerating configs manually and find one with 32 bit X11 visual

I can try it later.

But I have a question: even if I don't change any EGL configuration, I only change the depth of the X11 window, transparency works correctly. Moreover, we don't get the X11 visual via EGL now. So what's the purpose of changing the EGL config?

@kkwpsv
Copy link
Contributor Author

kkwpsv commented Jul 14, 2025

Using eglinfo -p x11 -v, I can get x11 visual with 32bit depth,but it appears at the end of the list, like belows:

(Omit)

EGL_CONFIG_ID:   5    EGL_BUFFER_SIZE: 32    EGL_LEVEL: 0
        EGL_RED_SIZE: 8    EGL_GREEN_SIZE: 8    EGL_BLUE_SIZE: 8    EGL_ALPHA_SIZE: 8
        EGL_DEPTH_SIZE: 32    EGL_STENCIL_SIZE: 0
        EGL_SAMPLES: 0    EGL_SAMPLE_BUFFERS: 0
        EGL_NATIVE_VISUAL_ID: 21    EGL_NATIVE_VISUAL_TYPE: 4    EGL_CONFIG_CAVEAT: true
        EGL_BIND_TO_TEXTURE: rgb
        EGL_RENDERABLE_TYPE: opengl,opengles,opengles2
        EGL_SURFACE_TYPE: window,pbuffer,pixmap

(Omit)

EGL_CONFIG_ID:  32    EGL_BUFFER_SIZE: 32    EGL_LEVEL: 0
        EGL_RED_SIZE: 8    EGL_GREEN_SIZE: 8    EGL_BLUE_SIZE: 8    EGL_ALPHA_SIZE: 8
        EGL_DEPTH_SIZE: 32    EGL_STENCIL_SIZE: 0
        EGL_SAMPLES: 4    EGL_SAMPLE_BUFFERS: 1
        EGL_NATIVE_VISUAL_ID: 42    EGL_NATIVE_VISUAL_TYPE: 4    EGL_CONFIG_CAVEAT: true
        EGL_BIND_TO_TEXTURE: rgb
        EGL_RENDERABLE_TYPE: opengl,opengles,opengles2
        EGL_SURFACE_TYPE: window,pbuffer,pixmap

And visual 21 is 24-bit color depth, visual 42 is 32-bit.

Here is the output of xdpyinfo

(Omit)

  default visual id:  0x21
  visual:
    visual id:    0x21
    class:    TrueColor
    depth:    24 planes
    available colormap entries:    256 per subfield
    red, green, blue masks:    0xff0000, 0xff00, 0xff
    significant bits in color specification:    8 bits

(Omit)

  visual:
    visual id:    0x42
    class:    TrueColor
    depth:    32 planes
    available colormap entries:    256 per subfield
    red, green, blue masks:    0xff0000, 0xff00, 0xff
    significant bits in color specification:    8 bits

(Omit)

Maybe this is why i get the 0x21 visual. And the _x11.TransparentVisualInfo.visualid is not one of them, so it had no effect?

@kekekeks
Copy link
Member

if I don't change any EGL configuration, I only change the depth of the X11 window, transparency works correctly

When I've tried this exact change a couple of years ago it has broken rendering completely (blank window) with some GPU drivers. So we need to do it the correct way.

@kkwpsv kkwpsv changed the title Fix window cannot be transparent when using EGL. WIP: Fix window cannot be transparent when using EGL. Jul 22, 2025
@kkwpsv
Copy link
Contributor Author

kkwpsv commented Jul 22, 2025

@kekekeks Now, I have implemented that retrieving all configurations using eglChooseConfig, then get the VisualID, and then find one with 32-bit color depth. This works fine in my virtual machine (using llvmpipe).
But in real hardwares, I can't find any VisualID with 32-bit color depth. (Tested with intel gpu and the previously mentioned Fantasy 2 GPU)

I also tried eglGetConfigs, and the configs from it were the same as those from eglChooseConfig. None of VisualID is 32-bit color depth.

So, maybe a option to force using 32-bit color depth is still necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants