diff options
author | Tim Kuehn <tkuehn@cmu.edu> | 2013-06-07 16:43:03 -0700 |
---|---|---|
committer | Patrick Walton <pcwalton@mimiga.net> | 2013-06-12 11:02:52 -0700 |
commit | 7b284621930299a625b53a744f3ee9fd2493e17e (patch) | |
tree | 5077df0a78ec09f97301318ea71cb4c618ed57b6 | |
parent | 1fbfd7d45e8950eef6713cf063ded756bf17f1bd (diff) | |
download | servo-7b284621930299a625b53a744f3ee9fd2493e17e.tar.gz servo-7b284621930299a625b53a744f3ee9fd2493e17e.zip |
Send status messages to the compositor
-rw-r--r-- | src/components/main/compositing/mod.rs | 24 | ||||
-rw-r--r-- | src/components/main/engine.rs | 19 | ||||
-rw-r--r-- | src/components/main/platform/common/glut_windowing.rs | 4 | ||||
-rw-r--r-- | src/components/main/windowing.rs | 2 | ||||
-rw-r--r-- | src/components/script/compositor_interface.rs | 19 | ||||
-rw-r--r-- | src/components/script/dom/window.rs | 1 | ||||
-rw-r--r-- | src/components/script/script.rc | 3 | ||||
-rw-r--r-- | src/components/script/script_task.rs | 19 |
8 files changed, 80 insertions, 11 deletions
diff --git a/src/components/main/compositing/mod.rs b/src/components/main/compositing/mod.rs index ad065a9966f..4f8ff79e8f0 100644 --- a/src/components/main/compositing/mod.rs +++ b/src/components/main/compositing/mod.rs @@ -9,6 +9,8 @@ use windowing::{ApplicationMethods, WindowMethods, WindowMouseEvent, WindowClick use windowing::{WindowMouseDownEvent, WindowMouseUpEvent}; use script::dom::event::{Event, ClickEvent, MouseDownEvent, MouseUpEvent}; +use script::compositor_interface::{ReadyState, CompositorInterface}; +use script::compositor_interface; use azure::azure_hl::{DataSourceSurface, DrawTarget, SourceSurfaceMethods}; use core::cell::Cell; @@ -36,6 +38,13 @@ pub struct CompositorTask { chan: SharedChan<Msg>, } +impl CompositorInterface for CompositorTask { + fn send_compositor_msg(&self, msg: ReadyState) { + let msg = ChangeReadyState(msg); + self.chan.send(msg); + } +} + impl CompositorTask { /// Starts the compositor. Returns an interface that can be used to communicate with the /// compositor and a port which allows notification when the compositor shuts down. @@ -63,10 +72,12 @@ impl CompositorTask { /// Messages to the compositor. pub enum Msg { - /// Requests that the compositor paint the given layer buffer set for the given page size. - Paint(LayerBufferSet, Size2D<uint>), /// Requests that the compositor shut down. Exit, + /// Requests that the compositor paint the given layer buffer set for the given page size. + Paint(LayerBufferSet, Size2D<uint>), + /// Alerts the compositor to the current status of page loading + ChangeReadyState(ReadyState), } /// Azure surface wrapping to work with the layers infrastructure. @@ -134,12 +145,19 @@ fn run_main_loop(port: Port<Msg>, let check_for_messages: @fn() = || { // Periodically check if the script task responded to our last resize event resize_rate_limiter.check_resize_response(); - // Handle messages while port.peek() { match port.recv() { Exit => *done = true, + ChangeReadyState(ready_state) => { + let window_title = match ready_state { + compositor_interface::FinishedLoading => ~"Servo", + _ => fmt!("%? — Servo", ready_state), + }; + window.set_title(window_title); + } + Paint(new_layer_buffer_set, new_size) => { debug!("osmain: received new frame"); diff --git a/src/components/main/engine.rs b/src/components/main/engine.rs index 6458876c8b6..8abbcaef096 100644 --- a/src/components/main/engine.rs +++ b/src/components/main/engine.rs @@ -10,6 +10,7 @@ use core::comm::{Port, SharedChan}; use gfx::opts::Opts; use gfx::render_task::RenderTask; use gfx::render_task; +use script::compositor_interface::{CompositorInterface, ReadyState}; use script::engine_interface::{EngineTask, ExitMsg, LoadUrlMsg, Msg}; use script::layout_interface::LayoutTask; use script::layout_interface; @@ -48,13 +49,15 @@ impl Engine { profiler_chan: ProfilerChan) -> EngineTask { let (script_port, script_chan) = (Cell(script_port), Cell(script_chan)); - let (request_port, request_chan) = comm::stream(); - let (request_port, request_chan) = (Cell(request_port), SharedChan::new(request_chan)); - let request_chan_clone = request_chan.clone(); + let (engine_port, engine_chan) = comm::stream(); + let (engine_port, engine_chan) = (Cell(engine_port), SharedChan::new(engine_chan)); + let engine_chan_clone = engine_chan.clone(); + let compositor = Cell(compositor); let profiler_port = Cell(profiler_port); let opts = Cell(copy *opts); do task::spawn { + let compositor = compositor.take(); let render_task = RenderTask::new(compositor.clone(), opts.with_ref(|o| copy *o), profiler_chan.clone()); @@ -70,16 +73,20 @@ impl Engine { opts, profiler_task.chan.clone()); + let compositor_clone = compositor.clone(); let script_task = ScriptTask::new(script_port.take(), script_chan.take(), - request_chan_clone.clone(), + engine_chan_clone.clone(), + |msg: ReadyState| { + compositor_clone.send_compositor_msg(msg) + }, layout_task.clone(), resource_task.clone(), image_cache_task.clone()); Engine { - request_port: request_port.take(), + request_port: engine_port.take(), compositor: compositor.clone(), render_task: render_task, resource_task: resource_task.clone(), @@ -89,7 +96,7 @@ impl Engine { profiler_task: profiler_task, }.run(); } - request_chan.clone() + engine_chan.clone() } fn run(&self) { diff --git a/src/components/main/platform/common/glut_windowing.rs b/src/components/main/platform/common/glut_windowing.rs index 27db4d71154..7e3dfd33044 100644 --- a/src/components/main/platform/common/glut_windowing.rs +++ b/src/components/main/platform/common/glut_windowing.rs @@ -162,6 +162,10 @@ impl WindowMethods<Application> for Window { pub fn set_needs_display(@mut self) { glut::post_redisplay() } + + pub fn set_title(@mut self, title: &str) { + glut::set_window_title(self.glut_window, title); + } } impl Window { diff --git a/src/components/main/windowing.rs b/src/components/main/windowing.rs index 42cce45c60a..829d1f26c40 100644 --- a/src/components/main/windowing.rs +++ b/src/components/main/windowing.rs @@ -61,5 +61,7 @@ pub trait WindowMethods<A> { pub fn check_loop(@mut self); /// Schedules a redisplay at the next turn of the event loop. pub fn set_needs_display(@mut self); + /// Sets the title of the window + pub fn set_title(@mut self, title: &str); } diff --git a/src/components/script/compositor_interface.rs b/src/components/script/compositor_interface.rs new file mode 100644 index 00000000000..78e74f5fee1 --- /dev/null +++ b/src/components/script/compositor_interface.rs @@ -0,0 +1,19 @@ +/* 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/. */ + +//! The high-level interface from script to compositor. Using this abstract interface helps reduce +/// coupling between these two components + +pub enum ReadyState { + /// Informs the compositor that a page is loading. Used for setting status + Loading, + /// Informs the compositor that a page is rendering. Used for setting status + Rendering, + /// Informs the compositor that a page is finished loading. Used for setting status + FinishedLoading, +} + +pub trait CompositorInterface: Clone { + fn send_compositor_msg(&self, ReadyState); +} diff --git a/src/components/script/dom/window.rs b/src/components/script/dom/window.rs index a5904b642c7..aa375a4d614 100644 --- a/src/components/script/dom/window.rs +++ b/src/components/script/dom/window.rs @@ -4,6 +4,7 @@ use dom::bindings::utils::WrapperCache; use dom::bindings::window; + use layout_interface::ReflowForScriptQuery; use script_task::{ExitMsg, FireTimerMsg, ScriptMsg, ScriptContext}; diff --git a/src/components/script/script.rc b/src/components/script/script.rc index dc303783472..2d608e4d25b 100644 --- a/src/components/script/script.rc +++ b/src/components/script/script.rc @@ -64,7 +64,8 @@ pub mod html { pub mod hubbub_html_parser; } -pub mod layout_interface; +pub mod compositor_interface; pub mod engine_interface; +pub mod layout_interface; pub mod script_task; diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index 0482febe570..d3aba93a8f9 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -5,6 +5,7 @@ /// The script task is the task that owns the DOM in memory, runs JavaScript, and spawns parsing /// and layout tasks. +use compositor_interface::{ReadyState, Loading, Rendering, FinishedLoading}; use dom::bindings::utils::GlobalStaticData; use dom::document::Document; use dom::element::Element; @@ -68,12 +69,14 @@ impl ScriptTask { pub fn new(script_port: Port<ScriptMsg>, script_chan: SharedChan<ScriptMsg>, engine_task: EngineTask, + //FIXME(rust #5192): workaround for lack of working ~Trait + compositor_task: ~fn(ReadyState), layout_task: LayoutTask, resource_task: ResourceTask, image_cache_task: ImageCacheTask) -> ScriptTask { let (script_chan_copy, script_port) = (script_chan.clone(), Cell(script_port)); - + let compositor_task = Cell(compositor_task); // FIXME: rust#6399 let mut the_task = task(); the_task.sched_mode(SingleThreaded); @@ -82,6 +85,7 @@ impl ScriptTask { script_port.take(), script_chan_copy.clone(), engine_task.clone(), + compositor_task.take(), resource_task.clone(), image_cache_task.clone()); script_context.start(); @@ -123,6 +127,8 @@ pub struct ScriptContext { /// For communicating load url messages to the engine engine_task: EngineTask, + /// For communicating loading messages to the compositor + compositor_task: ~fn(ReadyState), /// The JavaScript runtime. js_runtime: js::rust::rt, @@ -176,6 +182,7 @@ impl ScriptContext { script_port: Port<ScriptMsg>, script_chan: SharedChan<ScriptMsg>, engine_task: EngineTask, + compositor_task: ~fn(ReadyState), resource_task: ResourceTask, img_cache_task: ImageCacheTask) -> @mut ScriptContext { @@ -200,6 +207,7 @@ impl ScriptContext { script_chan: script_chan, engine_task: engine_task, + compositor_task: compositor_task, js_runtime: js_runtime, js_context: js_context, @@ -308,6 +316,12 @@ impl ScriptContext { self.layout_task.chan.send(layout_interface::ExitMsg) } + // tells the compositor when loading starts and finishes + // FIXME ~compositor_interface doesn't work right now, which is why this is necessary + fn send_compositor_msg(&self, msg: ReadyState) { + (self.compositor_task)(msg); + } + /// The entry point to document loading. Defines bindings, sets up the window and document /// objects, parses HTML and CSS, and kicks off initial layout. fn load(&mut self, url: Url) { @@ -319,6 +333,7 @@ impl ScriptContext { self.bindings_initialized = true } + self.send_compositor_msg(Loading); // Parse HTML. // // Note: We can parse the next document in parallel with any previous documents. @@ -359,6 +374,7 @@ impl ScriptContext { url: url }); + self.send_compositor_msg(Rendering); // Perform the initial reflow. self.damage = Some(DocumentDamage { root: root_node, @@ -376,6 +392,7 @@ impl ScriptContext { ~"???", 1); } + self.send_compositor_msg(FinishedLoading); } /// Sends a ping to layout and waits for the response. The response will arrive when the |