mirror of
https://github.com/servo/servo.git
synced 2025-08-09 23:45:35 +01:00
libservo: Expose a ServoBuilder
(#36549)
Expose a `ServoBuilder` for easily creating Servo instances using default values. This change enables removing `EmbedderTraits`. Testing: This is covered by `Servo` unit tests. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
7a8e75266f
commit
d8a7abda69
17 changed files with 252 additions and 271 deletions
|
@ -2,11 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//! Abstract windowing methods. The concrete implementations of these can be found in `platform/`.
|
||||
|
||||
use embedder_traits::EventLoopWaker;
|
||||
use net::protocols::ProtocolRegistry;
|
||||
|
||||
/// Various debug and profiling flags that WebRender supports.
|
||||
#[derive(Clone)]
|
||||
pub enum WebRenderDebugOption {
|
||||
|
@ -14,23 +9,3 @@ pub enum WebRenderDebugOption {
|
|||
TextureCacheDebug,
|
||||
RenderTargetDebug,
|
||||
}
|
||||
|
||||
pub trait EmbedderMethods {
|
||||
/// Returns a thread-safe object to wake up the window's event loop.
|
||||
fn create_event_loop_waker(&mut self) -> Box<dyn EventLoopWaker>;
|
||||
|
||||
#[cfg(feature = "webxr")]
|
||||
/// Register services with a WebXR Registry.
|
||||
fn register_webxr(
|
||||
&mut self,
|
||||
_: &mut webxr::MainThreadRegistry,
|
||||
_: embedder_traits::EmbedderProxy,
|
||||
) {
|
||||
}
|
||||
|
||||
/// Returns the protocol handlers implemented by that embedder.
|
||||
/// They will be merged with the default internal ones.
|
||||
fn get_protocol_handlers(&self) -> ProtocolRegistry {
|
||||
ProtocolRegistry::default()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@ use std::cell::RefCell;
|
|||
use std::error::Error;
|
||||
use std::rc::Rc;
|
||||
|
||||
use compositing::windowing::EmbedderMethods;
|
||||
use euclid::{Scale, Size2D};
|
||||
use servo::{
|
||||
RenderingContext, Servo, TouchEventType, WebView, WebViewBuilder, WindowRenderingContext,
|
||||
RenderingContext, Servo, ServoBuilder, TouchEventType, WebView, WebViewBuilder,
|
||||
WindowRenderingContext,
|
||||
};
|
||||
use tracing::warn;
|
||||
use url::Url;
|
||||
|
@ -95,15 +95,9 @@ impl ApplicationHandler<WakerEvent> for App {
|
|||
|
||||
let _ = rendering_context.make_current();
|
||||
|
||||
let servo = Servo::new(
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
rendering_context.clone(),
|
||||
Box::new(EmbedderDelegate {
|
||||
waker: waker.clone(),
|
||||
}),
|
||||
Default::default(),
|
||||
);
|
||||
let servo = ServoBuilder::new(rendering_context.clone())
|
||||
.event_loop_waker(Box::new(waker.clone()))
|
||||
.build();
|
||||
servo.setup_logging();
|
||||
|
||||
let app_state = Rc::new(AppState {
|
||||
|
@ -204,19 +198,6 @@ impl ApplicationHandler<WakerEvent> for App {
|
|||
}
|
||||
}
|
||||
|
||||
struct EmbedderDelegate {
|
||||
waker: Waker,
|
||||
}
|
||||
|
||||
impl EmbedderMethods for EmbedderDelegate {
|
||||
// FIXME: rust-analyzer “Implement missing members” autocompletes this as
|
||||
// webxr_api::MainThreadWaker, which is not available when building without
|
||||
// libservo/webxr, and even if it was, it would fail to compile with E0053.
|
||||
fn create_event_loop_waker(&mut self) -> Box<dyn embedder_traits::EventLoopWaker> {
|
||||
Box::new(self.waker.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Waker(winit::event_loop::EventLoopProxy<WakerEvent>);
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -42,7 +42,6 @@ use canvas::WebGLComm;
|
|||
use canvas::canvas_paint_thread::CanvasPaintThread;
|
||||
use canvas_traits::webgl::{GlType, WebGLThreads};
|
||||
use clipboard_delegate::StringRequest;
|
||||
use compositing::windowing::EmbedderMethods;
|
||||
use compositing::{IOCompositor, InitialCompositorState};
|
||||
pub use compositing_traits::rendering_context::{
|
||||
OffscreenRenderingContext, RenderingContext, SoftwareRenderingContext, WindowRenderingContext,
|
||||
|
@ -247,26 +246,18 @@ impl webrender_api::RenderNotifier for RenderNotifier {
|
|||
impl Servo {
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(
|
||||
skip(preferences, rendering_context, embedder),
|
||||
fields(servo_profiling = true),
|
||||
level = "trace",
|
||||
)
|
||||
tracing::instrument(skip(builder), fields(servo_profiling = true), level = "trace",)
|
||||
)]
|
||||
pub fn new(
|
||||
opts: Opts,
|
||||
preferences: Preferences,
|
||||
rendering_context: Rc<dyn RenderingContext>,
|
||||
mut embedder: Box<dyn EmbedderMethods>,
|
||||
user_content_manager: UserContentManager,
|
||||
) -> Self {
|
||||
fn new(builder: ServoBuilder) -> Self {
|
||||
// Global configuration options, parsed from the command line.
|
||||
opts::set_options(opts);
|
||||
let opts = builder.opts.map(|opts| *opts);
|
||||
opts::set_options(opts.unwrap_or_default());
|
||||
let opts = opts::get();
|
||||
|
||||
// Set the preferences globally.
|
||||
// TODO: It would be better to make these private to a particular Servo instance.
|
||||
servo_config::prefs::set(preferences);
|
||||
let preferences = builder.preferences.map(|opts| *opts);
|
||||
servo_config::prefs::set(preferences.unwrap_or_default());
|
||||
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
|
@ -282,6 +273,7 @@ impl Servo {
|
|||
}
|
||||
|
||||
// Get GL bindings
|
||||
let rendering_context = builder.rendering_context;
|
||||
let webrender_gl = rendering_context.gleam_gl_api();
|
||||
|
||||
// Make sure the gl context is made current.
|
||||
|
@ -297,7 +289,7 @@ impl Servo {
|
|||
// the client window and the compositor. This channel is unique because
|
||||
// messages to client may need to pump a platform-specific event loop
|
||||
// to deliver the message.
|
||||
let event_loop_waker = embedder.create_event_loop_waker();
|
||||
let event_loop_waker = builder.event_loop_waker;
|
||||
let (compositor_proxy, compositor_receiver) =
|
||||
create_compositor_channel(event_loop_waker.clone());
|
||||
let (embedder_proxy, embedder_receiver) = create_embedder_channel(event_loop_waker.clone());
|
||||
|
@ -424,7 +416,7 @@ impl Servo {
|
|||
.expect("Failed to create WebXR device registry");
|
||||
#[cfg(feature = "webxr")]
|
||||
if pref!(dom_webxr_enabled) {
|
||||
embedder.register_webxr(&mut webxr_main_thread, embedder_proxy.clone());
|
||||
builder.webxr_registry.register(&mut webxr_main_thread);
|
||||
}
|
||||
|
||||
#[cfg(feature = "webgpu")]
|
||||
|
@ -447,7 +439,7 @@ impl Servo {
|
|||
// Create the constellation, which maintains the engine pipelines, including script and
|
||||
// layout, as well as the navigation context.
|
||||
let mut protocols = ProtocolRegistry::with_internal_protocols();
|
||||
protocols.merge(embedder.get_protocol_handlers());
|
||||
protocols.merge(builder.protocol_registry);
|
||||
|
||||
let constellation_chan = create_constellation(
|
||||
opts.config_dir.clone(),
|
||||
|
@ -465,7 +457,7 @@ impl Servo {
|
|||
#[cfg(feature = "webgpu")]
|
||||
wgpu_image_map,
|
||||
protocols,
|
||||
user_content_manager,
|
||||
builder.user_content_manager,
|
||||
);
|
||||
|
||||
if cfg!(feature = "webdriver") {
|
||||
|
@ -1204,3 +1196,77 @@ fn create_sandbox() {
|
|||
fn create_sandbox() {
|
||||
panic!("Sandboxing is not supported on Windows, iOS, ARM targets and android.");
|
||||
}
|
||||
|
||||
struct DefaultEventLoopWaker;
|
||||
|
||||
impl EventLoopWaker for DefaultEventLoopWaker {
|
||||
fn clone_box(&self) -> Box<dyn EventLoopWaker> {
|
||||
Box::new(DefaultEventLoopWaker)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "webxr")]
|
||||
struct DefaultWebXrRegistry;
|
||||
#[cfg(feature = "webxr")]
|
||||
impl webxr::WebXrRegistry for DefaultWebXrRegistry {}
|
||||
|
||||
pub struct ServoBuilder {
|
||||
rendering_context: Rc<dyn RenderingContext>,
|
||||
opts: Option<Box<Opts>>,
|
||||
preferences: Option<Box<Preferences>>,
|
||||
event_loop_waker: Box<dyn EventLoopWaker>,
|
||||
user_content_manager: UserContentManager,
|
||||
protocol_registry: ProtocolRegistry,
|
||||
#[cfg(feature = "webxr")]
|
||||
webxr_registry: Box<dyn webxr::WebXrRegistry>,
|
||||
}
|
||||
|
||||
impl ServoBuilder {
|
||||
pub fn new(rendering_context: Rc<dyn RenderingContext>) -> Self {
|
||||
Self {
|
||||
rendering_context,
|
||||
opts: None,
|
||||
preferences: None,
|
||||
event_loop_waker: Box::new(DefaultEventLoopWaker),
|
||||
user_content_manager: UserContentManager::default(),
|
||||
protocol_registry: ProtocolRegistry::default(),
|
||||
#[cfg(feature = "webxr")]
|
||||
webxr_registry: Box::new(DefaultWebXrRegistry),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build(self) -> Servo {
|
||||
Servo::new(self)
|
||||
}
|
||||
|
||||
pub fn opts(mut self, opts: Opts) -> Self {
|
||||
self.opts = Some(Box::new(opts));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn preferences(mut self, preferences: Preferences) -> Self {
|
||||
self.preferences = Some(Box::new(preferences));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn event_loop_waker(mut self, event_loop_waker: Box<dyn EventLoopWaker>) -> Self {
|
||||
self.event_loop_waker = event_loop_waker;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn user_content_manager(mut self, user_content_manager: UserContentManager) -> Self {
|
||||
self.user_content_manager = user_content_manager;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn protocol_registry(mut self, protocol_registry: ProtocolRegistry) -> Self {
|
||||
self.protocol_registry = protocol_registry;
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "webxr")]
|
||||
pub fn webxr_registry(mut self, webxr_registry: Box<dyn webxr::WebXrRegistry>) -> Self {
|
||||
self.webxr_registry = webxr_registry;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,13 +8,12 @@ use std::sync::{Arc, OnceLock};
|
|||
use std::time::Duration;
|
||||
|
||||
use anyhow::Error;
|
||||
use compositing::windowing::EmbedderMethods;
|
||||
use compositing_traits::rendering_context::{RenderingContext, SoftwareRenderingContext};
|
||||
use crossbeam_channel::{Receiver, Sender, unbounded};
|
||||
use dpi::PhysicalSize;
|
||||
use embedder_traits::EventLoopWaker;
|
||||
use parking_lot::Mutex;
|
||||
use servo::Servo;
|
||||
use servo::{Servo, ServoBuilder};
|
||||
|
||||
pub struct ServoTest {
|
||||
servo: Servo,
|
||||
|
@ -41,14 +40,6 @@ impl ServoTest {
|
|||
);
|
||||
assert!(rendering_context.make_current().is_ok());
|
||||
|
||||
#[derive(Clone)]
|
||||
struct EmbedderMethodsImpl(Arc<AtomicBool>);
|
||||
impl EmbedderMethods for EmbedderMethodsImpl {
|
||||
fn create_event_loop_waker(&mut self) -> Box<dyn embedder_traits::EventLoopWaker> {
|
||||
Box::new(EventLoopWakerImpl(self.0.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct EventLoopWakerImpl(Arc<AtomicBool>);
|
||||
impl EventLoopWaker for EventLoopWakerImpl {
|
||||
|
@ -62,13 +53,9 @@ impl ServoTest {
|
|||
}
|
||||
|
||||
let user_event_triggered = Arc::new(AtomicBool::new(false));
|
||||
let servo = Servo::new(
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
rendering_context.clone(),
|
||||
Box::new(EmbedderMethodsImpl(user_event_triggered)),
|
||||
Default::default(),
|
||||
);
|
||||
let servo = ServoBuilder::new(rendering_context.clone())
|
||||
.event_loop_waker(Box::new(EventLoopWakerImpl(user_event_triggered)))
|
||||
.build();
|
||||
Self { servo }
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ pub enum Cursor {
|
|||
|
||||
pub trait EventLoopWaker: 'static + Send {
|
||||
fn clone_box(&self) -> Box<dyn EventLoopWaker>;
|
||||
fn wake(&self);
|
||||
fn wake(&self) {}
|
||||
}
|
||||
|
||||
impl Clone for Box<dyn EventLoopWaker> {
|
||||
|
|
|
@ -26,6 +26,7 @@ openxr-api = ["angle", "openxr", "winapi", "wio", "surfman/sm-angle-default"]
|
|||
|
||||
[dependencies]
|
||||
crossbeam-channel = { workspace = true }
|
||||
embedder_traits = { workspace = true }
|
||||
euclid = { workspace = true }
|
||||
glow = { workspace = true }
|
||||
log = { workspace = true }
|
||||
|
|
|
@ -19,3 +19,8 @@ pub type MainThreadRegistry = webxr_api::MainThreadRegistry<surfman_layer_manage
|
|||
pub type Discovery = Box<dyn webxr_api::DiscoveryAPI<SurfmanGL>>;
|
||||
|
||||
pub(crate) mod gl_utils;
|
||||
|
||||
pub trait WebXrRegistry {
|
||||
/// Register services with a WebXR Registry.
|
||||
fn register(&self, _: &mut MainThreadRegistry) {}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue