diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:27 +0000 |
commit | 40a355a42d4a9444dc753c04c6608dade2f06a23 (patch) | |
tree | 871fc667d2de662f171103ce5ec067014ef85e61 /third_party/rust/wgpu-hal/src/gles/egl.rs | |
parent | Adding upstream version 124.0.1. (diff) | |
download | firefox-40a355a42d4a9444dc753c04c6608dade2f06a23.tar.xz firefox-40a355a42d4a9444dc753c04c6608dade2f06a23.zip |
Adding upstream version 125.0.1.upstream/125.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/wgpu-hal/src/gles/egl.rs')
-rw-r--r-- | third_party/rust/wgpu-hal/src/gles/egl.rs | 69 |
1 files changed, 53 insertions, 16 deletions
diff --git a/third_party/rust/wgpu-hal/src/gles/egl.rs b/third_party/rust/wgpu-hal/src/gles/egl.rs index aa985d8121..f4bfcf5487 100644 --- a/third_party/rust/wgpu-hal/src/gles/egl.rs +++ b/third_party/rust/wgpu-hal/src/gles/egl.rs @@ -1,7 +1,8 @@ use glow::HasContext; +use once_cell::sync::Lazy; use parking_lot::{Mutex, MutexGuard, RwLock}; -use std::{ffi, os::raw, ptr, rc::Rc, sync::Arc, time::Duration}; +use std::{collections::HashMap, ffi, os::raw, ptr, rc::Rc, sync::Arc, time::Duration}; /// The amount of time to wait while trying to obtain a lock to the adapter context const CONTEXT_LOCK_TIMEOUT_SECS: u64 = 1; @@ -50,16 +51,6 @@ type WlEglWindowResizeFun = unsafe extern "system" fn( type WlEglWindowDestroyFun = unsafe extern "system" fn(window: *const raw::c_void); -#[cfg(target_os = "android")] -extern "C" { - pub fn ANativeWindow_setBuffersGeometry( - window: *mut raw::c_void, - width: i32, - height: i32, - format: i32, - ) -> i32; -} - type EglLabel = *const raw::c_void; #[allow(clippy::upper_case_acronyms)] @@ -161,7 +152,7 @@ impl Drop for DisplayOwner { fn open_x_display() -> Option<DisplayOwner> { log::debug!("Loading X11 library to get the current display"); unsafe { - let library = libloading::Library::new("libX11.so").ok()?; + let library = find_library(&["libX11.so.6", "libX11.so"])?; let func: libloading::Symbol<XOpenDisplayFun> = library.get(b"XOpenDisplay").unwrap(); let result = func(ptr::null()); ptr::NonNull::new(result).map(|ptr| DisplayOwner { @@ -442,6 +433,45 @@ struct Inner { srgb_kind: SrgbFrameBufferKind, } +// Different calls to `eglGetPlatformDisplay` may return the same `Display`, making it a global +// state of all our `EglContext`s. This forces us to track the number of such context to prevent +// terminating the display if it's currently used by another `EglContext`. +static DISPLAYS_REFERENCE_COUNT: Lazy<Mutex<HashMap<usize, usize>>> = Lazy::new(Default::default); + +fn initialize_display( + egl: &EglInstance, + display: khronos_egl::Display, +) -> Result<(i32, i32), khronos_egl::Error> { + let mut guard = DISPLAYS_REFERENCE_COUNT.lock(); + *guard.entry(display.as_ptr() as usize).or_default() += 1; + + // We don't need to check the reference count here since according to the `eglInitialize` + // documentation, initializing an already initialized EGL display connection has no effect + // besides returning the version numbers. + egl.initialize(display) +} + +fn terminate_display( + egl: &EglInstance, + display: khronos_egl::Display, +) -> Result<(), khronos_egl::Error> { + let key = &(display.as_ptr() as usize); + let mut guard = DISPLAYS_REFERENCE_COUNT.lock(); + let count_ref = guard + .get_mut(key) + .expect("Attempted to decref a display before incref was called"); + + if *count_ref > 1 { + *count_ref -= 1; + + Ok(()) + } else { + guard.remove(key); + + egl.terminate(display) + } +} + impl Inner { fn create( flags: wgt::InstanceFlags, @@ -449,7 +479,7 @@ impl Inner { display: khronos_egl::Display, force_gles_minor_version: wgt::Gles3MinorVersion, ) -> Result<Self, crate::InstanceError> { - let version = egl.initialize(display).map_err(|e| { + let version = initialize_display(&egl, display).map_err(|e| { crate::InstanceError::with_source( String::from("failed to initialize EGL display connection"), e, @@ -618,7 +648,8 @@ impl Drop for Inner { { log::warn!("Error in destroy_context: {:?}", e); } - if let Err(e) = self.egl.instance.terminate(self.egl.display) { + + if let Err(e) = terminate_display(&self.egl.instance, self.egl.display) { log::warn!("Error in terminate: {:?}", e); } } @@ -783,11 +814,12 @@ impl crate::Instance<super::Api> for Instance { (display, Some(Rc::new(display_owner)), WindowKind::AngleX11) } else if client_ext_str.contains("EGL_MESA_platform_surfaceless") { log::warn!("No windowing system present. Using surfaceless platform"); + #[allow(clippy::unnecessary_literal_unwrap)] // This is only a literal on Emscripten let egl = egl1_5.expect("Failed to get EGL 1.5 for surfaceless"); let display = unsafe { egl.get_platform_display( EGL_PLATFORM_SURFACELESS_MESA, - std::ptr::null_mut(), + khronos_egl::DEFAULT_DISPLAY, &[khronos_egl::ATTRIB_NONE], ) } @@ -863,7 +895,12 @@ impl crate::Instance<super::Api> for Instance { .unwrap(); let ret = unsafe { - ANativeWindow_setBuffersGeometry(handle.a_native_window.as_ptr(), 0, 0, format) + ndk_sys::ANativeWindow_setBuffersGeometry( + handle.a_native_window.as_ptr() as *mut ndk_sys::ANativeWindow, + 0, + 0, + format, + ) }; if ret != 0 { |