diff options
author | Ngo Iok Ui (Wu Yu Wei) <yuweiwu@pm.me> | 2025-01-03 12:01:30 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-03 03:01:30 +0000 |
commit | da2074e5d639926fb5462f404243f6bb053d1b3f (patch) | |
tree | 882a06ca3045985ccdf9208e161db8f8e4d81b55 /ports/servoshell | |
parent | b252f238d1c66470a2a0d759f3df3a40504fd0e2 (diff) | |
download | servo-da2074e5d639926fb5462f404243f6bb053d1b3f.tar.gz servo-da2074e5d639926fb5462f404243f6bb053d1b3f.zip |
webxr: create glwindow with Rc window and without rendering context (#34813)
* Create webxr glwindow with Rc window
Signed-off-by: Wu Yu Wei <yuweiwu@pm.me>
* Remove obselte gurad type
Signed-off-by: Wu Yu Wei <yuweiwu@pm.me>
* Update GlWindow trait method
Signed-off-by: Wu Yuwei <yuweiwu@pm.me>
* Update how webxr discorvery is created
Now glwindow will create a hidden window. It's better to not use it
unless we really want to use this port.
Signed-off-by: Wu Yu Wei <yuweiwu@pm.me>
* Link back to upstream webxr repo
Signed-off-by: Wu Yu Wei <yuweiwu@pm.me>
---------
Signed-off-by: Wu Yu Wei <yuweiwu@pm.me>
Signed-off-by: Wu Yuwei <yuweiwu@pm.me>
Diffstat (limited to 'ports/servoshell')
-rw-r--r-- | ports/servoshell/desktop/app.rs | 27 | ||||
-rw-r--r-- | ports/servoshell/desktop/events_loop.rs | 48 | ||||
-rw-r--r-- | ports/servoshell/desktop/headed_window.rs | 13 | ||||
-rw-r--r-- | ports/servoshell/desktop/headless_window.rs | 23 | ||||
-rw-r--r-- | ports/servoshell/desktop/window_trait.rs | 4 |
5 files changed, 20 insertions, 95 deletions
diff --git a/ports/servoshell/desktop/app.rs b/ports/servoshell/desktop/app.rs index 606c3ee9bac..b65d495ee50 100644 --- a/ports/servoshell/desktop/app.rs +++ b/ports/servoshell/desktop/app.rs @@ -30,12 +30,11 @@ use winit::event::WindowEvent; use winit::event_loop::{ActiveEventLoop, ControlFlow}; use winit::window::WindowId; -use super::events_loop::{EventLoopGuard, EventsLoop, WakerEvent}; +use super::events_loop::{EventsLoop, WakerEvent}; use super::minibrowser::Minibrowser; use super::webview::WebViewManager; use super::{headed_window, headless_window}; use crate::desktop::embedder::{EmbedderCallbacks, XrDiscovery}; -use crate::desktop::events_loop::with_current_event_loop; use crate::desktop::tracing::trace_winit_event; use crate::desktop::window_trait::WindowPortsMethods; use crate::parser::get_default_url; @@ -172,7 +171,7 @@ impl App { self.event_queue.push(EmbedderEvent::Idle); let (_, window) = self.windows.iter().next().unwrap(); - let openxr_discovery = if pref!(dom.webxr.openxr.enabled) && !opts::get().headless { + let xr_discovery = if pref!(dom.webxr.openxr.enabled) && !opts::get().headless { #[cfg(target_os = "windows")] let openxr = { let app_info = AppInfo::new("Servoshell", 0, "Servo", 0); @@ -182,28 +181,13 @@ impl App { let openxr = None; openxr + } else if pref!(dom.webxr.glwindow.enabled) && !opts::get().headless { + let window = window.new_glwindow(event_loop.unwrap()); + Some(XrDiscovery::GlWindow(GlWindowDiscovery::new(window))) } else { None }; - let glwindow_discovery = if pref!(dom.webxr.glwindow.enabled) && !opts::get().headless { - let window = window.clone(); - let factory = Box::new(move || { - with_current_event_loop(|w| Ok(window.new_glwindow(w))) - .expect("An event loop should always be active in headed mode") - }); - Some(XrDiscovery::GlWindow(GlWindowDiscovery::new( - rendering_context.connection(), - rendering_context.adapter(), - rendering_context.context_attributes(), - factory, - ))) - } else { - None - }; - - let xr_discovery = openxr_discovery.or(glwindow_discovery); - let window = window.clone(); // Implements embedder methods, used by libservo and constellation. let embedder = Box::new(EmbedderCallbacks::new(self.waker.clone(), xr_discovery)); @@ -423,7 +407,6 @@ impl App { impl ApplicationHandler<WakerEvent> for App { fn resumed(&mut self, event_loop: &ActiveEventLoop) { - let _guard = EventLoopGuard::new(event_loop); self.init(Some(event_loop)); } diff --git a/ports/servoshell/desktop/events_loop.rs b/ports/servoshell/desktop/events_loop.rs index 118de1ae99c..7dc7b803f56 100644 --- a/ports/servoshell/desktop/events_loop.rs +++ b/ports/servoshell/desktop/events_loop.rs @@ -4,7 +4,6 @@ //! An event loop implementation that works in headless mode. -use std::cell::Cell; use std::sync::{Arc, Condvar, Mutex}; use std::time; @@ -12,7 +11,7 @@ use log::warn; use servo::config::{pref, set_pref}; use servo::embedder_traits::EventLoopWaker; use winit::error::EventLoopError; -use winit::event_loop::{ActiveEventLoop, EventLoop as WinitEventLoop}; +use winit::event_loop::EventLoop as WinitEventLoop; #[cfg(target_os = "macos")] use winit::platform::macos::{ActivationPolicy, EventLoopBuilderExtMacOS}; @@ -164,48 +163,3 @@ impl EventLoopWaker for HeadlessEventLoopWaker { Box::new(HeadlessEventLoopWaker(self.0.clone())) } } - -thread_local! { - static CURRENT_EVENT_LOOP: Cell<Option<*const ActiveEventLoop>> = const { Cell::new(None) }; -} - -pub struct EventLoopGuard; - -impl EventLoopGuard { - pub fn new(event_loop: &ActiveEventLoop) -> Self { - CURRENT_EVENT_LOOP.with(|cell| { - assert!( - cell.get().is_none(), - "Attempted to set a new event loop while one is already set" - ); - cell.set(Some(event_loop as *const ActiveEventLoop)); - }); - Self - } -} - -impl Drop for EventLoopGuard { - fn drop(&mut self) { - CURRENT_EVENT_LOOP.with(|cell| cell.set(None)); - } -} - -// Helper function to safely use the current event loop -#[allow(unsafe_code)] -pub fn with_current_event_loop<F, R>(f: F) -> Option<R> -where - F: FnOnce(&ActiveEventLoop) -> R, -{ - CURRENT_EVENT_LOOP.with(|cell| { - cell.get().map(|ptr| { - // SAFETY: - // 1. The pointer is guaranteed to be valid when it's Some, as the EventLoopGuard that created it - // lives at least as long as the reference, and clears it when it's dropped. Only run_forever creates - // a new EventLoopGuard, and does not leak it. - // 2. Since the pointer was created from a borrow which lives at least as long as this pointer there are - // no mutable references to the ActiveEventLoop. - let event_loop = unsafe { &*ptr }; - f(event_loop) - }) - }) -} diff --git a/ports/servoshell/desktop/headed_window.rs b/ports/servoshell/desktop/headed_window.rs index 11b95191655..14f322d67a5 100644 --- a/ports/servoshell/desktop/headed_window.rs +++ b/ports/servoshell/desktop/headed_window.rs @@ -10,7 +10,7 @@ use std::rc::Rc; use euclid::{Angle, Length, Point2D, Rotation3D, Scale, Size2D, UnknownUnit, Vector2D, Vector3D}; use log::{debug, info, trace}; -use raw_window_handle::HasWindowHandle; +use raw_window_handle::{HasDisplayHandle, HasWindowHandle}; use servo::compositing::windowing::{ AnimationState, EmbedderCoordinates, EmbedderEvent, MouseWindowEvent, WindowMethods, }; @@ -498,13 +498,13 @@ impl WindowPortsMethods for Window { fn new_glwindow( &self, event_loop: &winit::event_loop::ActiveEventLoop, - ) -> Box<dyn webxr::glwindow::GlWindow> { + ) -> Rc<dyn webxr::glwindow::GlWindow> { let size = self.winit_window.outer_size(); let window_attr = winit::window::Window::default_attributes() .with_title("Servo XR".to_string()) .with_inner_size(size) - .with_visible(true); + .with_visible(false); let winit_window = event_loop .create_window(window_attr) @@ -515,7 +515,7 @@ impl WindowPortsMethods for Window { xr_translation: Cell::new(Vector3D::zero()), }); self.xr_window_poses.borrow_mut().push(pose.clone()); - Box::new(XRWindow { winit_window, pose }) + Rc::new(XRWindow { winit_window, pose }) } fn winit_window(&self) -> Option<&winit::window::Window> { @@ -602,6 +602,7 @@ impl webxr::glwindow::GlWindow for XRWindow { device: &mut Device, _context: &mut Context, ) -> webxr::glwindow::GlWindowRenderTarget { + self.winit_window.set_visible(true); let window_handle = self .winit_window .window_handle() @@ -636,6 +637,10 @@ impl webxr::glwindow::GlWindow for XRWindow { webxr::glwindow::GlWindowMode::Blit } } + + fn display_handle(&self) -> raw_window_handle::DisplayHandle { + self.winit_window.display_handle().unwrap() + } } impl XRWindowPose { diff --git a/ports/servoshell/desktop/headless_window.rs b/ports/servoshell/desktop/headless_window.rs index fc4412197b6..cb9aecb909d 100644 --- a/ports/servoshell/desktop/headless_window.rs +++ b/ports/servoshell/desktop/headless_window.rs @@ -9,14 +9,13 @@ use std::rc::Rc; use std::sync::RwLock; use euclid::num::Zero; -use euclid::{Box2D, Length, Point2D, Rotation3D, Scale, Size2D, UnknownUnit, Vector3D}; +use euclid::{Box2D, Length, Point2D, Scale, Size2D}; use servo::compositing::windowing::{ AnimationState, EmbedderCoordinates, EmbedderEvent, WindowMethods, }; use servo::config::opts; use servo::servo_geometry::DeviceIndependentPixel; use servo::webrender_api::units::{DeviceIntSize, DevicePixel}; -use surfman::{Context, Device}; use crate::desktop::window_trait::WindowPortsMethods; @@ -124,7 +123,7 @@ impl WindowPortsMethods for Window { fn new_glwindow( &self, _events_loop: &winit::event_loop::ActiveEventLoop, - ) -> Box<dyn webxr::glwindow::GlWindow> { + ) -> Rc<dyn webxr::glwindow::GlWindow> { unimplemented!() } @@ -158,21 +157,3 @@ impl WindowMethods for Window { self.animation_state.set(state); } } - -impl webxr::glwindow::GlWindow for Window { - fn get_render_target( - &self, - _device: &mut Device, - _context: &mut Context, - ) -> webxr::glwindow::GlWindowRenderTarget { - unimplemented!() - } - - fn get_rotation(&self) -> Rotation3D<f32, UnknownUnit, UnknownUnit> { - Rotation3D::identity() - } - - fn get_translation(&self) -> Vector3D<f32, UnknownUnit> { - Vector3D::zero() - } -} diff --git a/ports/servoshell/desktop/window_trait.rs b/ports/servoshell/desktop/window_trait.rs index fb528705cbe..030fa112056 100644 --- a/ports/servoshell/desktop/window_trait.rs +++ b/ports/servoshell/desktop/window_trait.rs @@ -5,6 +5,8 @@ //! Definition of Window. //! Implemented by headless and headed windows. +use std::rc::Rc; + use euclid::{Length, Scale}; use servo::compositing::windowing::{EmbedderEvent, WindowMethods}; use servo::config::opts; @@ -41,7 +43,7 @@ pub trait WindowPortsMethods: WindowMethods { fn new_glwindow( &self, event_loop: &winit::event_loop::ActiveEventLoop, - ) -> Box<dyn webxr::glwindow::GlWindow>; + ) -> Rc<dyn webxr::glwindow::GlWindow>; fn winit_window(&self) -> Option<&winit::window::Window>; fn toolbar_height(&self) -> Length<f32, DeviceIndependentPixel>; fn set_toolbar_height(&self, height: Length<f32, DeviceIndependentPixel>); |