diff --git a/servo/src/components/compositing/compositor.rs b/servo/src/components/compositing/compositor.rs index 91db33e44f99..c2ce7b546f53 100644 --- a/servo/src/components/compositing/compositor.rs +++ b/servo/src/components/compositing/compositor.rs @@ -20,7 +20,7 @@ use windowing::{WindowEvent, WindowMethods, WindowNavigateMsg, ZoomWindowEvent}; use windowing::PinchZoomWindowEvent; use azure::azure_hl::SourceSurfaceMethods; -use azure::{azure_hl, AzFloat}; +use azure::azure_hl; use geom::matrix::identity; use geom::point::{Point2D, TypedPoint2D}; use geom::rect::Rect; @@ -34,8 +34,7 @@ use layers::scene::Scene; use layers::layers::Layer; use opengles::gl2; use png; -use servo_msg::compositor_msg::{Blank, Epoch, FinishedLoading}; -use servo_msg::compositor_msg::{IdleRenderState, RenderingRenderState}; +use servo_msg::compositor_msg::{Blank, Epoch, FinishedLoading, IdleRenderState}; use servo_msg::compositor_msg::{LayerId, ReadyState, RenderState}; use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, LoadUrlMsg, NavigateMsg}; use servo_msg::constellation_msg::{PipelineId, ResizedWindowMsg, WindowSizeData}; @@ -49,7 +48,6 @@ use std::io::timer::sleep; use std::collections::hashmap::HashMap; use std::path::Path; use std::rc::Rc; -use std::cmp; use time::precise_time_s; @@ -64,7 +62,7 @@ pub struct IOCompositor { context: RenderContext, /// The root pipeline. - pipeline_tree: Option, + root_pipeline: Option, /// The canvas to paint a page. scene: Scene, @@ -98,6 +96,9 @@ pub struct IOCompositor { /// The time of the last zoom action has started. zoom_time: f64, + /// Current display/reflow status of the page + ready_state: ReadyState, + /// Whether the page being rendered has loaded completely. /// Differs from ReadyState because we can finish loading (ready) /// many times for a single page. @@ -126,29 +127,6 @@ enum ShutdownState { FinishedShuttingDown, } -#[deriving(Clone)] -struct CompositionPipelineTree { - pipeline: CompositionPipeline, - children: Vec, - ready_state: ReadyState, - render_state: RenderState, -} - -impl CompositionPipelineTree { - pub fn new(frame_tree: SendableFrameTree) -> CompositionPipelineTree { - let mut tree = CompositionPipelineTree { - pipeline: frame_tree.pipeline, - children: Vec::new(), - ready_state: Blank, - render_state: RenderingRenderState, - }; - for child_tree in frame_tree.children.iter() { - tree.children.push(CompositionPipelineTree::new(child_tree.frame_tree.clone())); - } - return tree; - } -} - impl IOCompositor { fn new(app: &Application, opts: Opts, @@ -170,7 +148,7 @@ impl IOCompositor { port: port, opts: opts, context: rendergl::init_render_context(CompositorTask::create_graphics_context()), - pipeline_tree: None, + root_pipeline: None, scene: Scene::new(window_size.as_f32().to_untyped(), identity()), window_size: window_size, hidpi_factor: hidpi_factor, @@ -181,6 +159,7 @@ impl IOCompositor { viewport_zoom: ScaleFactor(1.0), zoom_action: false, zoom_time: 0f64, + ready_state: Blank, load_complete: false, constellation_chan: constellation_chan, time_profiler_chan: time_profiler_chan, @@ -288,12 +267,13 @@ impl IOCompositor { break; } - (Ok(ChangeReadyState(ready_state, pipeline_id)), NotShuttingDown) => { - self.change_ready_state(ready_state, pipeline_id); + (Ok(ChangeReadyState(ready_state)), NotShuttingDown) => { + self.window.set_ready_state(ready_state); + self.ready_state = ready_state; } - (Ok(ChangeRenderState(state, pipeline_id)), NotShuttingDown) => { - self.change_render_state(state, pipeline_id); + (Ok(ChangeRenderState(render_state)), NotShuttingDown) => { + self.change_render_state(render_state); } (Ok(SetIds(frame_tree, response_chan, new_constellation_chan)), _) => { @@ -306,25 +286,12 @@ impl IOCompositor { (Ok(CreateOrUpdateRootLayer(layer_properties)), NotShuttingDown) => { - let scene_root = self.scene.root.clone(); - self.create_or_update_root_layer(&scene_root, layer_properties); + self.create_or_update_root_layer(layer_properties); } (Ok(CreateOrUpdateDescendantLayer(layer_properties)), NotShuttingDown) => { - match self.find_parent_pipeline_id(self.get_root_pipeline_tree(), - layer_properties.pipeline_id) { - Some(parent_pipeline_id) => - self.create_or_update_descendant_layer(layer_properties, - parent_pipeline_id), - None if self.is_root_pipeline(layer_properties.pipeline_id) => - self.create_or_update_descendant_layer(layer_properties, - layer_properties.pipeline_id), - None => - fail!("didn't find pipeline for parent layer for pipeline id {:?}", - layer_properties.pipeline_id), - } - + self.create_or_update_descendant_layer(layer_properties); } (Ok(SetLayerClipRect(pipeline_id, layer_id, new_rect)), NotShuttingDown) => { @@ -352,75 +319,11 @@ impl IOCompositor { } } } - fn change_ready_state(&mut self, ready_state: ReadyState, pipeline_id: PipelineId) { - let mut use_param_ready_state = false; - { - let mut_root_pipeline_tree = self.get_mut_root_pipeline_tree(); - match IOCompositor::find_mut_pipeline(mut_root_pipeline_tree, pipeline_id) { - Some(tree) => tree.ready_state = ready_state, - None => use_param_ready_state = true, - }; - } - if use_param_ready_state { - self.window.set_ready_state(ready_state); - return; - } - let tree = match self.pipeline_tree { - Some(ref tree) => Some(tree), - None => None - }; - self.window.set_ready_state(self.get_ready_state(tree)); - } - fn get_ready_state(&self, pipeline_tree: Option<&CompositionPipelineTree>) -> ReadyState { - match pipeline_tree { - Some(ref tree) => { - let mut ready_state = tree.ready_state; - for child in tree.children.iter() { - ready_state = cmp::min(ready_state,self.get_ready_state(Some(child))); - if ready_state == Blank { break; }; - } - ready_state - } - None => Blank, - } - } - - fn change_render_state(&mut self, render_state: RenderState, pipeline_id: PipelineId) { - debug!("change_render_state: composite_ready {}, {:?}, {}", - self.composite_ready, render_state, pipeline_id); - let mut use_param_render_state = false; - { - let mut_root_pipeline_tree = self.get_mut_root_pipeline_tree(); - match IOCompositor::find_mut_pipeline(mut_root_pipeline_tree, pipeline_id) { - Some(tree) => tree.render_state = render_state, - None => use_param_render_state = true, - }; - } - if use_param_render_state { - self.window.set_render_state(render_state); - return; - } - let tree = match self.pipeline_tree { - Some(ref tree) => Some(tree), - None => None - }; - let new_render_state = self.get_render_state(tree); - self.window.set_render_state(new_render_state); - self.composite_ready = new_render_state == IdleRenderState; - } - - fn get_render_state(&self, pipeline_tree: Option<&CompositionPipelineTree>) -> RenderState { - match pipeline_tree { - Some(ref tree) => { - let mut render_state = tree.render_state; - for child in tree.children.iter() { - render_state = cmp::min(render_state,self.get_render_state(Some(child))); - if render_state == RenderingRenderState { break; }; - } - render_state - } - None => IdleRenderState, + fn change_render_state(&mut self, render_state: RenderState) { + self.window.set_render_state(render_state); + if render_state == IdleRenderState { + self.composite_ready = true; } } @@ -429,34 +332,14 @@ impl IOCompositor { response_chan: Sender<()>, new_constellation_chan: ConstellationChan) { response_chan.send(()); - let tree = CompositionPipelineTree::new(frame_tree); - self.pipeline_tree = Some(tree.clone()); - self.scene.root = Some(self.create_pipeline_tree_root_layers(&tree.clone())); + + self.root_pipeline = Some(frame_tree.pipeline.clone()); + // Initialize the new constellation channel by sending it the root window size. self.constellation_chan = new_constellation_chan; self.send_window_size(); } - fn create_pipeline_tree_root_layers(&mut self, - pipeline_tree: &CompositionPipelineTree) - -> Rc> { - let compositor_data = CompositorData::new_root(pipeline_tree.pipeline.clone(), - LayerId::null(), - Epoch(0), - self.opts.cpu_painting, - azure_hl::Color::new(0 as AzFloat, - 0 as AzFloat, - 0 as AzFloat, - 0 as AzFloat)); - let root_layer = Rc::new(Layer::new(Rect::zero(), - self.opts.tile_size, - compositor_data)); - for child_pipeline in pipeline_tree.children.iter() { - root_layer.add_child(self.create_pipeline_tree_root_layers(child_pipeline)); - } - return root_layer; - } - fn update_layer_if_exists(&mut self, properties: LayerProperties) -> bool { match self.scene.root { Some(ref root_layer) => { @@ -474,205 +357,59 @@ impl IOCompositor { } } - fn create_or_update_root_layer(&mut self, - root: &Option>>, - layer_properties: LayerProperties) { + fn create_or_update_root_layer(&mut self, layer_properties: LayerProperties) { let need_new_root_layer = !self.update_layer_if_exists(layer_properties); if need_new_root_layer { - let pipeline = match IOCompositor::find_pipeline(self.get_root_pipeline_tree(), - layer_properties.pipeline_id) { - Some(pipeline_tree) => pipeline_tree.pipeline.clone(), - None => - fail!("Compositor: Making new layer without initialized pipeline {}", - layer_properties.pipeline_id), + let root_pipeline = match self.root_pipeline { + Some(ref root_pipeline) => root_pipeline.clone(), + None => fail!("Compositor: Making new layer without initialized pipeline"), }; - let new_compositor_data = - CompositorData::new_root(pipeline.clone(), - layer_properties.id, - layer_properties.epoch, - self.opts.cpu_painting, - layer_properties.background_color); + let new_compositor_data = CompositorData::new_root(root_pipeline, + layer_properties.epoch, + self.opts.cpu_painting, + layer_properties.background_color); + let new_root = Rc::new(Layer::new(layer_properties.rect, + self.opts.tile_size, + new_compositor_data)); - if self.is_root_pipeline(layer_properties.pipeline_id) { - let scene_root = match self.scene.root { - // Release all tiles from the layer before dropping it. - Some(ref mut layer) if layer.extra_data.borrow().id == LayerId::null() => { - CompositorData::clear_all_tiles(layer.clone()); - layer - }, - // root layer is already initialized - Some(_) => fail!("scene.root already initalized"), - None => fail!("No scene root layer"), - }; + CompositorData::add_child(new_root.clone(), layer_properties); - let mut scene_bounds = scene_root.bounds.borrow_mut(); - if *scene_bounds == Rect::zero() { - *scene_bounds = layer_properties.rect; - } - *scene_root.extra_data.borrow_mut() = new_compositor_data; - } else { - let root_layer = - match self.find_pipeline_root_layer(root, layer_properties.pipeline_id) { - // Release all tiles from the layer before dropping it. - Some(ref mut layer) => { - CompositorData::clear_all_tiles(layer.clone()); - layer.clone() - }, - None => fail!("No pipeline root layer"), - }; - - let mut root_bounds = root_layer.bounds.borrow_mut(); - if *root_bounds == Rect::zero() { - *root_bounds = layer_properties.rect; - } - *root_layer.extra_data.borrow_mut() = new_compositor_data; + // Release all tiles from the layer before dropping it. + match self.scene.root { + Some(ref mut layer) => CompositorData::clear_all_tiles(layer.clone()), + None => { } } + self.scene.root = Some(new_root); } + self.scroll_layer_to_fragment_point_if_necessary(layer_properties.pipeline_id, layer_properties.id); self.ask_for_tiles(); } - fn is_root_pipeline(&mut self, pipeline_id: PipelineId) -> bool { - match self.pipeline_tree { - Some(ref root_pipeline) => root_pipeline.pipeline.id == pipeline_id, - None => fail!("Compositor: Uninitialized pipeline tree"), - } - } - - fn get_mut_root_pipeline_tree<'a>(&'a mut self) -> Option<&'a mut CompositionPipelineTree>{ - match self.pipeline_tree { - Some(ref mut tree) => Some(tree), - None => None, - } - } - - fn get_root_pipeline_tree<'a>(&'a self) -> Option<&'a CompositionPipelineTree>{ - match self.pipeline_tree { - Some(ref tree) => Some(tree), - None => None, - } - } - - fn find_mut_pipeline<'a>(tree: Option<&'a mut CompositionPipelineTree>, - pipeline_id: PipelineId) - -> Option<&'a mut CompositionPipelineTree> { - match tree { - Some(pipeline_tree) => { - if pipeline_tree.pipeline.id == pipeline_id { - Some(pipeline_tree) - } else { - for child in pipeline_tree.children.mut_iter() { - if child.pipeline.id == pipeline_id { - return Some(child); - } - match IOCompositor::find_mut_pipeline(Some(child), pipeline_id) { - Some(tree) => return Some(tree), - None => { }, - }; - } - None - }}, - None => None, - } - } - - fn find_pipeline<'a>(tree: Option<&'a CompositionPipelineTree>, - pipeline_id: PipelineId) - -> Option<&'a CompositionPipelineTree> { - match tree { - Some(pipeline_tree) => { - if pipeline_tree.pipeline.id == pipeline_id { - Some(pipeline_tree) - } else { - for child in pipeline_tree.children.iter() { - if child.pipeline.id == pipeline_id { - return Some(child); - } - match IOCompositor::find_pipeline(Some(child), pipeline_id) { - Some(tree) => return Some(tree), - None => { }, - }; - } - None - }}, - None => None, - } - } - - fn find_parent_pipeline_id(&self, - tree: Option<&CompositionPipelineTree>, - child_pipeline_id: PipelineId) - -> Option { - match tree { - Some(ref pipeline_tree) => { - for child_pipeline in pipeline_tree.children.iter() { - if child_pipeline.pipeline.id == child_pipeline_id { - return Some(pipeline_tree.pipeline.id); - } - } - for child_tree in pipeline_tree.children.iter() { - match self.find_parent_pipeline_id(Some(child_tree), - child_pipeline_id) { - Some(parent_pipeline_id) => return Some(parent_pipeline_id), - None => {}, - } - } - None - }, - None => None, - } - } - - fn create_or_update_descendant_layer(&mut self, - layer_properties: LayerProperties, - parent_layer_pipeline_id: PipelineId) { + fn create_or_update_descendant_layer(&mut self, layer_properties: LayerProperties) { if !self.update_layer_if_exists(layer_properties) { - self.create_descendant_layer(layer_properties, parent_layer_pipeline_id); + self.create_descendant_layer(layer_properties); } self.scroll_layer_to_fragment_point_if_necessary(layer_properties.pipeline_id, layer_properties.id); self.ask_for_tiles(); } - fn find_pipeline_root_layer(&self, - root: &Option>>, - pipeline_id: PipelineId) - -> Option>> { - let root_layer = match *root { - Some(ref layer) => layer.clone(), - None => fail!("no layer"), - }; - if root_layer.extra_data.borrow().pipeline.id == pipeline_id { - return Some(root_layer); - } else { - for child in root_layer.children().iter() { - match self.find_pipeline_root_layer(&Some(child.clone()), pipeline_id) { - Some(l) => return Some(l), - None => { }, - } - } - return None; - } - } - - fn create_descendant_layer(&mut self, - layer_properties: LayerProperties, - parent_layer_pipeline_id: PipelineId) { + fn create_descendant_layer(&self, layer_properties: LayerProperties) { match self.scene.root { Some(ref root_layer) => { - let x = Some(root_layer.clone()); - let parent_layer = match self.find_pipeline_root_layer(&x, - parent_layer_pipeline_id) { - Some(l) => l, - None => fail!("couldn't find parent layer"), - }; - let pipeline = match IOCompositor::find_pipeline(self.get_root_pipeline_tree(), - layer_properties.pipeline_id) { - Some(pipeline_tree) => pipeline_tree.pipeline.clone(), - None => fail!("Received new layer without initialized pipeline"), - }; - CompositorData::add_child(parent_layer.clone(), layer_properties, pipeline); + let parent_layer_id = root_layer.extra_data.borrow().id; + match CompositorData::find_layer_with_pipeline_and_layer_id(root_layer.clone(), + layer_properties.pipeline_id, + parent_layer_id) { + Some(ref mut parent_layer) => { + CompositorData::add_child(parent_layer.clone(), layer_properties); + } + None => { + fail!("Compositor: couldn't find parent layer"); + } + } } None => fail!("Compositor: Received new layer without initialized pipeline") } @@ -720,29 +457,17 @@ impl IOCompositor { pipeline_id: PipelineId, layer_id: LayerId, new_rect: Rect) { - let root_layer = match self.scene.root { - Some(ref root) => Some(root.clone()), - None => None, - }; - let id = match (layer_id == LayerId::null(), - self.find_pipeline_root_layer(&root_layer, pipeline_id)) { - (false, _) => layer_id, - (true, Some(l)) => l.extra_data.borrow().id, - (true, None) => fail!("No root layer for {}", pipeline_id)}; - let ask: bool = match self.scene.root { - Some(ref layer) => - match CompositorData::find_layer_with_pipeline_and_layer_id(layer.clone(), - pipeline_id, - id) { - Some(child_node) => { - *child_node.bounds.borrow_mut() = new_rect; - true - }, - None => - fail!("failed to clip rect for (pipeline_id, layer_id): {}, {}", - pipeline_id, id)}, - None => false, + Some(ref layer) => { + assert!(CompositorData::set_clipping_rect(layer.clone(), + pipeline_id, + layer_id, + new_rect)); + true + } + None => { + false + } }; if ask { @@ -1050,11 +775,7 @@ impl IOCompositor { // Render to PNG. We must read from the back buffer (ie, before // self.window.present()) as OpenGL ES 2 does not have glReadBuffer(). - let tree = match self.pipeline_tree { - Some(ref tree) => Some(tree), - None => None - }; - if self.load_complete && self.get_ready_state(tree) == FinishedLoading + if self.load_complete && self.ready_state == FinishedLoading && self.opts.output_file.is_some() { let (width, height) = (self.window_size.width.get(), self.window_size.height.get()); let path = from_str::(self.opts.output_file.get_ref().as_slice()).unwrap(); diff --git a/servo/src/components/compositing/compositor_data.rs b/servo/src/components/compositing/compositor_data.rs index 80099c5edbbe..5beabeb963d3 100644 --- a/servo/src/components/compositing/compositor_data.rs +++ b/servo/src/components/compositing/compositor_data.rs @@ -76,12 +76,11 @@ impl CompositorData { } pub fn new_root(pipeline: CompositionPipeline, - layer_id: LayerId, epoch: Epoch, cpu_painting: bool, unrendered_color: Color) -> CompositorData { CompositorData::new(pipeline, - layer_id, + LayerId::null(), epoch, cpu_painting, WantsScrollEvents, @@ -90,12 +89,11 @@ impl CompositorData { } /// Adds a child layer to the layer with the given ID and the given pipeline, if it doesn't - /// exist yet. The child layer will have the same tile size, memory limit, and CPU + /// exist yet. The child layer will have the same pipeline, tile size, memory limit, and CPU /// painting status as its parent. pub fn add_child(layer: Rc>, - layer_properties: LayerProperties, - pipeline: CompositionPipeline) { - let new_compositor_data = CompositorData::new(pipeline, + layer_properties: LayerProperties) { + let new_compositor_data = CompositorData::new(layer.extra_data.borrow().pipeline.clone(), layer_properties.id, layer_properties.epoch, layer.extra_data.borrow().cpu_painting, @@ -165,6 +163,34 @@ impl CompositorData { layer.children().iter().map(get_child_buffer_request).any(|b| b) || redisplay } + // Move the sublayer to an absolute position in page coordinates relative to its parent, + // and clip the layer to the specified size in page coordinates. + // This method returns false if the specified layer is not found. + pub fn set_clipping_rect(layer: Rc>, + pipeline_id: PipelineId, + layer_id: LayerId, + new_rect: Rect) + -> bool { + debug!("compositor_data: starting set_clipping_rect()"); + match CompositorData::find_child_with_pipeline_and_layer_id(layer.clone(), + pipeline_id, + layer_id) { + Some(child_node) => { + debug!("compositor_data: node found for set_clipping_rect()"); + *child_node.bounds.borrow_mut() = new_rect; + true + } + None => { + layer.children().iter() + .any(|kid| CompositorData::set_clipping_rect(kid.clone(), + pipeline_id, + layer_id, + new_rect)) + + } + } + } + pub fn update_layer(layer: Rc>, layer_properties: LayerProperties) { layer.extra_data.borrow_mut().epoch = layer_properties.epoch; layer.extra_data.borrow_mut().unrendered_color = layer_properties.background_color; @@ -181,6 +207,19 @@ impl CompositorData { size); } + fn find_child_with_pipeline_and_layer_id(layer: Rc>, + pipeline_id: PipelineId, + layer_id: LayerId) + -> Option>> { + for kid in layer.children().iter() { + if pipeline_id == kid.extra_data.borrow().pipeline.id && + layer_id == kid.extra_data.borrow().id { + return Some(kid.clone()); + } + } + return None + } + pub fn find_layer_with_pipeline_and_layer_id(layer: Rc>, pipeline_id: PipelineId, layer_id: LayerId) @@ -280,3 +319,4 @@ impl CompositorData { } } } + diff --git a/servo/src/components/compositing/compositor_task.rs b/servo/src/components/compositing/compositor_task.rs index 98dd27601808..4f803413e7cc 100644 --- a/servo/src/components/compositing/compositor_task.rs +++ b/servo/src/components/compositing/compositor_task.rs @@ -38,8 +38,8 @@ pub struct CompositorChan { /// Implementation of the abstract `ScriptListener` interface. impl ScriptListener for CompositorChan { - fn set_ready_state(&self, pipeline_id: PipelineId, ready_state: ReadyState) { - let msg = ChangeReadyState(ready_state, pipeline_id); + fn set_ready_state(&self, ready_state: ReadyState) { + let msg = ChangeReadyState(ready_state); self.chan.send(msg); } @@ -117,6 +117,8 @@ impl RenderListener for CompositorChan { } else { self.chan.send(CreateOrUpdateDescendantLayer(layer_properties)); } + + self.chan.send(SetLayerClipRect(pipeline_id, metadata.id, layer_properties.rect)); } } @@ -131,10 +133,8 @@ impl RenderListener for CompositorChan { self.chan.send(SetLayerClipRect(pipeline_id, layer_id, new_rect)) } - fn set_render_state(&self, - render_state: RenderState, - pipeline_id: PipelineId) { - self.chan.send(ChangeRenderState(render_state, pipeline_id)) + fn set_render_state(&self, render_state: RenderState) { + self.chan.send(ChangeRenderState(render_state)) } } @@ -175,16 +175,15 @@ pub enum Msg { /// layer with that ID exists). CreateOrUpdateDescendantLayer(LayerProperties), /// Alerts the compositor that the specified layer's clipping rect has changed. - /// If LayerId is LayerId::null() then set the pipeline root layer clipping rect. SetLayerClipRect(PipelineId, LayerId, Rect), /// Scroll a page in a window ScrollFragmentPoint(PipelineId, LayerId, Point2D), /// Requests that the compositor paint the given layer buffer set for the given page size. Paint(PipelineId, Epoch, Vec<(LayerId, Box)>), /// Alerts the compositor to the current status of page loading. - ChangeReadyState(ReadyState, PipelineId), + ChangeReadyState(ReadyState), /// Alerts the compositor to the current status of rendering. - ChangeRenderState(RenderState, PipelineId), + ChangeRenderState(RenderState), /// Sets the channel to the current layout and render tasks, along with their id SetIds(SendableFrameTree, Sender<()>, ConstellationChan), /// The load of a page for a given URL has completed. diff --git a/servo/src/components/compositing/constellation.rs b/servo/src/components/compositing/constellation.rs index 5438db602b8b..4d55b25f4f45 100644 --- a/servo/src/components/compositing/constellation.rs +++ b/servo/src/components/compositing/constellation.rs @@ -69,13 +69,11 @@ struct ChildFrameTree { pub rect: Option>, } -#[deriving(Clone)] pub struct SendableFrameTree { pub pipeline: CompositionPipeline, pub children: Vec, } -#[deriving(Clone)] pub struct SendableChildFrameTree { pub frame_tree: SendableFrameTree, pub rect: Option>, diff --git a/servo/src/components/gfx/render_task.rs b/servo/src/components/gfx/render_task.rs index 65b69661a120..d80eb0507154 100644 --- a/servo/src/components/gfx/render_task.rs +++ b/servo/src/components/gfx/render_task.rs @@ -246,7 +246,6 @@ impl RenderTask { } let mut replies = Vec::new(); - self.compositor.set_render_state(RenderingRenderState, self.id); for ReRenderRequest { buffer_requests, scale, layer_id, epoch } in requests.move_iter() { if self.epoch == epoch { @@ -255,7 +254,6 @@ impl RenderTask { debug!("renderer epoch mismatch: {:?} != {:?}", self.epoch, epoch); } } - self.compositor.set_render_state(IdleRenderState, self.id); debug!("render_task: returning surfaces"); self.compositor.paint(self.id, self.epoch, replies); @@ -267,11 +265,17 @@ impl RenderTask { } PaintPermissionGranted => { self.paint_permission = true; - self.epoch.next(); - initialize_layers(&mut self.compositor, - self.id, - self.epoch, - self.render_layers.as_slice()); + + // Here we assume that the main layer—the layer responsible for the page size— + // is the first layer. This is a pretty fragile assumption. It will be fixed + // once we use the layers-based scrolling infrastructure for all scrolling. + if self.render_layers.len() > 1 { + self.epoch.next(); + initialize_layers(&mut self.compositor, + self.id, + self.epoch, + self.render_layers.as_slice()); + } } PaintPermissionRevoked => { self.paint_permission = false; @@ -301,6 +305,8 @@ impl RenderTask { None => return, }; + self.compositor.set_render_state(RenderingRenderState); + // Divide up the layer into tiles. for tile in tiles.iter() { // Optimize the display list for this tile. @@ -437,6 +443,8 @@ impl RenderTask { }; replies.push((render_layer.id, layer_buffer_set)); + self.compositor.set_render_state(IdleRenderState); }) } } + diff --git a/servo/src/components/msg/compositor_msg.rs b/servo/src/components/msg/compositor_msg.rs index 9000f02acc1a..48d7600a0ae5 100644 --- a/servo/src/components/msg/compositor_msg.rs +++ b/servo/src/components/msg/compositor_msg.rs @@ -14,13 +14,13 @@ use std::fmt; use constellation_msg::PipelineId; /// The status of the renderer. -#[deriving(Eq, Ord, PartialOrd, PartialEq, Clone)] +#[deriving(PartialEq, Clone)] pub enum RenderState { - RenderingRenderState, IdleRenderState, + RenderingRenderState, } -#[deriving(Eq, Ord, PartialOrd, PartialEq, Clone)] +#[deriving(PartialEq, Clone)] pub enum ReadyState { /// Informs the compositor that nothing has been done yet. Used for setting status Blank, @@ -33,7 +33,7 @@ pub enum ReadyState { } /// A newtype struct for denoting the age of messages; prevents race conditions. -#[deriving(PartialEq, PartialOrd)] +#[deriving(PartialEq)] pub struct Epoch(pub uint); impl Epoch { @@ -105,13 +105,13 @@ pub trait RenderListener { epoch: Epoch, replies: Vec<(LayerId, Box)>); - fn set_render_state(&self, render_state: RenderState, pipeline_id: PipelineId); + fn set_render_state(&self, render_state: RenderState); } /// The interface used by the script task to tell the compositor to update its ready state, /// which is used in displaying the appropriate message in the window's title. pub trait ScriptListener : Clone { - fn set_ready_state(&self, pipeline_id: PipelineId, ReadyState); + fn set_ready_state(&self, ReadyState); fn scroll_fragment_point(&self, pipeline_id: PipelineId, layer_id: LayerId, diff --git a/servo/src/components/msg/constellation_msg.rs b/servo/src/components/msg/constellation_msg.rs index c546272eabee..1969b7d7513e 100644 --- a/servo/src/components/msg/constellation_msg.rs +++ b/servo/src/components/msg/constellation_msg.rs @@ -76,7 +76,7 @@ pub enum NavigationDirection { Back, } -#[deriving(Clone, PartialEq, Eq, Hash, Encodable, Show)] +#[deriving(Clone, PartialEq, Eq, Hash, Encodable)] pub struct PipelineId(pub uint); #[deriving(Clone, PartialEq, Eq, Hash, Encodable)] diff --git a/servo/src/components/script/page.rs b/servo/src/components/script/page.rs index e2b8720f77b3..98d074787dae 100644 --- a/servo/src/components/script/page.rs +++ b/servo/src/components/script/page.rs @@ -319,7 +319,7 @@ impl Page { self.join_layout(); // Tell the user that we're performing layout. - compositor.set_ready_state(self.id, PerformingLayout); + compositor.set_ready_state(PerformingLayout); // Layout will let us know when it's done. let (join_chan, join_port) = channel(); diff --git a/servo/src/components/script/script_task.rs b/servo/src/components/script/script_task.rs index 51a4c5f3e514..e173a37f7623 100644 --- a/servo/src/components/script/script_task.rs +++ b/servo/src/components/script/script_task.rs @@ -452,7 +452,7 @@ impl ScriptTask { let mut layout_join_port = page.layout_join_port.deref().borrow_mut(); *layout_join_port = None; } - self.compositor.set_ready_state(pipeline_id, FinishedLoading); + self.compositor.set_ready_state(FinishedLoading); } /// Handles a navigate forward or backward message. @@ -549,7 +549,7 @@ impl ScriptTask { let document = Document::new(&*window, Some(url.clone()), HTMLDocument, None).root(); window.deref().init_browser_context(&*document); - self.compositor.set_ready_state(pipeline_id, Loading); + self.compositor.set_ready_state(Loading); // Parse HTML. // // Note: We can parse the next document in parallel with any previous documents.