From 24b8408916c3771d67c2bf17f99f728c72f307f4 Mon Sep 17 00:00:00 2001 From: glowe Date: Mon, 21 Oct 2019 22:43:47 -0400 Subject: [PATCH 1/4] Remove some global options access within glutin Removed opts::get() access for the two glutin specific options: angle and disable-vsync. This is the first step in a refactoring to separate these two options from the global options. --- ports/glutin/app.rs | 24 +++++++++++++++++------- ports/glutin/embedder.rs | 23 +++++++++++++++++------ ports/glutin/headed_window.rs | 12 ++++++++++-- ports/glutin/main2.rs | 2 +- ports/libsimpleservo/api/src/lib.rs | 1 + 5 files changed, 46 insertions(+), 16 deletions(-) diff --git a/ports/glutin/app.rs b/ports/glutin/app.rs index 77bd3eb41dc..d5371bf1e93 100644 --- a/ports/glutin/app.rs +++ b/ports/glutin/app.rs @@ -6,8 +6,8 @@ use crate::browser::Browser; use crate::embedder::EmbedderCallbacks; -use crate::window_trait::WindowPortsMethods; use crate::events_loop::EventsLoop; +use crate::window_trait::WindowPortsMethods; use crate::{headed_window, headless_window}; use glutin::WindowId; use servo::compositing::windowing::WindowEvent; @@ -34,14 +34,20 @@ pub struct App { } impl App { - pub fn run() { + pub fn run(angle: bool, enable_vsync: bool) { let events_loop = EventsLoop::new(opts::get().headless); // Implements window methods, used by compositor. let window = if opts::get().headless { headless_window::Window::new(opts::get().initial_window_size) } else { - Rc::new(headed_window::Window::new(opts::get().initial_window_size, None, events_loop.clone())) + Rc::new(headed_window::Window::new( + opts::get().initial_window_size, + None, + events_loop.clone(), + angle, + enable_vsync, + )) }; // Implements embedder methods, used by libservo and constellation. @@ -49,6 +55,7 @@ impl App { window.clone(), events_loop.clone(), window.gl(), + angle, )); // Handle browser state. @@ -110,7 +117,7 @@ impl App { }; window.winit_event_to_servo_event(event); return cont; - } + }, } }); }, @@ -121,7 +128,10 @@ impl App { fn run_loop(self) { loop { let animating = WINDOWS.with(|windows| { - windows.borrow().iter().any(|(_, window)| window.is_animating()) + windows + .borrow() + .iter() + .any(|(_, window)| window.is_animating()) }); if !animating || self.suspended.get() { // If there's no animations running then we block on the window event loop. @@ -219,8 +229,8 @@ pub fn register_window(window: Rc) { }); } -pub fn gl_version() -> glutin::GlRequest { - if opts::get().angle { +pub fn gl_version(angle: bool) -> glutin::GlRequest { + if angle { glutin::GlRequest::Specific(glutin::Api::OpenGlEs, (3, 0)) } else { glutin::GlRequest::GlThenGles { diff --git a/ports/glutin/embedder.rs b/ports/glutin/embedder.rs index fcebdd4d859..678ecdd8064 100644 --- a/ports/glutin/embedder.rs +++ b/ports/glutin/embedder.rs @@ -9,8 +9,8 @@ use crate::events_loop::EventsLoop; use crate::window_trait::WindowPortsMethods; use gleam::gl; use glutin; -use glutin::EventsLoopClosed; use glutin::dpi::LogicalSize; +use glutin::EventsLoopClosed; use rust_webvr::GlWindowVRService; use servo::compositing::windowing::EmbedderMethods; use servo::embedder_traits::EventLoopWaker; @@ -24,15 +24,22 @@ pub struct EmbedderCallbacks { window: Rc, events_loop: Rc>, gl: Rc, + angle: bool, } impl EmbedderCallbacks { pub fn new( window: Rc, events_loop: Rc>, - gl: Rc + gl: Rc, + angle: bool, ) -> EmbedderCallbacks { - EmbedderCallbacks { window, events_loop, gl } + EmbedderCallbacks { + window, + events_loop, + gl, + angle, + } } } @@ -55,7 +62,10 @@ impl EmbedderMethods for EmbedderCallbacks { let size = LogicalSize::new(size.width, size.height); let events_loop_clone = self.events_loop.clone(); let events_loop_factory = Box::new(move || { - events_loop_clone.borrow_mut().take().ok_or(EventsLoopClosed) + events_loop_clone + .borrow_mut() + .take() + .ok_or(EventsLoopClosed) }); let window_builder = glutin::WindowBuilder::new() .with_title(name.clone()) @@ -63,12 +73,13 @@ impl EmbedderMethods for EmbedderCallbacks { .with_visibility(false) .with_multitouch(); let context = glutin::ContextBuilder::new() - .with_gl(app::gl_version()) + .with_gl(app::gl_version(self.angle)) .with_vsync(false) // Assume the browser vsync is the same as the test VR window vsync .build_windowed(window_builder, &*self.events_loop.borrow().as_winit()) .expect("Failed to create window."); let gl = self.gl.clone(); - let (service, heartbeat) = GlWindowVRService::new(name, context, events_loop_factory, gl); + let (service, heartbeat) = + GlWindowVRService::new(name, context, events_loop_factory, gl); services.register(Box::new(service)); heartbeats.push(Box::new(heartbeat)); diff --git a/ports/glutin/headed_window.rs b/ports/glutin/headed_window.rs index f8e54149863..37af152a2a2 100644 --- a/ports/glutin/headed_window.rs +++ b/ports/glutin/headed_window.rs @@ -71,6 +71,8 @@ pub struct Window { fullscreen: Cell, gl: Rc, xr_rotation: Cell>, + angle: bool, + enable_vsync: bool, } #[cfg(not(target_os = "windows"))] @@ -90,6 +92,8 @@ impl Window { win_size: Size2D, sharing: Option<&Window>, events_loop: Rc>, + angle: bool, + enable_vsync: bool, ) -> Window { let opts = opts::get(); @@ -114,8 +118,8 @@ impl Window { window_builder = builder_with_platform_options(window_builder); let mut context_builder = glutin::ContextBuilder::new() - .with_gl(app::gl_version()) - .with_vsync(opts.enable_vsync); + .with_gl(app::gl_version(angle)) + .with_vsync(enable_vsync); if opts.use_msaa { context_builder = context_builder.with_multisampling(MULTISAMPLES) @@ -198,6 +202,8 @@ impl Window { primary_monitor, screen_size, xr_rotation: Cell::new(Rotation3D::identity()), + angle, + enable_vsync, }; window.present(); @@ -545,6 +551,8 @@ impl webxr::glwindow::GlWindow for Window { self.inner_size.get(), Some(self), self.events_loop.clone(), + self.angle, + self.enable_vsync, )); app::register_window(window.clone()); Ok(window) diff --git a/ports/glutin/main2.rs b/ports/glutin/main2.rs index 579c97d3a23..733a16036e6 100644 --- a/ports/glutin/main2.rs +++ b/ports/glutin/main2.rs @@ -128,7 +128,7 @@ pub fn main() { process::exit(0); } - App::run(); + App::run(opts::get().angle, opts::get().enable_vsync); platform::deinit() } diff --git a/ports/libsimpleservo/api/src/lib.rs b/ports/libsimpleservo/api/src/lib.rs index a68cea55dbc..8f4d314932b 100644 --- a/ports/libsimpleservo/api/src/lib.rs +++ b/ports/libsimpleservo/api/src/lib.rs @@ -9,6 +9,7 @@ pub mod gl_glue; pub use servo::script_traits::MouseButton; +use getopts::Options; use servo::compositing::windowing::{ AnimationState, EmbedderCoordinates, EmbedderMethods, MouseWindowEvent, WindowEvent, WindowMethods, From 6eca38aea3178e99f2f97dda5e4d257244a01fad Mon Sep 17 00:00:00 2001 From: glowe Date: Tue, 22 Oct 2019 19:28:03 -0400 Subject: [PATCH 2/4] Make angle and disable-vsync embedder options The angle and disable-vsync options were declared as global options but only used in the Glutin embedding for desktop builds. Moving them to the Glutin embedding code makes them easier to update. Partially fixes #23009 --- Cargo.lock | 2 ++ components/config/opts.rs | 36 +++++--------------------- ports/glutin/Cargo.toml | 1 + ports/glutin/main2.rs | 39 +++++++++++++++++++++-------- ports/libmlservo/Cargo.toml | 1 + ports/libsimpleservo/api/src/lib.rs | 2 +- 6 files changed, 40 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f791057f5c..15c435e6eba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2673,6 +2673,7 @@ dependencies = [ name = "libmlservo" version = "0.0.1" dependencies = [ + "getopts", "libc", "libservo", "log", @@ -4406,6 +4407,7 @@ dependencies = [ "cc", "clipboard", "euclid", + "getopts", "gleam 0.6.18", "glutin", "image", diff --git a/components/config/opts.rs b/components/config/opts.rs index ffc557c0a46..2e2cb20a45f 100644 --- a/components/config/opts.rs +++ b/components/config/opts.rs @@ -7,7 +7,7 @@ use crate::prefs::{self, PrefValue}; use euclid::Size2D; -use getopts::Options; +use getopts::{Matches, Options}; use servo_geometry::DeviceIndependentPixel; use servo_url::ServoUrl; use std::borrow::Cow; @@ -78,9 +78,6 @@ pub struct Opts { pub headless: bool, - /// Use ANGLE to create the GL context (Windows-only). - pub angle: bool, - /// True to exit on thread failure instead of displaying about:failure. pub hard_fail: bool, @@ -187,9 +184,6 @@ pub struct Opts { /// Do not use native titlebar pub no_native_titlebar: bool, - /// Enable vsync in the compositor - pub enable_vsync: bool, - /// True to show webrender profiling stats on screen. pub webrender_stats: bool, @@ -314,9 +308,6 @@ pub struct DebugOptions { /// Load web fonts synchronously to avoid non-deterministic network-driven reflows. pub load_webfonts_synchronously: bool, - /// Disable vsync in the compositor - pub disable_vsync: bool, - /// Show webrender profiling stats on screen. pub webrender_stats: bool, @@ -368,7 +359,6 @@ impl DebugOptions { "replace-surrogates" => self.replace_surrogates = true, "gc-profile" => self.gc_profile = true, "load-webfonts-synchronously" => self.load_webfonts_synchronously = true, - "disable-vsync" => self.disable_vsync = true, "wr-stats" => self.webrender_stats = true, "wr-record" => self.webrender_record = true, "wr-no-batch" => self.webrender_disable_batch = true, @@ -462,10 +452,6 @@ fn print_debug_usage(app: &str) -> ! { "load-webfonts-synchronously", "Load web fonts synchronously to avoid non-deterministic network-driven reflows", ); - print_option( - "disable-vsync", - "Disable vsync mode in the compositor to allow profiling at more than monitor refresh rate", - ); print_option("wr-stats", "Show WebRender profiler on screen."); print_option("msaa", "Use multisample antialiasing in WebRender."); print_option("full-backtraces", "Print full backtraces for all errors"); @@ -564,7 +550,6 @@ pub fn default_opts() -> Opts { gc_profile: false, load_webfonts_synchronously: false, headless: false, - angle: false, hard_fail: true, bubble_inline_sizes_separately: false, show_debug_fragment_borders: false, @@ -595,7 +580,6 @@ pub fn default_opts() -> Opts { convert_mouse_to_touch: false, exit_after_load: false, no_native_titlebar: false, - enable_vsync: true, webrender_stats: false, use_msaa: false, config_dir: None, @@ -613,10 +597,9 @@ pub fn default_opts() -> Opts { } } -pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { +pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingResult { let (app_name, args) = args.split_first().unwrap(); - let mut opts = Options::new(); opts.optflag("c", "cpu", "CPU painting"); opts.optflag("g", "gpu", "GPU painting"); opts.optopt("o", "output", "Output file", "output.png"); @@ -673,11 +656,6 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { "", ); opts.optflag("z", "headless", "Headless mode"); - opts.optflag( - "", - "angle", - "Use ANGLE to create a GL context (Windows-only)", - ); opts.optflag( "f", "hard-fail", @@ -793,7 +771,7 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { // some dummy options for now. if let Some(content_process) = opt_match.opt_str("content-process") { MULTIPROCESS.store(true, Ordering::SeqCst); - return ArgumentParsingResult::ContentProcess(content_process); + return ArgumentParsingResult::ContentProcess(opt_match, content_process); } let mut debug_options = DebugOptions::default(); @@ -1010,7 +988,6 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { gc_profile: debug_options.gc_profile, load_webfonts_synchronously: debug_options.load_webfonts_synchronously, headless: opt_match.opt_present("z"), - angle: opt_match.opt_present("angle"), hard_fail: opt_match.opt_present("f") && !opt_match.opt_present("F"), bubble_inline_sizes_separately: bubble_inline_sizes_separately, profile_script_events: debug_options.profile_script_events, @@ -1041,7 +1018,6 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { convert_mouse_to_touch: debug_options.convert_mouse_to_touch, exit_after_load: opt_match.opt_present("x"), no_native_titlebar: do_not_use_native_titlebar, - enable_vsync: !debug_options.disable_vsync, webrender_stats: debug_options.webrender_stats, use_msaa: debug_options.use_msaa, config_dir: opt_match.opt_str("config-dir").map(Into::into), @@ -1074,12 +1050,12 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { set_pref!(layout.threads, layout_threads as i64); } - ArgumentParsingResult::ChromeProcess + return ArgumentParsingResult::ChromeProcess(opt_match); } pub enum ArgumentParsingResult { - ChromeProcess, - ContentProcess(String), + ChromeProcess(Matches), + ContentProcess(Matches, String), } // Make Opts available globally. This saves having to clone and pass diff --git a/ports/glutin/Cargo.toml b/ports/glutin/Cargo.toml index a9f786e7f54..3b490d73e30 100644 --- a/ports/glutin/Cargo.toml +++ b/ports/glutin/Cargo.toml @@ -49,6 +49,7 @@ vslatestinstalled = ["libservo/vslatestinstalled"] backtrace = "0.3" clipboard = "0.5" euclid = "0.20" +getopts = "0.2.11" gleam = "0.6" glutin = "0.21.0" keyboard-types = "0.4.3" diff --git a/ports/glutin/main2.rs b/ports/glutin/main2.rs index 733a16036e6..e0224e64daa 100644 --- a/ports/glutin/main2.rs +++ b/ports/glutin/main2.rs @@ -24,6 +24,7 @@ mod window_trait; use app::App; use backtrace::Backtrace; +use getopts::Options; use servo::config::opts::{self, ArgumentParsingResult}; use servo::config::servo_version; use std::env; @@ -76,16 +77,32 @@ pub fn main() { // Parse the command line options and store them globally let args: Vec = env::args().collect(); - let opts_result = opts::from_cmdline_args(&args); + let mut opts = Options::new(); + opts.optflag( + "", + "angle", + "Use ANGLE to create a GL context (Windows-only)", + ); + opts.optflag( + "", + "disable-vsync", + "Disable vsync mode in the compositor to allow profiling at more than monitor refresh rate", + ); - let content_process_token = if let ArgumentParsingResult::ContentProcess(token) = opts_result { - Some(token) - } else { - if opts::get().is_running_problem_test && env::var("RUST_LOG").is_err() { - env::set_var("RUST_LOG", "compositing::constellation"); - } - - None + let opts_matches; + let content_process_token; + match opts::from_cmdline_args(opts, &args) { + ArgumentParsingResult::ContentProcess(matches, token) => { + opts_matches = matches; + content_process_token = Some(token); + if opts::get().is_running_problem_test && env::var("RUST_LOG").is_err() { + env::set_var("RUST_LOG", "compositing::constellation"); + } + }, + ArgumentParsingResult::ChromeProcess(matches) => { + opts_matches = matches; + content_process_token = None; + }, }; // TODO: once log-panics is released, can this be replaced by @@ -128,7 +145,9 @@ pub fn main() { process::exit(0); } - App::run(opts::get().angle, opts::get().enable_vsync); + let angle = opts_matches.opt_present("angle"); + let enable_vsync = !opts_matches.opt_present("disable-vsync"); + App::run(angle, enable_vsync); platform::deinit() } diff --git a/ports/libmlservo/Cargo.toml b/ports/libmlservo/Cargo.toml index 4c4ef0e8b1b..4809675761c 100644 --- a/ports/libmlservo/Cargo.toml +++ b/ports/libmlservo/Cargo.toml @@ -25,6 +25,7 @@ simpleservo = { path = "../libsimpleservo/api", features = ["no_static_freetype" rust-webvr = { version = "0.16", features = ["magicleap"] } webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] } webxr = { git = "https://github.com/servo/webxr", features = ["ipc", "magicleap"] } +getopts = "0.2.11" libc = "0.2" log = "0.4" servo-egl = "0.2" diff --git a/ports/libsimpleservo/api/src/lib.rs b/ports/libsimpleservo/api/src/lib.rs index 8f4d314932b..97d22dba867 100644 --- a/ports/libsimpleservo/api/src/lib.rs +++ b/ports/libsimpleservo/api/src/lib.rs @@ -171,7 +171,7 @@ pub fn init( gfx.subpixel_text_antialiasing.enabled, init_opts.enable_subpixel_text_antialiasing ); - opts::from_cmdline_args(&args); + opts::from_cmdline_args(Options::new(), &args); } let embedder_url = init_opts.url.as_ref().and_then(|s| ServoUrl::parse(s).ok()); From 74f1e2ec322b22ef9a1370d56d7cf3b1d38479ef Mon Sep 17 00:00:00 2001 From: glowe Date: Wed, 23 Oct 2019 18:13:57 -0400 Subject: [PATCH 3/4] Extract 3 more embedder options Extracted clean-shutdown, msaa, and no-native-titlebar embedder specific options out from the global options. Partially fixes #23009 --- Cargo.lock | 2 +- components/config/opts.rs | 28 ---------------------------- ports/glutin/app.rs | 4 +++- ports/glutin/headed_window.rs | 16 ++++++++++++---- ports/glutin/main2.rs | 18 +++++++++++++++--- ports/glutin/platform/macos/mod.rs | 5 ++--- ports/libmlservo/Cargo.toml | 1 - ports/libsimpleservo/api/Cargo.toml | 1 + 8 files changed, 34 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 15c435e6eba..ca10d5ef330 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2673,7 +2673,6 @@ dependencies = [ name = "libmlservo" version = "0.0.1" dependencies = [ - "getopts", "libc", "libservo", "log", @@ -4809,6 +4808,7 @@ name = "simpleservo" version = "0.0.1" dependencies = [ "core-foundation", + "getopts", "gl_generator 0.11.0", "libc", "libloading", diff --git a/components/config/opts.rs b/components/config/opts.rs index 2e2cb20a45f..8fe8fb62d5d 100644 --- a/components/config/opts.rs +++ b/components/config/opts.rs @@ -181,9 +181,6 @@ pub struct Opts { /// True to exit after the page load (`-x`). pub exit_after_load: bool, - /// Do not use native titlebar - pub no_native_titlebar: bool, - /// True to show webrender profiling stats on screen. pub webrender_stats: bool, @@ -201,9 +198,6 @@ pub struct Opts { /// after each change is made. pub precache_shaders: bool, - /// True if WebRender should use multisample antialiasing. - pub use_msaa: bool, - /// Directory for a default config directory pub config_dir: Option, @@ -225,9 +219,6 @@ pub struct Opts { /// Print Progressive Web Metrics to console. pub print_pwm: bool, - - /// Only shutdown once all theads are finished. - pub clean_shutdown: bool, } fn print_usage(app: &str, opts: &Options) { @@ -317,9 +308,6 @@ pub struct DebugOptions { /// Enable webrender instanced draw call batching. pub webrender_disable_batch: bool, - /// Use multisample antialiasing in WebRender. - pub use_msaa: bool, - // don't skip any backtraces on panic pub full_backtraces: bool, @@ -362,7 +350,6 @@ impl DebugOptions { "wr-stats" => self.webrender_stats = true, "wr-record" => self.webrender_record = true, "wr-no-batch" => self.webrender_disable_batch = true, - "msaa" => self.use_msaa = true, "full-backtraces" => self.full_backtraces = true, "precache-shaders" => self.precache_shaders = true, "signpost" => self.signpost = true, @@ -453,7 +440,6 @@ fn print_debug_usage(app: &str) -> ! { "Load web fonts synchronously to avoid non-deterministic network-driven reflows", ); print_option("wr-stats", "Show WebRender profiler on screen."); - print_option("msaa", "Use multisample antialiasing in WebRender."); print_option("full-backtraces", "Print full backtraces for all errors"); print_option("wr-debug", "Display webrender tile borders."); print_option("wr-no-batch", "Disable webrender instanced batching."); @@ -579,9 +565,7 @@ pub fn default_opts() -> Opts { style_sharing_stats: false, convert_mouse_to_touch: false, exit_after_load: false, - no_native_titlebar: false, webrender_stats: false, - use_msaa: false, config_dir: None, full_backtraces: false, is_printing_version: false, @@ -593,7 +577,6 @@ pub fn default_opts() -> Opts { certificate_path: None, unminify_js: false, print_pwm: false, - clean_shutdown: false, } } @@ -745,11 +728,6 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR "config directory following xdg spec on linux platform", "", ); - opts.optflag( - "", - "clean-shutdown", - "Do not shutdown until all threads have finished (macos only)", - ); opts.optflag("v", "version", "Display servo version information"); opts.optflag("", "unminify-js", "Unminify Javascript"); opts.optopt("", "profiler-db-user", "Profiler database user", ""); @@ -964,9 +942,6 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR }) .collect(); - let do_not_use_native_titlebar = - opt_match.opt_present("b") || !(pref!(shell.native_titlebar.enabled)); - let enable_subpixel_text_antialiasing = !debug_options.disable_subpixel_aa && pref!(gfx.subpixel_text_antialiasing.enabled); @@ -1017,9 +992,7 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR style_sharing_stats: debug_options.style_sharing_stats, convert_mouse_to_touch: debug_options.convert_mouse_to_touch, exit_after_load: opt_match.opt_present("x"), - no_native_titlebar: do_not_use_native_titlebar, webrender_stats: debug_options.webrender_stats, - use_msaa: debug_options.use_msaa, config_dir: opt_match.opt_str("config-dir").map(Into::into), full_backtraces: debug_options.full_backtraces, is_printing_version: is_printing_version, @@ -1031,7 +1004,6 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR certificate_path: opt_match.opt_str("certificate-path"), unminify_js: opt_match.opt_present("unminify-js"), print_pwm: opt_match.opt_present("print-pwm"), - clean_shutdown: opt_match.opt_present("clean-shutdown"), }; set_options(opts); diff --git a/ports/glutin/app.rs b/ports/glutin/app.rs index d5371bf1e93..44c8d52e6a7 100644 --- a/ports/glutin/app.rs +++ b/ports/glutin/app.rs @@ -34,7 +34,7 @@ pub struct App { } impl App { - pub fn run(angle: bool, enable_vsync: bool) { + pub fn run(angle: bool, enable_vsync: bool, use_msaa: bool, no_native_titlebar: bool) { let events_loop = EventsLoop::new(opts::get().headless); // Implements window methods, used by compositor. @@ -47,6 +47,8 @@ impl App { events_loop.clone(), angle, enable_vsync, + use_msaa, + no_native_titlebar, )) }; diff --git a/ports/glutin/headed_window.rs b/ports/glutin/headed_window.rs index 37af152a2a2..10c69ba59c6 100644 --- a/ports/glutin/headed_window.rs +++ b/ports/glutin/headed_window.rs @@ -73,6 +73,8 @@ pub struct Window { xr_rotation: Cell>, angle: bool, enable_vsync: bool, + use_msaa: bool, + no_native_titlebar: bool, } #[cfg(not(target_os = "windows"))] @@ -94,6 +96,8 @@ impl Window { events_loop: Rc>, angle: bool, enable_vsync: bool, + use_msaa: bool, + no_native_titlebar: bool, ) -> Window { let opts = opts::get(); @@ -101,7 +105,7 @@ impl Window { // `load_end()`. This avoids an ugly flash of unstyled content (especially important since // unstyled content is white and chrome often has a transparent background). See issue // #9996. - let visible = opts.output_file.is_none() && !opts.no_native_titlebar; + let visible = opts.output_file.is_none() && !no_native_titlebar; let win_size: DeviceIntSize = (win_size.to_f32() * window_creation_scale_factor()).to_i32(); let width = win_size.to_untyped().width; @@ -109,8 +113,8 @@ impl Window { let mut window_builder = glutin::WindowBuilder::new() .with_title("Servo".to_string()) - .with_decorations(!opts.no_native_titlebar) - .with_transparency(opts.no_native_titlebar) + .with_decorations(!no_native_titlebar) + .with_transparency(no_native_titlebar) .with_dimensions(LogicalSize::new(width as f64, height as f64)) .with_visibility(visible) .with_multitouch(); @@ -121,7 +125,7 @@ impl Window { .with_gl(app::gl_version(angle)) .with_vsync(enable_vsync); - if opts.use_msaa { + if use_msaa { context_builder = context_builder.with_multisampling(MULTISAMPLES) } @@ -204,6 +208,8 @@ impl Window { xr_rotation: Cell::new(Rotation3D::identity()), angle, enable_vsync, + use_msaa, + no_native_titlebar, }; window.present(); @@ -553,6 +559,8 @@ impl webxr::glwindow::GlWindow for Window { self.events_loop.clone(), self.angle, self.enable_vsync, + self.use_msaa, + self.no_native_titlebar, )); app::register_window(window.clone()); Ok(window) diff --git a/ports/glutin/main2.rs b/ports/glutin/main2.rs index e0224e64daa..c6aff92f5e0 100644 --- a/ports/glutin/main2.rs +++ b/ports/glutin/main2.rs @@ -27,6 +27,7 @@ use backtrace::Backtrace; use getopts::Options; use servo::config::opts::{self, ArgumentParsingResult}; use servo::config::servo_version; +use servo::servo_config::pref; use std::env; use std::panic; use std::process; @@ -40,7 +41,7 @@ pub mod platform { pub mod macos; #[cfg(not(target_os = "macos"))] - pub fn deinit() {} + pub fn deinit(_clean_shutdown: bool) {} } #[cfg(not(any(target_os = "macos", target_os = "linux")))] @@ -83,11 +84,18 @@ pub fn main() { "angle", "Use ANGLE to create a GL context (Windows-only)", ); + opts.optflag( + "", + "clean-shutdown", + "Do not shutdown until all threads have finished (macos only)", + ); opts.optflag( "", "disable-vsync", "Disable vsync mode in the compositor to allow profiling at more than monitor refresh rate", ); + opts.optflag("", "msaa", "Use multisample antialiasing in WebRender."); + opts.optflag("b", "no-native-titlebar", "Do not use native titlebar"); let opts_matches; let content_process_token; @@ -146,8 +154,12 @@ pub fn main() { } let angle = opts_matches.opt_present("angle"); + let clean_shutdown = opts_matches.opt_present("clean-shutdown"); + let do_not_use_native_titlebar = + opts_matches.opt_present("no-native-titlebar") || !(pref!(shell.native_titlebar.enabled)); let enable_vsync = !opts_matches.opt_present("disable-vsync"); - App::run(angle, enable_vsync); + let use_msaa = opts_matches.opt_present("msaa"); + App::run(angle, enable_vsync, use_msaa, do_not_use_native_titlebar); - platform::deinit() + platform::deinit(clean_shutdown) } diff --git a/ports/glutin/platform/macos/mod.rs b/ports/glutin/platform/macos/mod.rs index 730f4072576..d9d14bb9ee8 100644 --- a/ports/glutin/platform/macos/mod.rs +++ b/ports/glutin/platform/macos/mod.rs @@ -2,12 +2,11 @@ * 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/. */ -use servo::config::opts; use std::ptr; use std::thread; use std::time::Duration; -pub fn deinit() { +pub fn deinit(clean_shutdown: bool) { // An unfortunate hack to make sure the linker's dead code stripping doesn't strip our // `Info.plist`. unsafe { @@ -21,7 +20,7 @@ pub fn deinit() { "{} threads are still running after shutdown (bad).", thread_count ); - if opts::get().clean_shutdown { + if clean_shutdown { println!("Waiting until all threads have shutdown"); loop { let thread_count = unsafe { macos_count_running_threads() }; diff --git a/ports/libmlservo/Cargo.toml b/ports/libmlservo/Cargo.toml index 4809675761c..4c4ef0e8b1b 100644 --- a/ports/libmlservo/Cargo.toml +++ b/ports/libmlservo/Cargo.toml @@ -25,7 +25,6 @@ simpleservo = { path = "../libsimpleservo/api", features = ["no_static_freetype" rust-webvr = { version = "0.16", features = ["magicleap"] } webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] } webxr = { git = "https://github.com/servo/webxr", features = ["ipc", "magicleap"] } -getopts = "0.2.11" libc = "0.2" log = "0.4" servo-egl = "0.2" diff --git a/ports/libsimpleservo/api/Cargo.toml b/ports/libsimpleservo/api/Cargo.toml index e0204f3ebb6..afbd3f4c800 100644 --- a/ports/libsimpleservo/api/Cargo.toml +++ b/ports/libsimpleservo/api/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" publish = false [dependencies] +getopts = "0.2.11" libservo = { path = "../../../components/servo" } log = "0.4" servo-media = { git = "https://github.com/servo/media" } From 0ee300479ec22e18ea00d9d1c7c60bdd35808983 Mon Sep 17 00:00:00 2001 From: glowe Date: Sat, 26 Oct 2019 11:37:09 -0400 Subject: [PATCH 4/4] Extract device_pixels_per_px from global opts This is also an embedder specific option, so removing it from the global options makes sense. --- components/config/opts.rs | 16 --------------- components/constellation/constellation.rs | 10 +++++++++ components/constellation/pipeline.rs | 8 +++++++- components/servo/lib.rs | 13 +++++++++--- ports/glutin/app.rs | 13 +++++++++--- ports/glutin/headed_window.rs | 6 +++++- ports/glutin/headless_window.rs | 25 ++++++++++++++--------- ports/glutin/main2.rs | 10 ++++++++- ports/libsimpleservo/api/src/lib.rs | 2 +- 9 files changed, 67 insertions(+), 36 deletions(-) diff --git a/components/config/opts.rs b/components/config/opts.rs index 8fe8fb62d5d..64856866a86 100644 --- a/components/config/opts.rs +++ b/components/config/opts.rs @@ -32,10 +32,6 @@ pub struct Opts { /// The maximum size of each tile in pixels (`-s`). pub tile_size: usize, - /// The ratio of device pixels per px at the default scale. If unspecified, will use the - /// platform default setting. - pub device_pixels_per_px: Option, - /// `None` to disable the time profiler or `Some` to enable it with: /// /// - an interval in seconds to cause it to produce output on that interval. @@ -524,7 +520,6 @@ pub fn default_opts() -> Opts { is_running_problem_test: false, url: None, tile_size: 512, - device_pixels_per_px: None, time_profiling: None, time_profiler_trace_path: None, mem_profiler_period: None, @@ -587,7 +582,6 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR opts.optflag("g", "gpu", "GPU painting"); opts.optopt("o", "output", "Output file", "output.png"); opts.optopt("s", "size", "Size of tiles", "512"); - opts.optopt("", "device-pixel-ratio", "Device pixels per px", ""); opts.optflagopt( "p", "profile", @@ -792,15 +786,6 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR None => 512, }; - let device_pixels_per_px = opt_match.opt_str("device-pixel-ratio").map(|dppx_str| { - dppx_str.parse().unwrap_or_else(|err| { - args_fail(&format!( - "Error parsing option: --device-pixel-ratio ({})", - err - )) - }) - }); - // If only the flag is present, default to a 5 second period for both profilers let time_profiling = if opt_match.opt_present("p") { match opt_match.opt_str("p") { @@ -951,7 +936,6 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR is_running_problem_test: is_running_problem_test, url: url_opt, tile_size: tile_size, - device_pixels_per_px: device_pixels_per_px, time_profiling: time_profiling, time_profiler_trace_path: opt_match.opt_str("profiler-trace-path"), mem_profiler_period: mem_profiler_period, diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 356f530d9ed..a819bd65a1b 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -464,6 +464,10 @@ pub struct Constellation { /// Mechanism to force the compositor to process events. event_loop_waker: Option>, + + /// The ratio of device pixels per px at the default scale. If unspecified, will use the + /// platform default setting. + device_pixels_per_px: Option, } /// State needed to construct a constellation. @@ -520,6 +524,10 @@ pub struct InitialConstellationState { /// Mechanism to force the compositor to process events. pub event_loop_waker: Option>, + + /// The ratio of device pixels per px at the default scale. If unspecified, will use the + /// platform default setting. + pub device_pixels_per_px: Option, } /// Data needed for webdriver @@ -837,6 +845,7 @@ where glplayer_threads: state.glplayer_threads, player_context: state.player_context, event_loop_waker: state.event_loop_waker, + device_pixels_per_px, }; constellation.run(); @@ -1081,6 +1090,7 @@ where webxr_registry: self.webxr_registry.clone(), player_context: self.player_context.clone(), event_loop_waker: self.event_loop_waker.as_ref().map(|w| (*w).clone_box()), + device_pixels_per_px: self.device_pixels_per_px, }); let pipeline = match result { diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs index 373d4820529..2579343f3fe 100644 --- a/components/constellation/pipeline.rs +++ b/components/constellation/pipeline.rs @@ -205,6 +205,10 @@ pub struct InitialPipelineState { /// Mechanism to force the compositor to process events. pub event_loop_waker: Option>, + + /// The ratio of device pixels per px at the default scale. If unspecified, will use the + /// platform default setting. + pub device_pixels_per_px: Option, } pub struct NewPipeline { @@ -312,6 +316,7 @@ impl Pipeline { webvr_chan: state.webvr_chan, webxr_registry: state.webxr_registry, player_context: state.player_context, + device_pixels_per_px: state.device_pixels_per_px, }; // Spawn the child process. @@ -518,6 +523,7 @@ pub struct UnprivilegedPipelineContent { webvr_chan: Option>, webxr_registry: webxr_api::Registry, player_context: WindowGLContext, + device_pixels_per_px: Option, } impl UnprivilegedPipelineContent { @@ -609,7 +615,7 @@ impl UnprivilegedPipelineContent { layout_thread_busy_flag.clone(), self.opts.load_webfonts_synchronously, self.opts.initial_window_size, - self.opts.device_pixels_per_px, + self.device_pixels_per_px, self.opts.dump_display_list, self.opts.dump_display_list_json, self.opts.dump_style_tree, diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 7e8a6c1a438..86920bbe361 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -306,7 +306,11 @@ impl Servo where Window: WindowMethods + 'static + ?Sized, { - pub fn new(mut embedder: Box, window: Rc) -> Servo { + pub fn new( + mut embedder: Box, + window: Rc, + device_pixels_per_px: Option, + ) -> Servo { // Global configuration options, parsed from the command line. let opts = opts::get(); @@ -551,6 +555,7 @@ where webvr_constellation_sender, glplayer_threads, event_loop_waker, + device_pixels_per_px, ); // Send the constellation's swmanager sender to service worker manager thread @@ -582,7 +587,7 @@ where opts.is_running_problem_test, opts.exit_after_load, opts.convert_mouse_to_touch, - opts.device_pixels_per_px, + device_pixels_per_px, ); Servo { @@ -870,6 +875,7 @@ fn create_constellation( webvr_constellation_sender: Option>>, glplayer_threads: Option, event_loop_waker: Option>, + device_pixels_per_px: Option, ) -> (Sender, SWManagerSenders) { // Global configuration options, parsed from the command line. let opts = opts::get(); @@ -912,6 +918,7 @@ fn create_constellation( glplayer_threads, player_context, event_loop_waker, + device_pixels_per_px, }; let (constellation_chan, from_swmanager_sender) = Constellation::< script_layout_interface::message::Msg, @@ -920,7 +927,7 @@ fn create_constellation( >::start( initial_state, opts.initial_window_size, - opts.device_pixels_per_px, + device_pixels_per_px, opts.random_pipeline_closure_probability, opts.random_pipeline_closure_seed, opts.is_running_problem_test, diff --git a/ports/glutin/app.rs b/ports/glutin/app.rs index 44c8d52e6a7..a43245d79a5 100644 --- a/ports/glutin/app.rs +++ b/ports/glutin/app.rs @@ -34,12 +34,18 @@ pub struct App { } impl App { - pub fn run(angle: bool, enable_vsync: bool, use_msaa: bool, no_native_titlebar: bool) { + pub fn run( + angle: bool, + enable_vsync: bool, + use_msaa: bool, + no_native_titlebar: bool, + device_pixels_per_px: Option, + ) { let events_loop = EventsLoop::new(opts::get().headless); // Implements window methods, used by compositor. let window = if opts::get().headless { - headless_window::Window::new(opts::get().initial_window_size) + headless_window::Window::new(opts::get().initial_window_size, device_pixels_per_px) } else { Rc::new(headed_window::Window::new( opts::get().initial_window_size, @@ -49,6 +55,7 @@ impl App { enable_vsync, use_msaa, no_native_titlebar, + device_pixels_per_px, )) }; @@ -63,7 +70,7 @@ impl App { // Handle browser state. let browser = Browser::new(window.clone()); - let mut servo = Servo::new(embedder, window.clone()); + let mut servo = Servo::new(embedder, window.clone(), device_pixels_per_px); let browser_id = BrowserId::new(); servo.handle_events(vec![WindowEvent::NewBrowser(get_default_url(), browser_id)]); servo.setup_logging(); diff --git a/ports/glutin/headed_window.rs b/ports/glutin/headed_window.rs index 10c69ba59c6..dfaf980b6fb 100644 --- a/ports/glutin/headed_window.rs +++ b/ports/glutin/headed_window.rs @@ -75,6 +75,7 @@ pub struct Window { enable_vsync: bool, use_msaa: bool, no_native_titlebar: bool, + device_pixels_per_px: Option, } #[cfg(not(target_os = "windows"))] @@ -98,6 +99,7 @@ impl Window { enable_vsync: bool, use_msaa: bool, no_native_titlebar: bool, + device_pixels_per_px: Option, ) -> Window { let opts = opts::get(); @@ -210,6 +212,7 @@ impl Window { enable_vsync, use_msaa, no_native_titlebar, + device_pixels_per_px, }; window.present(); @@ -329,7 +332,7 @@ impl Window { } fn servo_hidpi_factor(&self) -> Scale { - match opts::get().device_pixels_per_px { + match self.device_pixels_per_px { Some(device_pixels_per_px) => Scale::new(device_pixels_per_px), _ => match opts::get().output_file { Some(_) => Scale::new(1.0), @@ -561,6 +564,7 @@ impl webxr::glwindow::GlWindow for Window { self.enable_vsync, self.use_msaa, self.no_native_titlebar, + self.device_pixels_per_px, )); app::register_window(window.clone()); Ok(window) diff --git a/ports/glutin/headless_window.rs b/ports/glutin/headless_window.rs index 4b87915bb17..c0c5c1fabb0 100644 --- a/ports/glutin/headless_window.rs +++ b/ports/glutin/headless_window.rs @@ -5,12 +5,11 @@ //! A headless window implementation. use crate::window_trait::WindowPortsMethods; -use glutin; use euclid::{default::Size2D as UntypedSize2D, Point2D, Rotation3D, Scale, Size2D, UnknownUnit}; use gleam::gl; +use glutin; use servo::compositing::windowing::{AnimationState, WindowEvent}; use servo::compositing::windowing::{EmbedderCoordinates, WindowMethods}; -use servo::servo_config::opts; use servo::servo_geometry::DeviceIndependentPixel; use servo::style_traits::DevicePixel; use servo::webrender_api::units::{DeviceIntRect, DeviceIntSize}; @@ -92,10 +91,14 @@ pub struct Window { animation_state: Cell, fullscreen: Cell, gl: Rc, + device_pixels_per_px: Option, } impl Window { - pub fn new(size: Size2D) -> Rc { + pub fn new( + size: Size2D, + device_pixels_per_px: Option, + ) -> Rc { let context = HeadlessContext::new(size.width, size.height, None); let gl = unsafe { gl::GlFns::load_with(|s| HeadlessContext::get_proc_address(s)) }; @@ -110,13 +113,14 @@ impl Window { gl, animation_state: Cell::new(AnimationState::Idle), fullscreen: Cell::new(false), + device_pixels_per_px, }; Rc::new(window) } fn servo_hidpi_factor(&self) -> Scale { - match opts::get().device_pixels_per_px { + match self.device_pixels_per_px { Some(device_pixels_per_px) => Scale::new(device_pixels_per_px), _ => Scale::new(1.0), } @@ -133,9 +137,7 @@ impl WindowPortsMethods for Window { } fn id(&self) -> glutin::WindowId { - unsafe { - glutin::WindowId::dummy() - } + unsafe { glutin::WindowId::dummy() } } fn page_height(&self) -> f32 { @@ -167,8 +169,7 @@ impl WindowMethods for Window { fn get_coordinates(&self) -> EmbedderCoordinates { let dpr = self.servo_hidpi_factor(); - let size = - (Size2D::new(self.context.width, self.context.height).to_f32() * dpr).to_i32(); + let size = (Size2D::new(self.context.width, self.context.height).to_f32() * dpr).to_i32(); let viewport = DeviceIntRect::new(Point2D::zero(), size); let framebuffer = DeviceIntSize::from_untyped(size.to_untyped()); EmbedderCoordinates { @@ -223,7 +224,10 @@ impl webxr::glwindow::GlWindow for Window { fn swap_buffers(&self) {} fn size(&self) -> UntypedSize2D { let dpr = self.servo_hidpi_factor().get(); - Size2D::new((self.context.width as f32 * dpr) as gl::GLsizei, (self.context.height as f32 * dpr) as gl::GLsizei) + Size2D::new( + (self.context.width as f32 * dpr) as gl::GLsizei, + (self.context.height as f32 * dpr) as gl::GLsizei, + ) } fn new_window(&self) -> Result, ()> { let width = self.context.width; @@ -236,6 +240,7 @@ impl webxr::glwindow::GlWindow for Window { gl, animation_state: Cell::new(AnimationState::Idle), fullscreen: Cell::new(false), + device_pixels_per_px: self.device_pixels_per_px, })) } fn get_rotation(&self) -> Rotation3D { diff --git a/ports/glutin/main2.rs b/ports/glutin/main2.rs index c6aff92f5e0..b8d784db762 100644 --- a/ports/glutin/main2.rs +++ b/ports/glutin/main2.rs @@ -96,6 +96,7 @@ pub fn main() { ); opts.optflag("", "msaa", "Use multisample antialiasing in WebRender."); opts.optflag("b", "no-native-titlebar", "Do not use native titlebar"); + opts.optopt("", "device-pixel-ratio", "Device pixels per px", ""); let opts_matches; let content_process_token; @@ -159,7 +160,14 @@ pub fn main() { opts_matches.opt_present("no-native-titlebar") || !(pref!(shell.native_titlebar.enabled)); let enable_vsync = !opts_matches.opt_present("disable-vsync"); let use_msaa = opts_matches.opt_present("msaa"); - App::run(angle, enable_vsync, use_msaa, do_not_use_native_titlebar); + let device_pixels_per_px = opts_matches.opt_str("device-pixel-ratio").map(|dppx_str| { + dppx_str.parse().unwrap_or_else(|err| { + error!( "Error parsing option: --device-pixel-ratio ({})", err); + process::exit(1); + }) + }); + + App::run(angle, enable_vsync, use_msaa, do_not_use_native_titlebar, device_pixels_per_px); platform::deinit(clean_shutdown) } diff --git a/ports/libsimpleservo/api/src/lib.rs b/ports/libsimpleservo/api/src/lib.rs index 97d22dba867..57844593a95 100644 --- a/ports/libsimpleservo/api/src/lib.rs +++ b/ports/libsimpleservo/api/src/lib.rs @@ -205,7 +205,7 @@ pub fn init( gl: gl.clone(), }); - let servo = Servo::new(embedder_callbacks, window_callbacks.clone()); + let servo = Servo::new(embedder_callbacks, window_callbacks.clone(), None); SERVO.with(|s| { let mut servo_glue = ServoGlue {