From ad0ef47f4975872aafbc0fe898b82ae6433c0881 Mon Sep 17 00:00:00 2001 From: Tony Bierman Date: Fri, 8 May 2026 08:27:23 -0500 Subject: [PATCH 1/4] anyrender_skia: pick X11 visual before window creation to avoid EGL_BAD_MATCH winit's default X11 window inherits the root visual via COPY_FROM_PARENT, which may not match any EGL FBConfig. The Skia OpenGL backend then panics with `EGL_BAD_MATCH` at `eglCreateWindowSurface` (e.g. on NVIDIA + X11). Expose `pick_x11_gl_visual` so callers can query a GL-compatible visual from the EGL configs and apply it via `WindowAttributesExtX11::with_x11_visual` before creating the window. The `OpenGLBackend` config search now also filters with `compatible_with_native_window` so it converges on the same visual. Update bunnymark to use the new helper so its default Skia/GL path no longer crashes on startup. Co-Authored-By: Claude Sonnet 4.6 --- crates/anyrender_skia/src/lib.rs | 3 + crates/anyrender_skia/src/opengl.rs | 94 ++++++++++++++++++++--------- examples/bunnymark/src/main.rs | 19 +++++- 3 files changed, 85 insertions(+), 31 deletions(-) diff --git a/crates/anyrender_skia/src/lib.rs b/crates/anyrender_skia/src/lib.rs index a52bd7e..8407766 100644 --- a/crates/anyrender_skia/src/lib.rs +++ b/crates/anyrender_skia/src/lib.rs @@ -14,3 +14,6 @@ mod vulkan; pub use image_renderer::SkiaImageRenderer; pub use scene::{SkiaSceneCache, SkiaScenePainter}; pub use window_renderer::*; + +#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] +pub use opengl::pick_x11_gl_visual; diff --git a/crates/anyrender_skia/src/opengl.rs b/crates/anyrender_skia/src/opengl.rs index 9ce8908..9417b11 100644 --- a/crates/anyrender_skia/src/opengl.rs +++ b/crates/anyrender_skia/src/opengl.rs @@ -1,5 +1,6 @@ use std::{ffi::CString, num::NonZeroU32, sync::Arc}; +use glutin::config::Config; use glutin::display::DisplayApiPreference; use glutin::{ config::{ConfigTemplateBuilder, GetGlConfig, GlConfig}, @@ -8,6 +9,7 @@ use glutin::{ prelude::{GlDisplay, NotCurrentGlContext, PossiblyCurrentGlContext}, surface::{GlSurface, SurfaceAttributesBuilder, WindowSurface}, }; +use raw_window_handle::{RawDisplayHandle, RawWindowHandle}; use skia_safe::{ Surface, gpu::{ @@ -18,6 +20,66 @@ use skia_safe::{ use crate::window_renderer::SkiaBackend; +fn build_gl_display(raw_display_handle: RawDisplayHandle, _raw_window: Option) -> Display { + unsafe { + Display::new( + raw_display_handle, + #[cfg(any(target_os = "macos", target_os = "ios"))] + DisplayApiPreference::Cgl, + #[cfg(target_os = "windows")] + DisplayApiPreference::Wgl(_raw_window), + #[cfg(not(any(target_os = "windows", target_os = "macos", target_os = "ios")))] + DisplayApiPreference::Egl, + ) + .unwrap() + } +} + +fn pick_gl_config(display: &Display, raw_window: Option) -> Config { + let mut template = ConfigTemplateBuilder::new().with_transparency(true); + if let Some(rwh) = raw_window { + template = template.compatible_with_native_window(rwh); + } + let template = template.build(); + unsafe { + display + .find_configs(template) + .unwrap() + .reduce(|accum, config| { + let transparency_check = config.supports_transparency().unwrap_or(false) + & !accum.supports_transparency().unwrap_or(false); + + if transparency_check || config.num_samples() < accum.num_samples() { + config + } else { + accum + } + }) + .expect("no GL config found for display") + } +} + +/// Pick an X11 visual ID compatible with the OpenGL backend used by [`SkiaWindowRenderer`]. +/// +/// Apply the returned visual to the winit window with [`WindowAttributesExtX11::with_x11_visual`] +/// before creating the window. This avoids `EGL_BAD_MATCH` at surface creation, which happens +/// when winit's default visual doesn't match any EGL config. +/// +/// Returns `None` on non-X11 displays (Wayland, macOS, Windows) or if the platform's EGL +/// implementation doesn't expose an X11 visual ID for the picked config. +/// +/// [`WindowAttributesExtX11::with_x11_visual`]: https://docs.rs/winit/latest/winit/platform/x11/trait.WindowAttributesExtX11.html#tymethod.with_x11_visual +#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] +pub fn pick_x11_gl_visual(raw_display_handle: RawDisplayHandle) -> Option { + if !matches!(raw_display_handle, RawDisplayHandle::Xlib(_) | RawDisplayHandle::Xcb(_)) { + return None; + } + let display = build_gl_display(raw_display_handle, None); + let config = pick_gl_config(&display, None); + use glutin::platform::x11::X11GlConfigExt; + config.x11_visual().map(|v| v.visual_id() as u32) +} + pub(crate) struct OpenGLBackend { surface: Option, gr_context: DirectContext, @@ -35,36 +97,8 @@ impl OpenGLBackend { let raw_display_handle = window.display_handle().unwrap().as_raw(); let raw_window_handle = window.window_handle().unwrap().as_raw(); - let gl_display = unsafe { - Display::new( - raw_display_handle, - #[cfg(any(target_os = "macos", target_os = "ios"))] - DisplayApiPreference::Cgl, - #[cfg(target_os = "windows")] - DisplayApiPreference::Wgl(Some(raw_window_handle.clone())), - #[cfg(not(any(target_os = "windows", target_os = "macos", target_os = "ios")))] - DisplayApiPreference::Egl, - ) - .unwrap() - }; - - let gl_config_template = ConfigTemplateBuilder::new().with_transparency(true).build(); - let gl_config = unsafe { - gl_display - .find_configs(gl_config_template) - .unwrap() - .reduce(|accum, config| { - let transparency_check = config.supports_transparency().unwrap_or(false) - & !accum.supports_transparency().unwrap_or(false); - - if transparency_check || config.num_samples() < accum.num_samples() { - config - } else { - accum - } - }) - .unwrap() - }; + let gl_display = build_gl_display(raw_display_handle, Some(raw_window_handle)); + let gl_config = pick_gl_config(&gl_display, Some(raw_window_handle)); let gl_context_attrs = ContextAttributesBuilder::new().build(Some(raw_window_handle)); let gl_surface_attrs = SurfaceAttributesBuilder::::new().build( diff --git a/examples/bunnymark/src/main.rs b/examples/bunnymark/src/main.rs index 9401410..0761b2a 100644 --- a/examples/bunnymark/src/main.rs +++ b/examples/bunnymark/src/main.rs @@ -1,4 +1,6 @@ use anyrender::{PaintScene, WindowRenderer}; +#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] +use anyrender_skia::pick_x11_gl_visual; use anyrender_skia::{SkiaImageRenderer, SkiaWindowRenderer}; use anyrender_vello::VelloWindowRenderer; use anyrender_vello_cpu::VelloCpuWindowRenderer; @@ -134,7 +136,7 @@ impl App { RenderState::Suspended(cached_window) => cached_window.clone(), }; let window = window.take().unwrap_or_else(|| { - let attr = Window::default_attributes() + let mut attr = Window::default_attributes() .with_inner_size(winit::dpi::LogicalSize::new( self.logical_width, self.logical_height, @@ -143,6 +145,21 @@ impl App { .with_title("anyrender + winit demo") .with_visible(true) .with_active(true); + + // On X11, pre-pick a visual that's compatible with the OpenGL backend's EGL + // configs. winit otherwise inherits the root window's visual via COPY_FROM_PARENT, + // which may have no matching EGL config and causes EGL_BAD_MATCH at surface creation. + #[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] + { + use winit::platform::x11::WindowAttributesExtX11; + use winit::raw_window_handle::HasDisplayHandle; + if let Ok(display_handle) = event_loop.display_handle() { + if let Some(visual_id) = pick_x11_gl_visual(display_handle.as_raw()) { + attr = attr.with_x11_visual(visual_id); + } + } + } + Arc::new(event_loop.create_window(attr).unwrap()) }); self.scale_factor = window.scale_factor(); From 8e761885e0451e6905691f07391d1779cc20e9f0 Mon Sep 17 00:00:00 2001 From: Tony Bierman Date: Fri, 8 May 2026 08:30:08 -0500 Subject: [PATCH 2/4] player: pre-pick X11 visual to avoid EGL_BAD_MATCH on Linux/X11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same fix as bunnymark — the player's default Skia/GL backend would crash at startup on X11 because winit's COPY_FROM_PARENT visual may not match any EGL config. Apply `pick_x11_gl_visual` before window creation. Co-Authored-By: Claude Sonnet 4.6 --- examples/player/src/main.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/examples/player/src/main.rs b/examples/player/src/main.rs index 4641733..782c5ea 100644 --- a/examples/player/src/main.rs +++ b/examples/player/src/main.rs @@ -1,5 +1,7 @@ use anyrender::{NullWindowRenderer, PaintScene, Scene, WindowRenderer}; use anyrender_serialize::SceneArchive; +#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] +use anyrender_skia::pick_x11_gl_visual; use anyrender_skia::SkiaWindowRenderer; use anyrender_vello::VelloWindowRenderer; use anyrender_vello_cpu::{PixelsWindowRenderer, SoftbufferWindowRenderer, VelloCpuImageRenderer}; @@ -131,12 +133,27 @@ impl App { RenderState::Suspended(cached_window) => cached_window.clone(), }; let window = window.take().unwrap_or_else(|| { - let attr = Window::default_attributes() + let mut attr = Window::default_attributes() .with_inner_size(winit::dpi::LogicalSize::new(self.width, self.height)) .with_resizable(true) .with_title("anyrender + winit demo") .with_visible(true) .with_active(true); + + // On X11, pre-pick a visual that's compatible with the OpenGL backend's EGL + // configs. winit otherwise inherits the root window's visual via COPY_FROM_PARENT, + // which may have no matching EGL config and causes EGL_BAD_MATCH at surface creation. + #[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] + { + use winit::platform::x11::WindowAttributesExtX11; + use winit::raw_window_handle::HasDisplayHandle; + if let Ok(display_handle) = event_loop.display_handle() { + if let Some(visual_id) = pick_x11_gl_visual(display_handle.as_raw()) { + attr = attr.with_x11_visual(visual_id); + } + } + } + Arc::new(event_loop.create_window(attr).unwrap()) }); From 7dd7acfd976b72ccda425d1eca9e2b30dba0b46a Mon Sep 17 00:00:00 2001 From: Tony Bierman Date: Fri, 8 May 2026 08:55:14 -0500 Subject: [PATCH 3/4] anyrender_skia: tighten pick_x11_gl_visual API and cache GL Display Address review nits from the prior commit: - pick_gl_config now returns Option so pick_x11_gl_visual can honor its documented Option contract instead of panicking when no EGL configs are available. OpenGLBackend::new keeps a clear panic at its call site. - Cache the glutin Display in a process-local OnceLock> keyed by raw display pointer so we don't initialize EGL twice for the same X server connection (once in pick_x11_gl_visual, once in OpenGLBackend::new). - Reword the docstring to match the cfg gating: macOS/Windows callers can't see the symbol, so describe failure modes by display-handle variant ("non-Xlib/Xcb display handles") instead. Co-Authored-By: Claude Sonnet 4.6 --- crates/anyrender_skia/src/opengl.rs | 58 +++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/crates/anyrender_skia/src/opengl.rs b/crates/anyrender_skia/src/opengl.rs index 9417b11..cfa7514 100644 --- a/crates/anyrender_skia/src/opengl.rs +++ b/crates/anyrender_skia/src/opengl.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; +use std::sync::{Mutex, OnceLock}; use std::{ffi::CString, num::NonZeroU32, sync::Arc}; use glutin::config::Config; @@ -35,7 +37,7 @@ fn build_gl_display(raw_display_handle: RawDisplayHandle, _raw_window: Option) -> Config { +fn pick_gl_config(display: &Display, raw_window: Option) -> Option { let mut template = ConfigTemplateBuilder::new().with_transparency(true); if let Some(rwh) = raw_window { template = template.compatible_with_native_window(rwh); @@ -44,7 +46,7 @@ fn pick_gl_config(display: &Display, raw_window: Option) -> Con unsafe { display .find_configs(template) - .unwrap() + .ok()? .reduce(|accum, config| { let transparency_check = config.supports_transparency().unwrap_or(false) & !accum.supports_transparency().unwrap_or(false); @@ -55,18 +57,53 @@ fn pick_gl_config(display: &Display, raw_window: Option) -> Con accum } }) - .expect("no GL config found for display") } } +/// Cache of glutin `Display`s keyed by the raw X display/connection pointer, to avoid +/// double-initializing EGL for the same X server connection (once in `pick_x11_gl_visual` +/// and again in `OpenGLBackend::new`). +#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] +fn display_cache() -> &'static Mutex> { + static CACHE: OnceLock>> = OnceLock::new(); + CACHE.get_or_init(|| Mutex::new(HashMap::new())) +} + +#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] +fn display_cache_key(raw_display_handle: RawDisplayHandle) -> Option { + match raw_display_handle { + RawDisplayHandle::Xlib(h) => h.display.map(|p| p.as_ptr() as usize), + RawDisplayHandle::Xcb(h) => h.connection.map(|p| p.as_ptr() as usize), + _ => None, + } +} + +#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] +fn get_or_build_gl_display( + raw_display_handle: RawDisplayHandle, + raw_window: Option, +) -> Display { + if let Some(key) = display_cache_key(raw_display_handle) { + let mut cache = display_cache().lock().unwrap(); + if let Some(d) = cache.get(&key) { + return d.clone(); + } + let display = build_gl_display(raw_display_handle, raw_window); + cache.insert(key, display.clone()); + return display; + } + build_gl_display(raw_display_handle, raw_window) +} + /// Pick an X11 visual ID compatible with the OpenGL backend used by [`SkiaWindowRenderer`]. /// /// Apply the returned visual to the winit window with [`WindowAttributesExtX11::with_x11_visual`] /// before creating the window. This avoids `EGL_BAD_MATCH` at surface creation, which happens /// when winit's default visual doesn't match any EGL config. /// -/// Returns `None` on non-X11 displays (Wayland, macOS, Windows) or if the platform's EGL -/// implementation doesn't expose an X11 visual ID for the picked config. +/// Returns `None` on non-Xlib/Xcb display handles, if no compatible EGL config can be +/// found, or if the platform's EGL implementation doesn't expose an X11 visual ID for the +/// picked config. /// /// [`WindowAttributesExtX11::with_x11_visual`]: https://docs.rs/winit/latest/winit/platform/x11/trait.WindowAttributesExtX11.html#tymethod.with_x11_visual #[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] @@ -74,8 +111,8 @@ pub fn pick_x11_gl_visual(raw_display_handle: RawDisplayHandle) -> Option { if !matches!(raw_display_handle, RawDisplayHandle::Xlib(_) | RawDisplayHandle::Xcb(_)) { return None; } - let display = build_gl_display(raw_display_handle, None); - let config = pick_gl_config(&display, None); + let display = get_or_build_gl_display(raw_display_handle, None); + let config = pick_gl_config(&display, None)?; use glutin::platform::x11::X11GlConfigExt; config.x11_visual().map(|v| v.visual_id() as u32) } @@ -97,8 +134,13 @@ impl OpenGLBackend { let raw_display_handle = window.display_handle().unwrap().as_raw(); let raw_window_handle = window.window_handle().unwrap().as_raw(); + #[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] + let gl_display = get_or_build_gl_display(raw_display_handle, Some(raw_window_handle)); + #[cfg(not(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android")))))] let gl_display = build_gl_display(raw_display_handle, Some(raw_window_handle)); - let gl_config = pick_gl_config(&gl_display, Some(raw_window_handle)); + + let gl_config = pick_gl_config(&gl_display, Some(raw_window_handle)) + .expect("no GL config found for display"); let gl_context_attrs = ContextAttributesBuilder::new().build(Some(raw_window_handle)); let gl_surface_attrs = SurfaceAttributesBuilder::::new().build( From 6bc5ee62903bec3da6ae7098d54f988b8e69da7b Mon Sep 17 00:00:00 2001 From: Tony Bierman Date: Sat, 6 Jun 2026 11:24:11 -0500 Subject: [PATCH 4/4] Fix rustfmt, collapsible_if, and broken intra-doc link for CI - wrap long cfg attributes per rustfmt - collapse nested if-lets into let-chains (clippy::collapsible_if, Rust 1.96) - link SkiaWindowRenderer doc reference via crate:: path so rustdoc resolves it Co-Authored-By: Claude Opus 4.8 --- crates/anyrender_skia/src/lib.rs | 5 +++- crates/anyrender_skia/src/opengl.rs | 41 +++++++++++++++++++++++------ examples/bunnymark/src/main.rs | 18 ++++++++----- examples/player/src/main.rs | 20 +++++++++----- 4 files changed, 62 insertions(+), 22 deletions(-) diff --git a/crates/anyrender_skia/src/lib.rs b/crates/anyrender_skia/src/lib.rs index 8407766..3974acd 100644 --- a/crates/anyrender_skia/src/lib.rs +++ b/crates/anyrender_skia/src/lib.rs @@ -15,5 +15,8 @@ pub use image_renderer::SkiaImageRenderer; pub use scene::{SkiaSceneCache, SkiaScenePainter}; pub use window_renderer::*; -#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] +#[cfg(all( + unix, + not(any(target_os = "macos", target_os = "ios", target_os = "android")) +))] pub use opengl::pick_x11_gl_visual; diff --git a/crates/anyrender_skia/src/opengl.rs b/crates/anyrender_skia/src/opengl.rs index cfa7514..be5344a 100644 --- a/crates/anyrender_skia/src/opengl.rs +++ b/crates/anyrender_skia/src/opengl.rs @@ -22,7 +22,10 @@ use skia_safe::{ use crate::window_renderer::SkiaBackend; -fn build_gl_display(raw_display_handle: RawDisplayHandle, _raw_window: Option) -> Display { +fn build_gl_display( + raw_display_handle: RawDisplayHandle, + _raw_window: Option, +) -> Display { unsafe { Display::new( raw_display_handle, @@ -63,13 +66,19 @@ fn pick_gl_config(display: &Display, raw_window: Option) -> Opt /// Cache of glutin `Display`s keyed by the raw X display/connection pointer, to avoid /// double-initializing EGL for the same X server connection (once in `pick_x11_gl_visual` /// and again in `OpenGLBackend::new`). -#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] +#[cfg(all( + unix, + not(any(target_os = "macos", target_os = "ios", target_os = "android")) +))] fn display_cache() -> &'static Mutex> { static CACHE: OnceLock>> = OnceLock::new(); CACHE.get_or_init(|| Mutex::new(HashMap::new())) } -#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] +#[cfg(all( + unix, + not(any(target_os = "macos", target_os = "ios", target_os = "android")) +))] fn display_cache_key(raw_display_handle: RawDisplayHandle) -> Option { match raw_display_handle { RawDisplayHandle::Xlib(h) => h.display.map(|p| p.as_ptr() as usize), @@ -78,7 +87,10 @@ fn display_cache_key(raw_display_handle: RawDisplayHandle) -> Option { } } -#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] +#[cfg(all( + unix, + not(any(target_os = "macos", target_os = "ios", target_os = "android")) +))] fn get_or_build_gl_display( raw_display_handle: RawDisplayHandle, raw_window: Option, @@ -105,10 +117,17 @@ fn get_or_build_gl_display( /// found, or if the platform's EGL implementation doesn't expose an X11 visual ID for the /// picked config. /// +/// [`SkiaWindowRenderer`]: crate::SkiaWindowRenderer /// [`WindowAttributesExtX11::with_x11_visual`]: https://docs.rs/winit/latest/winit/platform/x11/trait.WindowAttributesExtX11.html#tymethod.with_x11_visual -#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] +#[cfg(all( + unix, + not(any(target_os = "macos", target_os = "ios", target_os = "android")) +))] pub fn pick_x11_gl_visual(raw_display_handle: RawDisplayHandle) -> Option { - if !matches!(raw_display_handle, RawDisplayHandle::Xlib(_) | RawDisplayHandle::Xcb(_)) { + if !matches!( + raw_display_handle, + RawDisplayHandle::Xlib(_) | RawDisplayHandle::Xcb(_) + ) { return None; } let display = get_or_build_gl_display(raw_display_handle, None); @@ -134,9 +153,15 @@ impl OpenGLBackend { let raw_display_handle = window.display_handle().unwrap().as_raw(); let raw_window_handle = window.window_handle().unwrap().as_raw(); - #[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] + #[cfg(all( + unix, + not(any(target_os = "macos", target_os = "ios", target_os = "android")) + ))] let gl_display = get_or_build_gl_display(raw_display_handle, Some(raw_window_handle)); - #[cfg(not(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android")))))] + #[cfg(not(all( + unix, + not(any(target_os = "macos", target_os = "ios", target_os = "android")) + )))] let gl_display = build_gl_display(raw_display_handle, Some(raw_window_handle)); let gl_config = pick_gl_config(&gl_display, Some(raw_window_handle)) diff --git a/examples/bunnymark/src/main.rs b/examples/bunnymark/src/main.rs index 0761b2a..dec89b4 100644 --- a/examples/bunnymark/src/main.rs +++ b/examples/bunnymark/src/main.rs @@ -1,5 +1,8 @@ use anyrender::{PaintScene, WindowRenderer}; -#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] +#[cfg(all( + unix, + not(any(target_os = "macos", target_os = "ios", target_os = "android")) +))] use anyrender_skia::pick_x11_gl_visual; use anyrender_skia::{SkiaImageRenderer, SkiaWindowRenderer}; use anyrender_vello::VelloWindowRenderer; @@ -149,14 +152,17 @@ impl App { // On X11, pre-pick a visual that's compatible with the OpenGL backend's EGL // configs. winit otherwise inherits the root window's visual via COPY_FROM_PARENT, // which may have no matching EGL config and causes EGL_BAD_MATCH at surface creation. - #[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] + #[cfg(all( + unix, + not(any(target_os = "macos", target_os = "ios", target_os = "android")) + ))] { use winit::platform::x11::WindowAttributesExtX11; use winit::raw_window_handle::HasDisplayHandle; - if let Ok(display_handle) = event_loop.display_handle() { - if let Some(visual_id) = pick_x11_gl_visual(display_handle.as_raw()) { - attr = attr.with_x11_visual(visual_id); - } + if let Ok(display_handle) = event_loop.display_handle() + && let Some(visual_id) = pick_x11_gl_visual(display_handle.as_raw()) + { + attr = attr.with_x11_visual(visual_id); } } diff --git a/examples/player/src/main.rs b/examples/player/src/main.rs index 782c5ea..7b254ea 100644 --- a/examples/player/src/main.rs +++ b/examples/player/src/main.rs @@ -1,8 +1,11 @@ use anyrender::{NullWindowRenderer, PaintScene, Scene, WindowRenderer}; use anyrender_serialize::SceneArchive; -#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] -use anyrender_skia::pick_x11_gl_visual; use anyrender_skia::SkiaWindowRenderer; +#[cfg(all( + unix, + not(any(target_os = "macos", target_os = "ios", target_os = "android")) +))] +use anyrender_skia::pick_x11_gl_visual; use anyrender_vello::VelloWindowRenderer; use anyrender_vello_cpu::{PixelsWindowRenderer, SoftbufferWindowRenderer, VelloCpuImageRenderer}; use anyrender_vello_hybrid::VelloHybridWindowRenderer; @@ -143,14 +146,17 @@ impl App { // On X11, pre-pick a visual that's compatible with the OpenGL backend's EGL // configs. winit otherwise inherits the root window's visual via COPY_FROM_PARENT, // which may have no matching EGL config and causes EGL_BAD_MATCH at surface creation. - #[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))] + #[cfg(all( + unix, + not(any(target_os = "macos", target_os = "ios", target_os = "android")) + ))] { use winit::platform::x11::WindowAttributesExtX11; use winit::raw_window_handle::HasDisplayHandle; - if let Ok(display_handle) = event_loop.display_handle() { - if let Some(visual_id) = pick_x11_gl_visual(display_handle.as_raw()) { - attr = attr.with_x11_visual(visual_id); - } + if let Ok(display_handle) = event_loop.display_handle() + && let Some(visual_id) = pick_x11_gl_visual(display_handle.as_raw()) + { + attr = attr.with_x11_visual(visual_id); } }