From 9f34acd5671987558038ba0abeb24c69220bd581 Mon Sep 17 00:00:00 2001 From: teoxoy <28601907+teoxoy@users.noreply.github.com> Date: Wed, 3 Jul 2024 13:28:16 +0200 Subject: [PATCH] [wgpu-hal] return `None` in `Adapter.surface_capabilities()` if the `Surface` and the `Adapter` don't share the same WebGL2 context --- CHANGELOG.md | 3 +++ wgpu-hal/src/gles/adapter.rs | 5 +++++ wgpu-hal/src/gles/web.rs | 14 ++++++++++---- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3546f8e4a3..526f6f99c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -134,6 +134,9 @@ By @atlv24 in [#5383](https://github.com/gfx-rs/wgpu/pull/5383) When targeting WebGL2, it has always been the case that a surface had to be created before calling `request_adapter()`. We now make this requirement explicit. +Validation was also added to prevent configuring the surface with a device that doesn't share the same underlying +WebGL2 context since this has never worked. + Calling `enumerate_adapters()` when targeting WebGPU used to return an empty `Vec` and since we now require users to pass a compatible surface when targeting WebGL2, having `enumerate_adapters()` doesn't make sense. diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index 9a41dfe113..933c36dc82 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -1151,6 +1151,11 @@ impl crate::Adapter for super::Adapter { &self, surface: &super::Surface, ) -> Option { + #[cfg(webgl)] + if self.shared.context.webgl2_context != surface.webgl2_context { + return None; + } + if surface.presentable { let mut formats = vec![ wgt::TextureFormat::Rgba8Unorm, diff --git a/wgpu-hal/src/gles/web.rs b/wgpu-hal/src/gles/web.rs index a36710f648..a6c79721b4 100644 --- a/wgpu-hal/src/gles/web.rs +++ b/wgpu-hal/src/gles/web.rs @@ -8,6 +8,7 @@ use super::TextureFormatDesc; /// with the `AdapterContext` API from the EGL implementation. pub struct AdapterContext { pub glow_context: glow::Context, + pub webgl2_context: web_sys::WebGl2RenderingContext, } impl AdapterContext { @@ -124,9 +125,14 @@ impl crate::Instance for Instance { if let Some(surface_hint) = surface_hint { let gl = glow::Context::from_webgl2_context(surface_hint.webgl2_context.clone()); - unsafe { super::Adapter::expose(AdapterContext { glow_context: gl }) } - .into_iter() - .collect() + unsafe { + super::Adapter::expose(AdapterContext { + glow_context: gl, + webgl2_context: surface_hint.webgl2_context.clone(), + }) + } + .into_iter() + .collect() } else { Vec::new() } @@ -172,7 +178,7 @@ impl crate::Instance for Instance { #[derive(Debug)] pub struct Surface { canvas: Canvas, - webgl2_context: web_sys::WebGl2RenderingContext, + pub(super) webgl2_context: web_sys::WebGl2RenderingContext, pub(super) swapchain: RwLock>, texture: Mutex>, pub(super) presentable: bool,