aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Kuehn <tkuehn@cmu.edu>2013-06-07 16:43:03 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-06-12 11:02:52 -0700
commit7b284621930299a625b53a744f3ee9fd2493e17e (patch)
tree5077df0a78ec09f97301318ea71cb4c618ed57b6
parent1fbfd7d45e8950eef6713cf063ded756bf17f1bd (diff)
downloadservo-7b284621930299a625b53a744f3ee9fd2493e17e.tar.gz
servo-7b284621930299a625b53a744f3ee9fd2493e17e.zip
Send status messages to the compositor
-rw-r--r--src/components/main/compositing/mod.rs24
-rw-r--r--src/components/main/engine.rs19
-rw-r--r--src/components/main/platform/common/glut_windowing.rs4
-rw-r--r--src/components/main/windowing.rs2
-rw-r--r--src/components/script/compositor_interface.rs19
-rw-r--r--src/components/script/dom/window.rs1
-rw-r--r--src/components/script/script.rc3
-rw-r--r--src/components/script/script_task.rs19
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