From 813bb2e43f68089b512b1f53fbdeaf40b39f5b4e Mon Sep 17 00:00:00 2001 From: eschweic Date: Fri, 9 Aug 2013 10:46:26 -0700 Subject: [PATCH] Add Epoch newtype; address review comments --- src/components/gfx/render_task.rs | 22 ++++++------- .../main/compositing/compositor_layer.rs | 32 +++++++++++-------- src/components/main/compositing/mod.rs | 12 +++---- src/components/msg/compositor_msg.rs | 14 ++++++-- 4 files changed, 47 insertions(+), 33 deletions(-) diff --git a/src/components/gfx/render_task.rs b/src/components/gfx/render_task.rs index 4521f9074e9..d91465ae583 100644 --- a/src/components/gfx/render_task.rs +++ b/src/components/gfx/render_task.rs @@ -8,7 +8,7 @@ use azure::{AzFloat, AzGLContext}; use azure::azure_hl::{B8G8R8A8, DrawTarget}; use display_list::DisplayList; use servo_msg::compositor_msg::{RenderListener, IdleRenderState, RenderingRenderState, LayerBuffer}; -use servo_msg::compositor_msg::{LayerBufferSet}; +use servo_msg::compositor_msg::{LayerBufferSet, Epoch}; use servo_msg::constellation_msg::PipelineId; use font_context::FontContext; use geom::matrix2d::Matrix2D; @@ -32,7 +32,7 @@ pub struct RenderLayer { pub enum Msg { RenderMsg(RenderLayer), - ReRenderMsg(~[BufferRequest], f32, PipelineId, uint), + ReRenderMsg(~[BufferRequest], f32, PipelineId, Epoch), PaintPermissionGranted, PaintPermissionRevoked, ExitMsg(Chan<()>), @@ -90,7 +90,7 @@ struct RenderTask { /// Cached copy of last layers rendered last_paint_msg: Option<(arc::Arc, Size2D)>, /// A counter for epoch messages - epoch_counter: uint, + epoch: Epoch, } impl RenderTask { @@ -125,7 +125,7 @@ impl RenderTask { paint_permission: false, last_paint_msg: None, - epoch_counter: 0, + epoch: Epoch(0), }; render_task.start(); @@ -139,24 +139,24 @@ impl RenderTask { match self.port.recv() { RenderMsg(render_layer) => { if self.paint_permission { - self.epoch_counter += 1; - self.compositor.set_layer_page_size(self.id, render_layer.size, self.epoch_counter); + self.epoch.next(); + self.compositor.set_layer_page_size(self.id, render_layer.size, self.epoch); } self.render_layer = Some(render_layer); } ReRenderMsg(tiles, scale, id, epoch) => { - if self.epoch_counter == epoch { + if self.epoch == epoch { self.render(tiles, scale, id); } else { - debug!("renderer epoch mismatch: %? != %?", self.epoch_counter, epoch); + debug!("renderer epoch mismatch: %? != %?", self.epoch, epoch); } } PaintPermissionGranted => { self.paint_permission = true; match self.render_layer { Some(ref render_layer) => { - self.epoch_counter += 1; - self.compositor.set_layer_page_size(self.id, render_layer.size, self.epoch_counter); + self.epoch.next(); + self.compositor.set_layer_page_size(self.id, render_layer.size, self.epoch); } None => {} } @@ -244,7 +244,7 @@ impl RenderTask { debug!("render_task: returning surface"); if self.paint_permission { - self.compositor.paint(id, layer_buffer_set.clone(), self.epoch_counter); + self.compositor.paint(id, layer_buffer_set.clone(), self.epoch); } debug!("caching paint msg"); self.last_paint_msg = Some((layer_buffer_set, render_layer.size)); diff --git a/src/components/main/compositing/compositor_layer.rs b/src/components/main/compositing/compositor_layer.rs index edba5e63569..8aba63008a9 100644 --- a/src/components/main/compositing/compositor_layer.rs +++ b/src/components/main/compositing/compositor_layer.rs @@ -7,7 +7,7 @@ use geom::size::Size2D; use geom::rect::Rect; use geom::matrix::identity; use gfx::render_task::ReRenderMsg; -use servo_msg::compositor_msg::{LayerBuffer, LayerBufferSet}; +use servo_msg::compositor_msg::{LayerBuffer, LayerBufferSet, Epoch}; use servo_msg::constellation_msg::PipelineId; use script::dom::event::{ClickEvent, MouseDownEvent, MouseUpEvent}; use script::script_task::SendEventMsg; @@ -45,7 +45,7 @@ pub struct CompositorLayer { hidden: bool, /// A monotonically increasing counter that keeps track of the current epoch. /// add_buffer() calls that don't match the current epoch will be ignored. - epoch: uint, + epoch: Epoch, } /// Helper struct for keeping CompositorLayer children organized. @@ -82,8 +82,8 @@ impl CompositorLayer { max_mem)), }, root_layer: @mut ContainerLayer(), - hidden: page_size.is_none(), - epoch: 0, + hidden: true, + epoch: Epoch(0), } } @@ -98,20 +98,20 @@ impl CompositorLayer { let container = @mut ContainerLayer(); match rect { Some(rect) => { - container.scissor = Some(Rect(Point2D(100f32, 200f32), Size2D(700f32, 800f32))); - container.common.transform = identity().translate(100f32, 200f32, 0f32); + //container.scissor = Some(Rect(Point2D(100f32, 200f32), Size2D(700f32, 800f32))); + //container.common.transform = identity().translate(100f32, 200f32, 0f32); // FIXME: The top two lines are temporary until layout window sizes are fixed. // When they are, uncomment the next 2 lines: - // container.scissor = Some(rect); - // container.common.transform = identity().translate(rect.origin.x, - // rect.origin.y, - // 0f32); + container.scissor = Some(rect); + container.common.transform = identity().translate(rect.origin.x, + rect.origin.y, + 0f32); } None => {} - }; + } let child_layer = ~CompositorLayer::from_frame_tree(frame_tree, tile_size, max_mem); container.add_child(ContainerLayerKind(child_layer.root_layer)); @@ -124,7 +124,6 @@ impl CompositorLayer { layer } - // Move the layer by as relative specified amount in page coordinates. Does not change // the position of the layer relative to its parent. This also takes in a cursor position // to see if the mouse is over child layers first. If a layer successfully scrolled, returns @@ -276,7 +275,7 @@ impl CompositorLayer { // Set the layer's page size. This signals that the renderer is ready for BufferRequests. // If the layer is hidden and has a defined clipping rect, unhide it. // This method returns false if the specified layer is not found. - pub fn resize(&mut self, pipeline_id: PipelineId, new_size: Size2D, window_size: Size2D, epoch: uint) -> bool { + pub fn resize(&mut self, pipeline_id: PipelineId, new_size: Size2D, window_size: Size2D, epoch: Epoch) -> bool { if self.pipeline.id == pipeline_id { self.epoch = epoch; self.page_size = Some(new_size); @@ -298,8 +297,13 @@ impl CompositorLayer { } // A helper method to resize sublayers. +<<<<<<< HEAD fn resize_helper(&mut self, pipeline_id: PipelineId, new_size: Size2D, epoch: uint) -> bool { for child_node in self.children.mut_iter() { +======= + fn resize_helper(&mut self, pipeline_id: PipelineId, new_size: Size2D, epoch: Epoch) -> bool { + for self.children.mut_iter().advance |child_node| { +>>>>>>> 2ad7d8e... Add Epoch newtype; address review comments if pipeline_id != child_node.child.pipeline.id { loop; } @@ -406,7 +410,7 @@ impl CompositorLayer { // Add LayerBuffers to the specified layer. Returns false if the layer is not found. // If the epoch of the message does not match the layer's epoch, the message is ignored. - pub fn add_buffers(&mut self, pipeline_id: PipelineId, new_buffers: &LayerBufferSet, epoch: uint) -> bool { + pub fn add_buffers(&mut self, pipeline_id: PipelineId, new_buffers: &LayerBufferSet, epoch: Epoch) -> bool { if self.pipeline.id == pipeline_id { if self.epoch != epoch { debug!("compositor epoch mismatch: %? != %?, id: %?", self.epoch, epoch, self.pipeline.id); diff --git a/src/components/main/compositing/mod.rs b/src/components/main/compositing/mod.rs index 13852e1e8b2..a480ee76b39 100644 --- a/src/components/main/compositing/mod.rs +++ b/src/components/main/compositing/mod.rs @@ -11,7 +11,7 @@ use windowing::{ScrollWindowEvent, ZoomWindowEvent, NavigationWindowEvent, Finis use windowing::{QuitWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent, MouseWindowMouseUpEvent}; use servo_msg::compositor_msg::{RenderListener, LayerBufferSet, RenderState}; -use servo_msg::compositor_msg::{ReadyState, ScriptListener}; +use servo_msg::compositor_msg::{ReadyState, ScriptListener, Epoch}; use servo_msg::constellation_msg::{ConstellationChan, NavigateMsg, PipelineId, ResizedWindowMsg, LoadUrlMsg}; use servo_msg::constellation_msg; use gfx::opts::Opts; @@ -79,7 +79,7 @@ impl RenderListener for CompositorChan { port.recv() } - fn paint(&self, id: PipelineId, layer_buffer_set: arc::Arc, epoch: uint) { + fn paint(&self, id: PipelineId, layer_buffer_set: arc::Arc, epoch: Epoch) { self.chan.send(Paint(id, layer_buffer_set, epoch)) } @@ -87,7 +87,7 @@ impl RenderListener for CompositorChan { let Size2D { width, height } = page_size; self.chan.send(NewLayer(id, Size2D(width as f32, height as f32))) } - fn set_layer_page_size(&self, id: PipelineId, page_size: Size2D, epoch: uint) { + fn set_layer_page_size(&self, id: PipelineId, page_size: Size2D, epoch: Epoch) { let Size2D { width, height } = page_size; self.chan.send(SetLayerPageSize(id, Size2D(width as f32, height as f32), epoch)) } @@ -139,7 +139,7 @@ pub enum Msg { /// Alerts the compositor that there is a new layer to be rendered. NewLayer(PipelineId, Size2D), /// Alerts the compositor that the specified layer's page has changed size. - SetLayerPageSize(PipelineId, Size2D, uint), + SetLayerPageSize(PipelineId, Size2D, Epoch), /// Alerts the compositor that the specified layer's clipping rect has changed. SetLayerClipRect(PipelineId, Rect), /// Alerts the compositor that the specified layer has been deleted. @@ -148,7 +148,7 @@ pub enum Msg { InvalidateRect(PipelineId, Rect), /// Requests that the compositor paint the given layer buffer set for the given page size. - Paint(PipelineId, arc::Arc, uint), + Paint(PipelineId, arc::Arc, Epoch), /// Alerts the compositor to the current status of page loading. ChangeReadyState(ReadyState), /// Alerts the compositor to the current status of rendering. @@ -238,7 +238,7 @@ impl CompositorTask { recomposite = layer.get_buffer_request(Rect(Point2D(0f32, 0f32), window_size_page), world_zoom) || recomposite; } else { - debug!("layer is hidden!"); //eschweic + debug!("Compositor: root layer is hidden!"); } } }; diff --git a/src/components/msg/compositor_msg.rs b/src/components/msg/compositor_msg.rs index 929b5a158d3..949f418c317 100644 --- a/src/components/msg/compositor_msg.rs +++ b/src/components/msg/compositor_msg.rs @@ -54,15 +54,25 @@ pub enum ReadyState { FinishedLoading, } +/// A newtype struct for denoting the age of messages; prevents race conditions. +#[deriving(Eq)] +pub struct Epoch(uint); + +impl Epoch { + pub fn next(&mut self) { + **self += 1; + } +} + /// The interface used by the renderer to acquire draw targets for each render frame and /// submit them to be drawn to the display. pub trait RenderListener { fn get_gl_context(&self) -> AzGLContext; fn new_layer(&self, PipelineId, Size2D); - fn set_layer_page_size(&self, PipelineId, Size2D, uint); + fn set_layer_page_size(&self, PipelineId, Size2D, Epoch); fn set_layer_clip_rect(&self, PipelineId, Rect); fn delete_layer(&self, PipelineId); - fn paint(&self, id: PipelineId, layer_buffer_set: arc::Arc, uint); + fn paint(&self, id: PipelineId, layer_buffer_set: arc::Arc, Epoch); fn set_render_state(&self, render_state: RenderState); }