Skip to content

Commit ee79685

Browse files
committed
[wgpu-hal] Allow importing external WGL contexts as with EGL
1 parent cf0ac22 commit ee79685

File tree

4 files changed

+92
-27
lines changed

4 files changed

+92
-27
lines changed

Cargo.lock

Lines changed: 12 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

wgpu-hal/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ env_logger.workspace = true
207207
glam.workspace = true # for ray-traced-triangle example
208208
winit.workspace = true # for "halmark" example
209209

210-
[target.'cfg(not(any(target_arch = "wasm32", windows, target_os = "ios")))'.dev-dependencies]
211-
glutin-winit = { workspace = true, features = ["egl"] } # for "raw-gles" example
212-
glutin = { workspace = true, features = ["egl"] } # for "raw-gles" example
210+
[target.'cfg(not(any(target_arch = "wasm32", target_os = "ios")))'.dev-dependencies]
211+
glutin-winit = { workspace = true, features = ["egl", "wgl"] } # for "raw-gles" example
212+
glutin = { workspace = true, features = ["egl", "wgl"] } # for "raw-gles" example
213213
rwh_05 = { version = "0.5", package = "raw-window-handle" } # temporary compatibility for glutin-winit in "raw-gles" example
214214
winit = { workspace = true, features = ["rwh_05"] } # for "raw-gles" example

wgpu-hal/examples/raw-gles.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
1111
extern crate wgpu_hal as hal;
1212

13-
#[cfg(not(any(windows, target_arch = "wasm32", target_os = "ios")))]
13+
#[cfg(not(any(target_arch = "wasm32", target_os = "ios")))]
1414
fn main() {
1515
use std::{ffi::CString, num::NonZeroU32};
1616

1717
use glutin::{
1818
config::GlConfig as _,
19-
context::{NotCurrentGlContext, PossiblyCurrentGlContext as _},
19+
context::{AsRawContext as _, NotCurrentGlContext, PossiblyCurrentGlContext as _},
2020
display::{GetGlDisplay, GlDisplay},
2121
surface::GlSurface as _,
2222
};
@@ -137,12 +137,22 @@ fn main() {
137137
println!("Hooking up to wgpu-hal");
138138
exposed.get_or_insert_with(|| {
139139
unsafe {
140-
<hal::api::Gles as hal::Api>::Adapter::new_external(|name| {
141-
// XXX: On WGL this should only be called after the context was made current
142-
gl_config
143-
.display()
144-
.get_proc_address(&CString::new(name).expect(name))
145-
})
140+
<hal::api::Gles as hal::Api>::Adapter::new_external(
141+
|name| {
142+
// XXX: On WGL this should only be called after the context was made current
143+
gl_config
144+
.display()
145+
.get_proc_address(&CString::new(name).expect(name))
146+
},
147+
#[cfg(windows)]
148+
if let glutin::context::RawContext::Wgl(context) =
149+
gl_context.raw_context()
150+
{
151+
context.cast_mut()
152+
} else {
153+
unreachable!()
154+
},
155+
)
146156
}
147157
.expect("GL adapter can't be initialized")
148158
});
@@ -254,7 +264,6 @@ fn main() {
254264
}
255265

256266
#[cfg(any(
257-
windows,
258267
all(target_arch = "wasm32", not(target_os = "emscripten")),
259268
target_os = "ios"
260269
))]
@@ -263,7 +272,6 @@ fn main() {
263272
}
264273

265274
#[cfg(not(any(
266-
windows,
267275
all(target_arch = "wasm32", not(target_os = "emscripten")),
268276
target_os = "ios"
269277
)))]

wgpu-hal/src/gles/wgl.rs

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
use glow::HasContext;
2-
use glutin_wgl_sys::wgl_extra::{
3-
Wgl, CONTEXT_CORE_PROFILE_BIT_ARB, CONTEXT_DEBUG_BIT_ARB, CONTEXT_FLAGS_ARB,
4-
CONTEXT_PROFILE_MASK_ARB,
5-
};
6-
use once_cell::sync::Lazy;
7-
use parking_lot::{Mutex, MutexGuard, RwLock};
8-
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
91
use std::{
102
collections::HashSet,
113
ffi::{c_void, CStr, CString},
@@ -19,6 +11,15 @@ use std::{
1911
thread,
2012
time::Duration,
2113
};
14+
15+
use glow::HasContext;
16+
use glutin_wgl_sys::wgl_extra::{
17+
Wgl, CONTEXT_CORE_PROFILE_BIT_ARB, CONTEXT_DEBUG_BIT_ARB, CONTEXT_FLAGS_ARB,
18+
CONTEXT_PROFILE_MASK_ARB,
19+
};
20+
use once_cell::sync::Lazy;
21+
use parking_lot::{Mutex, MutexGuard, RwLock};
22+
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
2223
use wgt::InstanceFlags;
2324
use windows::{
2425
core::{Error, PCSTR},
@@ -111,14 +112,20 @@ struct WglContext {
111112

112113
impl WglContext {
113114
fn make_current(&self, device: Gdi::HDC) -> windows::core::Result<()> {
114-
unsafe { OpenGL::wglMakeCurrent(device, self.context) }
115+
// TODO: Skip this for externally imported context? Otherwise use wglShareLists()
116+
println!("No current");
117+
Ok(())
118+
// unsafe { OpenGL::wglMakeCurrent(device, self.context) }
115119
}
116120

117121
fn unmake_current(&self) -> windows::core::Result<()> {
118-
if unsafe { OpenGL::wglGetCurrentContext() }.is_invalid() {
119-
return Ok(());
120-
}
121-
unsafe { OpenGL::wglMakeCurrent(None, None) }
122+
// TODO: Skip this for externally imported context?
123+
println!("No uncurrent");
124+
Ok(())
125+
// if unsafe { OpenGL::wglGetCurrentContext() }.is_invalid() {
126+
// return Ok(());
127+
// }
128+
// unsafe { OpenGL::wglMakeCurrent(None, None) }
122129
}
123130
}
124131

@@ -550,6 +557,45 @@ impl crate::Instance for Instance {
550557
}
551558
}
552559

560+
impl super::Adapter {
561+
/// Creates a new external adapter using the specified loader function.
562+
///
563+
/// # Safety
564+
///
565+
/// - The underlying OpenGL ES context must be current.
566+
/// - The underlying OpenGL ES context must be current when interfacing with any objects returned by
567+
/// wgpu-hal from this adapter.
568+
pub unsafe fn new_external(
569+
fun: impl FnMut(&str) -> *const c_void,
570+
// gl_context: OpenGL::HGLRC,
571+
gl_context: *mut c_void,
572+
) -> Option<crate::ExposedAdapter<super::Api>> {
573+
let context = unsafe { glow::Context::from_loader_function(fun) };
574+
unsafe {
575+
Self::expose(AdapterContext {
576+
inner: Arc::new(Mutex::new(Inner {
577+
gl: context,
578+
device: create_instance_device().ok()?,
579+
context: WglContext {
580+
context: OpenGL::HGLRC(gl_context),
581+
},
582+
})),
583+
})
584+
}
585+
}
586+
587+
pub fn adapter_context(&self) -> &AdapterContext {
588+
&self.shared.context
589+
}
590+
}
591+
592+
impl super::Device {
593+
/// Returns the underlying EGL context.
594+
pub fn context(&self) -> &AdapterContext {
595+
&self.shared.context
596+
}
597+
}
598+
553599
struct DeviceContextHandle {
554600
device: Gdi::HDC,
555601
window: Foundation::HWND,

0 commit comments

Comments
 (0)