diff --git a/servo/components/compositing/constellation.rs b/servo/components/compositing/constellation.rs index 8794c65662c9..24b581999860 100644 --- a/servo/components/compositing/constellation.rs +++ b/servo/components/compositing/constellation.rs @@ -2,6 +2,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +//! The `Constellation`, Servo's Grand Central Station +//! +//! The primary duty of a `Constellation` is to mediate between the +//! graphics compositor and the many `Pipeline`s in the browser's +//! navigation context, each `Pipeline` encompassing a `ScriptTask`, +//! `LayoutTask`, and `PaintTask`. + use pipeline::{Pipeline, CompositionPipeline}; use compositor_task::CompositorProxy; @@ -44,6 +51,11 @@ use clipboard::ClipboardContext; use webdriver_traits::WebDriverScriptCommand; /// Maintains the pipelines and navigation context and grants permission to composite. +/// +/// It is parameterized over a `LayoutTaskFactory` and a +/// `ScriptTaskFactory` (which in practice are implemented by +/// `LayoutTask` in the `layout` crate, and `ScriptTask` in +/// the `script` crate). pub struct Constellation { /// A channel through which messages can be sent to this object. pub chan: ConstellationChan, diff --git a/servo/components/servo/Cargo.lock b/servo/components/servo/Cargo.lock index c32b732cce5e..9af6b01feba4 100644 --- a/servo/components/servo/Cargo.lock +++ b/servo/components/servo/Cargo.lock @@ -1231,6 +1231,7 @@ dependencies = [ "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", "string_cache_plugin 0.1.1 (git+https://github.com/servo/string-cache)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/servo/components/servo/lib.rs b/servo/components/servo/lib.rs index 225d8f8a3b50..d4c1d4e44d37 100644 --- a/servo/components/servo/lib.rs +++ b/servo/components/servo/lib.rs @@ -32,7 +32,6 @@ extern crate script; extern crate layout; extern crate gfx; extern crate libc; -extern crate url; extern crate webdriver_server; use compositing::CompositorEventListener; @@ -79,8 +78,6 @@ pub struct Browser { impl Browser { pub fn new(window: Option>) -> Browser where Window: WindowMethods + 'static { - ::util::opts::set_experimental_enabled(opts::get().enable_experimental); - // Global configuration options, parsed from the command line. let opts = opts::get(); @@ -147,14 +144,12 @@ impl Browser { self.compositor.shutdown(); } } + fn create_constellation(opts: opts::Opts, compositor_proxy: Box, time_profiler_chan: time::ProfilerChan, devtools_chan: Option>, mem_profiler_chan: mem::ProfilerChan) -> ConstellationChan { - use std::env; - - // Create a Servo instance. let resource_task = new_resource_task(opts.user_agent.clone(), devtools_chan.clone()); let image_cache_task = new_image_cache_task(resource_task.clone()); @@ -173,17 +168,9 @@ fn create_constellation(opts: opts::Opts, storage_task); // Send the URL command to the constellation. - let cwd = env::current_dir().unwrap(); - let url = match url::Url::parse(&opts.url) { - Ok(url) => url, - Err(url::ParseError::RelativeUrlWithoutBase) - => url::Url::from_file_path(&*cwd.join(&opts.url)).unwrap(), - Err(_) => panic!("URL parsing failed"), - }; - { let ConstellationChan(ref chan) = constellation_chan; - chan.send(ConstellationMsg::InitLoadUrl(url)).unwrap(); + chan.send(ConstellationMsg::InitLoadUrl(opts.url.clone())).unwrap(); } constellation_chan diff --git a/servo/components/util/Cargo.toml b/servo/components/util/Cargo.toml index dadc3872d8e4..1ac5eff13548 100644 --- a/servo/components/util/Cargo.toml +++ b/servo/components/util/Cargo.toml @@ -48,3 +48,4 @@ fnv = "1.0" cssparser = "0.3.1" num = "0.1.24" lazy_static = "0.1.10" +url = "*" diff --git a/servo/components/util/lib.rs b/servo/components/util/lib.rs index 021499c3adcf..61c6de2475c6 100644 --- a/servo/components/util/lib.rs +++ b/servo/components/util/lib.rs @@ -36,6 +36,7 @@ extern crate rustc_serialize; extern crate selectors; extern crate smallvec as smallvec_; extern crate string_cache; +extern crate url; use std::sync::Arc; diff --git a/servo/components/util/opts.rs b/servo/components/util/opts.rs index 70ca9d4b92bc..3505b33f2108 100644 --- a/servo/components/util/opts.rs +++ b/servo/components/util/opts.rs @@ -18,12 +18,13 @@ use std::env; use std::io::{self, Write}; use std::mem; use std::ptr; +use url::{self, Url}; /// Global flags for Servo, currently set on the command line. #[derive(Clone)] pub struct Opts { /// The initial URL to load. - pub url: String, + pub url: Url, /// How many threads to use for CPU painting (`-t`). /// @@ -192,7 +193,7 @@ static FORCE_CPU_PAINTING: bool = false; pub fn default_opts() -> Opts { Opts { - url: String::new(), + url: Url::parse("about:blank").unwrap(), paint_threads: 1, gpu_painting: false, tile_size: 512, @@ -293,7 +294,14 @@ pub fn from_cmdline_args(args: &[String]) -> bool { args_fail("servo asks that you provide a URL"); return false; } else { - opt_match.free[0].clone() + let ref url = opt_match.free[0]; + let cwd = env::current_dir().unwrap(); + match Url::parse(url) { + Ok(url) => url, + Err(url::ParseError::RelativeUrlWithoutBase) + => Url::from_file_path(&*cwd.join(url)).unwrap(), + Err(_) => panic!("URL parsing failed"), + } }; let tile_size: usize = match opt_match.opt_str("s") { @@ -392,12 +400,15 @@ pub fn from_cmdline_args(args: &[String]) -> bool { disable_share_style_cache: debug_options.contains(&"disable-share-style-cache"), }; - set_opts(opts); + set(opts); true } static mut EXPERIMENTAL_ENABLED: bool = false; +/// Turn on experimental features globally. Normally this is done +/// during initialization by `set` or `from_cmdline_args`, but +/// tests that require experimental features will also set it. pub fn set_experimental_enabled(new_value: bool) { unsafe { EXPERIMENTAL_ENABLED = new_value; @@ -415,8 +426,10 @@ pub fn experimental_enabled() -> bool { // when passing through the DOM structures. static mut OPTIONS: *mut Opts = 0 as *mut Opts; -pub fn set_opts(opts: Opts) { +pub fn set(opts: Opts) { unsafe { + assert!(OPTIONS.is_null()); + set_experimental_enabled(opts.enable_experimental); let box_opts = box opts; OPTIONS = mem::transmute(box_opts); } @@ -430,7 +443,7 @@ pub fn get<'a>() -> &'a Opts { // set of options. This is mostly useful for unit tests that // run through a code path which queries the cmd line options. if OPTIONS == ptr::null_mut() { - set_opts(default_opts()); + set(default_opts()); } mem::transmute(OPTIONS) } diff --git a/servo/ports/cef/Cargo.lock b/servo/ports/cef/Cargo.lock index 85d5bba141d1..9c2a4d368d91 100644 --- a/servo/ports/cef/Cargo.lock +++ b/servo/ports/cef/Cargo.lock @@ -1224,6 +1224,7 @@ dependencies = [ "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", "string_cache_plugin 0.1.1 (git+https://github.com/servo/string-cache)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/servo/ports/cef/browser.rs b/servo/ports/cef/browser.rs index 6f773fa335a5..90e13801becc 100644 --- a/servo/ports/cef/browser.rs +++ b/servo/ports/cef/browser.rs @@ -15,7 +15,6 @@ use window; use compositing::windowing::{WindowNavigateMsg, WindowEvent}; use glutin_app; use libc::c_int; -use util::opts; use std::borrow::ToOwned; use std::cell::{Cell, RefCell, BorrowState}; use std::sync::atomic::{AtomicIsize, Ordering}; @@ -204,9 +203,6 @@ fn browser_host_create(window_info: &cef_window_info_t, client: CefClient, callback_executed: bool) -> CefBrowser { - let url = "http://s27.postimg.org/vqbtrolyr/servo.jpg".to_owned(); - let mut opts = opts::default_opts(); - opts.url = url; let browser = ServoCefBrowser::new(window_info, client).as_cef_interface(); browser.init(window_info); if callback_executed { diff --git a/servo/ports/cef/core.rs b/servo/ports/cef/core.rs index 7a27f37618f7..02f884e3c719 100644 --- a/servo/ports/cef/core.rs +++ b/servo/ports/cef/core.rs @@ -12,6 +12,7 @@ use std::borrow::ToOwned; use std::ffi; use std::str; use browser; +use std_url::Url; const MAX_RENDERING_THREADS: usize = 128; @@ -70,14 +71,14 @@ pub extern "C" fn cef_initialize(args: *const cef_main_args_t, }; let mut temp_opts = opts::default_opts(); - temp_opts.url = HOME_URL.to_owned(); + temp_opts.url = Url::parse(HOME_URL).unwrap(); temp_opts.paint_threads = rendering_threads; temp_opts.layout_threads = rendering_threads; temp_opts.headless = false; temp_opts.hard_fail = false; temp_opts.enable_text_antialiasing = true; temp_opts.resources_path = resources_path(); - opts::set_opts(temp_opts); + opts::set(temp_opts); return 1 } diff --git a/servo/ports/gonk/Cargo.lock b/servo/ports/gonk/Cargo.lock index 801ec61ba2c7..6c4d3d750e07 100644 --- a/servo/ports/gonk/Cargo.lock +++ b/servo/ports/gonk/Cargo.lock @@ -1086,6 +1086,7 @@ dependencies = [ "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", "string_cache_plugin 0.1.1 (git+https://github.com/servo/string-cache)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/servo/ports/gonk/src/lib.rs b/servo/ports/gonk/src/lib.rs deleted file mode 100644 index 3174c5294ee6..000000000000 --- a/servo/ports/gonk/src/lib.rs +++ /dev/null @@ -1,171 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#![feature(thread_local)] -#![feature(box_syntax)] -#![feature(rustc_private)] -// For FFI -#![allow(non_snake_case, dead_code)] - -#[macro_use] -extern crate log; - -extern crate compositing; -extern crate devtools; -extern crate net; -extern crate net_traits; -extern crate msg; -#[macro_use] -extern crate util; -extern crate script; -extern crate layout; -extern crate gfx; -extern crate libc; -extern crate profile; -extern crate url; - -use compositing::CompositorEventListener; -use compositing::windowing::{WindowEvent, WindowMethods}; - -#[cfg(not(test))] -use compositing::{CompositorProxy, CompositorTask, Constellation}; -#[cfg(not(test))] -use msg::constellation_msg::Msg as ConstellationMsg; -#[cfg(not(test))] -use msg::constellation_msg::ConstellationChan; -#[cfg(not(test))] -use script::dom::bindings::codegen::RegisterBindings; - -#[cfg(not(test))] -use net::image_cache_task::new_image_cache_task; -#[cfg(not(test))] -use net::storage_task::StorageTaskFactory; -#[cfg(not(test))] -use net::resource_task::new_resource_task; -#[cfg(not(test))] -use gfx::font_cache_task::FontCacheTask; -#[cfg(not(test))] -use profile::mem; -#[cfg(not(test))] -use profile::time; -#[cfg(not(test))] -use util::opts; -#[cfg(not(test))] -use util::taskpool::TaskPool; - -#[cfg(not(test))] -use std::env; -#[cfg(not(test))] -use std::rc::Rc; - -pub struct Browser { - compositor: Box, -} - -/// The in-process interface to Servo. -/// -/// It does everything necessary to render the web, primarily -/// orchestrating the interaction between JavaScript, CSS layout, -/// rendering, and the client window. -/// -/// Clients create a `Browser` for a given reference-counted type -/// implementing `WindowMethods`, which is the bridge to whatever -/// application Servo is embedded in. Clients then create an event -/// loop to pump messages between the embedding application and -/// various browser components. -impl Browser { - #[cfg(not(test))] - pub fn new(window: Option>) -> Browser - where Window: WindowMethods + 'static { - ::util::opts::set_experimental_enabled(opts::get().enable_experimental); - // Global configuration options, parsed from the command line. - let opts = opts::get(); - - // Create the global vtables used by the (generated) DOM - // bindings to implement JS proxies. - RegisterBindings::RegisterProxyHandlers(); - - // Use this thread pool to load-balance simple tasks, such as - // image decoding. - let shared_task_pool = TaskPool::new(8); - - // Get both endpoints of a special channel for communication between - // 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 (compositor_proxy, compositor_receiver) = - WindowMethods::create_compositor_channel(&window); - let time_profiler_chan = time::Profiler::create(opts.time_profiler_period); - let mem_profiler_chan = mem::Profiler::create(opts.mem_profiler_period); - let devtools_chan = opts.devtools_port.map(|port| { - devtools::start_server(port) - }); - - // Create a Servo instance. - let resource_task = new_resource_task(opts.user_agent.clone(), devtools_chan.clone()); - - let image_cache_task = new_image_cache_task(resource_task.clone()); - let font_cache_task = FontCacheTask::new(resource_task.clone()); - let storage_task = StorageTaskFactory::new(); - - // Create the constellation, which maintains the engine - // pipelines, including the script and layout threads, as well - // as the navigation context. - let constellation_chan = Constellation::::start( - compositor_proxy.clone_compositor_proxy(), - resource_task, - image_cache_task, - font_cache_task, - time_profiler_chan.clone(), - mem_profiler_chan.clone(), - devtools_chan, - storage_task); - - // Send the URL command to the constellation. - let cwd = env::current_dir().unwrap(); - let url = match url::Url::parse(&opts.url) { - Ok(url) => url, - Err(url::ParseError::RelativeUrlWithoutBase) - => url::Url::from_file_path(&*cwd.join(&opts.url)).unwrap(), - Err(_) => panic!("URL parsing failed"), - }; - - let ConstellationChan(ref chan) = constellation_chan; - chan.send(ConstellationMsg::InitLoadUrl(url)).unwrap(); - - // The compositor coordinates with the client window to create the final - // rendered page and display it somewhere. - let compositor = CompositorTask::create(window, - compositor_proxy, - compositor_receiver, - constellation_chan.clone(), - time_profiler_chan, - mem_profiler_chan); - - Browser { - compositor: compositor, - } - } - - pub fn handle_event(&mut self, event: WindowEvent) -> bool { - self.compositor.handle_event(event) - } - - pub fn repaint_synchronously(&mut self) { - self.compositor.repaint_synchronously() - } - - pub fn pinch_zoom_level(&self) -> f32 { - self.compositor.pinch_zoom_level() - } - - pub fn get_title_for_main_frame(&self) { - self.compositor.get_title_for_main_frame() - } - - pub fn shutdown(mut self) { - self.compositor.shutdown(); - } -}