aboutsummaryrefslogtreecommitdiffstats
path: root/ports/servoshell
diff options
context:
space:
mode:
authorNgo Iok Ui (Wu Yu Wei) <yuweiwu@pm.me>2025-01-03 12:01:30 +0900
committerGitHub <noreply@github.com>2025-01-03 03:01:30 +0000
commitda2074e5d639926fb5462f404243f6bb053d1b3f (patch)
tree882a06ca3045985ccdf9208e161db8f8e4d81b55 /ports/servoshell
parentb252f238d1c66470a2a0d759f3df3a40504fd0e2 (diff)
downloadservo-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.rs27
-rw-r--r--ports/servoshell/desktop/events_loop.rs48
-rw-r--r--ports/servoshell/desktop/headed_window.rs13
-rw-r--r--ports/servoshell/desktop/headless_window.rs23
-rw-r--r--ports/servoshell/desktop/window_trait.rs4
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>);