diff --git a/components/config/opts.rs b/components/config/opts.rs index 49fa0fee3447..4710edfe77d8 100644 --- a/components/config/opts.rs +++ b/components/config/opts.rs @@ -7,7 +7,7 @@ use crate::prefs::{self, PrefValue}; use euclid::TypedSize2D; -use getopts::Options; +use getopts::{Options}; use servo_geometry::DeviceIndependentPixel; use servo_url::ServoUrl; use std::borrow::Cow; @@ -78,8 +78,7 @@ pub struct Opts { pub headless: bool, - /// Use ANGLE to create the GL context (Windows-only). - pub angle: bool, + // pub angle: bool, /// True to exit on thread failure instead of displaying about:failure. pub hard_fail: bool, @@ -140,9 +139,6 @@ pub struct Opts { /// An optional string allowing the user agent to be set for testing. pub user_agent: Cow<'static, str>, - /// Whether we're running in multiprocess mode. - pub multiprocess: bool, - /// Whether we're running inside the sandbox. pub sandbox: bool, @@ -188,7 +184,7 @@ pub struct Opts { pub no_native_titlebar: bool, /// Enable vsync in the compositor - pub enable_vsync: bool, + // pub enable_vsync: bool, /// True to show webrender profiling stats on screen. pub webrender_stats: bool, @@ -314,9 +310,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 +361,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 +454,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"); @@ -490,18 +478,37 @@ pub enum OutputOptions { Stdout(f64), } -fn args_fail(msg: &str) -> ! { +pub fn args_fail(msg: &str) -> ! { writeln!(io::stderr(), "{}", msg).unwrap(); process::exit(1) } static MULTIPROCESS: AtomicBool = AtomicBool::new(false); +static VSYNC: AtomicBool = AtomicBool::new(true); + +static ANGLE: AtomicBool = AtomicBool::new(false); + +#[inline] +pub fn set_multiprocess(b: bool, ord: Ordering) { MULTIPROCESS.store(b, ord) } + +#[inline] +pub fn set_vsync(b: bool, ord: Ordering) { VSYNC.store(b, ord) } + +#[inline] +pub fn set_angle(b: bool, ord: Ordering) { ANGLE.store(b, ord) } + #[inline] pub fn multiprocess() -> bool { MULTIPROCESS.load(Ordering::Relaxed) } +#[inline] +pub fn enable_vsync() -> bool { VSYNC.load(Ordering::Relaxed) } + +#[inline] +pub fn angle() -> bool { ANGLE.load(Ordering::Relaxed) } + enum UserAgent { Desktop, Android, @@ -564,7 +571,7 @@ pub fn default_opts() -> Opts { gc_profile: false, load_webfonts_synchronously: false, headless: false, - angle: false, + // angle: false, hard_fail: true, bubble_inline_sizes_separately: false, show_debug_fragment_borders: false, @@ -578,7 +585,6 @@ pub fn default_opts() -> Opts { webdriver_port: None, initial_window_size: TypedSize2D::new(1024, 740), user_agent: default_user_agent_string(DEFAULT_USER_AGENT).into(), - multiprocess: false, random_pipeline_closure_probability: None, random_pipeline_closure_seed: None, sandbox: false, @@ -595,7 +601,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,15 +618,24 @@ pub fn default_opts() -> Opts { } } -pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { - let (app_name, args) = args.split_first().unwrap(); +fn create_global_opts(mut opts: getopts::Options) -> Options { + - 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"); opts.optopt("s", "size", "Size of tiles", "512"); opts.optopt("", "device-pixel-ratio", "Device pixels per px", ""); + + // TODO: Remove -z, e.g. --headlessone from global. + opts.optflag("z", "headless", "Headless mode"); + opts.optmulti( + "Z", + "debug", + "A comma-separated string of debug options. Pass help to show available options.", + "", + ); + opts.optflagopt( "p", "profile", @@ -672,12 +686,6 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { "Shaders will be loaded from the specified directory instead of using the builtin ones.", "", ); - opts.optflag("z", "headless", "Headless mode"); - opts.optflag( - "", - "angle", - "Use ANGLE to create a GL context (Windows-only)", - ); opts.optflag( "f", "hard-fail", @@ -713,7 +721,6 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { "Set custom user agent string (or ios / android / desktop for platform default)", "NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)", ); - opts.optflag("M", "multiprocess", "Run in multiprocess mode"); opts.optflag("S", "sandbox", "Run in a sandbox if multiprocess"); opts.optopt( "", @@ -727,12 +734,6 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { "A fixed seed for repeatbility of random pipeline closure.", "", ); - opts.optmulti( - "Z", - "debug", - "A comma-separated string of debug options. Pass help to show available options.", - "", - ); opts.optflag("h", "help", "Print this message"); opts.optopt( "", @@ -779,6 +780,14 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { opts.optopt("", "profiler-db-name", "Profiler database name", ""); opts.optflag("", "print-pwm", "Print Progressive Web Metrics"); + opts +} + +pub fn from_cmdline_args(opts: getopts::Options, args: &[String]) -> getopts::Result { + let (app_name, args) = args.split_first().unwrap(); + + let opts = create_global_opts(opts); + let opt_match = match opts.parse(args) { Ok(m) => m, Err(f) => args_fail(&f.to_string()), @@ -789,13 +798,6 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { process::exit(0); }; - // If this is the content process, we'll receive the real options over IPC. So just fill in - // 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); - } - let mut debug_options = DebugOptions::default(); for debug_string in opt_match.opt_strs("Z") { @@ -959,10 +961,6 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { None => TypedSize2D::new(1024, 740), }; - if opt_match.opt_present("M") { - MULTIPROCESS.store(true, Ordering::SeqCst) - } - let user_agent = match opt_match.opt_str("u") { Some(ref ua) if ua == "ios" => default_user_agent_string(UserAgent::iOS).into(), Some(ref ua) if ua == "android" => default_user_agent_string(UserAgent::Android).into(), @@ -994,7 +992,7 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { let is_printing_version = opt_match.opt_present("v") || opt_match.opt_present("version"); - let opts = Opts { + let mut opts = Opts { is_running_problem_test: is_running_problem_test, url: url_opt, tile_size: tile_size, @@ -1010,7 +1008,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, @@ -1021,7 +1018,6 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { webdriver_port: webdriver_port, initial_window_size: initial_window_size, user_agent: user_agent, - multiprocess: opt_match.opt_present("M"), sandbox: opt_match.opt_present("S"), random_pipeline_closure_probability: random_pipeline_closure_probability, random_pipeline_closure_seed: random_pipeline_closure_seed, @@ -1041,7 +1037,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,7 +1069,7 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { set_pref!(layout.threads, layout_threads as i64); } - ArgumentParsingResult::ChromeProcess + Ok(opt_match) } pub enum ArgumentParsingResult { @@ -1090,7 +1085,6 @@ lazy_static! { } pub fn set_options(opts: Opts) { - MULTIPROCESS.store(opts.multiprocess, Ordering::SeqCst); *OPTIONS.write().unwrap() = opts; } diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 0e5ccf2c2ad9..80c71a958379 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -203,7 +203,7 @@ where // Global configuration options, parsed from the command line. let opts = opts::get(); - if !opts.multiprocess { + if !opts::multiprocess() { ServoMedia::init::(); } diff --git a/ports/glutin/Cargo.toml b/ports/glutin/Cargo.toml index 2a6f1302d22c..09b6d0c25001 100644 --- a/ports/glutin/Cargo.toml +++ b/ports/glutin/Cargo.toml @@ -47,6 +47,7 @@ backtrace = "0.3" bitflags = "1.0" crossbeam-channel = "0.3" euclid = "0.19" +getopts = "0.2.11" gleam = "0.6" glutin = "0.21.0" keyboard-types = "0.4.3" diff --git a/ports/glutin/app.rs b/ports/glutin/app.rs index 46e84bdcc70b..fc3ce09c310b 100644 --- a/ports/glutin/app.rs +++ b/ports/glutin/app.rs @@ -185,7 +185,7 @@ fn get_default_url() -> ServoUrl { } pub fn gl_version() -> glutin::GlRequest { - if opts::get().angle { + if opts::angle() { glutin::GlRequest::Specific(glutin::Api::OpenGlEs, (3, 0)) } else { glutin::GlRequest::GlThenGles { diff --git a/ports/glutin/headed_window.rs b/ports/glutin/headed_window.rs index 3026170645ee..dff026cd3d62 100644 --- a/ports/glutin/headed_window.rs +++ b/ports/glutin/headed_window.rs @@ -109,7 +109,7 @@ impl Window { let mut context_builder = glutin::ContextBuilder::new() .with_gl(app::gl_version()) - .with_vsync(opts.enable_vsync); + .with_vsync(opts::enable_vsync()); if opts.use_msaa { context_builder = context_builder.with_multisampling(MULTISAMPLES) diff --git a/ports/glutin/main2.rs b/ports/glutin/main2.rs index 496c0515e19f..1c577b51516c 100644 --- a/ports/glutin/main2.rs +++ b/ports/glutin/main2.rs @@ -24,11 +24,14 @@ mod window_trait; use app::App; use backtrace::Backtrace; -use servo::config::opts::{self, ArgumentParsingResult}; +use getopts::Options; +use servo::config::opts::{self, ArgumentParsingResult, args_fail, set_multiprocess, set_vsync, + set_angle}; use servo::config::servo_version; use std::env; use std::panic; use std::process; +use std::sync::atomic::Ordering; use std::thread; pub mod platform { @@ -72,6 +75,23 @@ fn install_crash_handler() { signal!(Sig::BUS, handler); // handle invalid memory access } +fn create_gluten_opts() -> Options { + let mut opts = Options::new(); + opts.optflag("M", "multiprocess", "Run in multiprocess mode"); + opts.optflag("", + "disable-vsync", + "Disable vsync mode in the compositor to allow profiling at more than monitor refresh rate"); + + // opts.optflag("z", "headless", "Headless mode"); + /// Use ANGLE to create the GL context (Windows-only). + opts.optflag( + "", + "angle", + "Use ANGLE to create a GL context (Windows-only)", + ); + opts +} + pub fn main() { install_crash_handler(); @@ -79,18 +99,38 @@ 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); + // Get Glutin only config options to pass to global. + let opts = create_gluten_opts(); + // Get our Opts result to config remaining, Glutin specific, cli opts passed. + let opt_result = opts::from_cmdline_args(opts ,&args); + + let opt_match = match opt_result { + Ok(o) => o, + Err(f) => args_fail(&f.to_string()), + }; - let content_process_token = if let ArgumentParsingResult::ContentProcess(token) = opts_result { - Some(token) + if let Some(token) = opt_match.opt_str("content-process") { + return servo::run_content_process(token); } else { if opts::get().is_running_problem_test && env::var("RUST_LOG").is_err() { env::set_var("RUST_LOG", "compositing::constellation"); } - None + () }; + if opt_match.opt_present("M") { + set_multiprocess(true, Ordering::SeqCst); + } + + if opt_match.opt_present("disable-vsync") { + set_vsync(false, Ordering::SeqCst); + } + + if opt_match.opt_present("angle") { + set_angle(true, Ordering::SeqCst); + } + // TODO: once log-panics is released, can this be replaced by // log_panics::init()? panic::set_hook(Box::new(|info| { @@ -122,9 +162,9 @@ pub fn main() { error!("{}", msg); })); - if let Some(token) = content_process_token { - return servo::run_content_process(token); - } +// if let Some(token) = content_process_token { +// return servo::run_content_process(token); +// } if opts::get().is_printing_version { println!("{}", servo_version());