Add Epoch newtype; address review comments

This commit is contained in:
eschweic 2013-08-09 10:46:26 -07:00 committed by Tim Kuehn
parent 70cb58f2cf
commit 813bb2e43f
4 changed files with 47 additions and 33 deletions

View file

@ -8,7 +8,7 @@ use azure::{AzFloat, AzGLContext};
use azure::azure_hl::{B8G8R8A8, DrawTarget}; use azure::azure_hl::{B8G8R8A8, DrawTarget};
use display_list::DisplayList; use display_list::DisplayList;
use servo_msg::compositor_msg::{RenderListener, IdleRenderState, RenderingRenderState, LayerBuffer}; 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 servo_msg::constellation_msg::PipelineId;
use font_context::FontContext; use font_context::FontContext;
use geom::matrix2d::Matrix2D; use geom::matrix2d::Matrix2D;
@ -32,7 +32,7 @@ pub struct RenderLayer {
pub enum Msg { pub enum Msg {
RenderMsg(RenderLayer), RenderMsg(RenderLayer),
ReRenderMsg(~[BufferRequest], f32, PipelineId, uint), ReRenderMsg(~[BufferRequest], f32, PipelineId, Epoch),
PaintPermissionGranted, PaintPermissionGranted,
PaintPermissionRevoked, PaintPermissionRevoked,
ExitMsg(Chan<()>), ExitMsg(Chan<()>),
@ -90,7 +90,7 @@ struct RenderTask<C> {
/// Cached copy of last layers rendered /// Cached copy of last layers rendered
last_paint_msg: Option<(arc::Arc<LayerBufferSet>, Size2D<uint>)>, last_paint_msg: Option<(arc::Arc<LayerBufferSet>, Size2D<uint>)>,
/// A counter for epoch messages /// A counter for epoch messages
epoch_counter: uint, epoch: Epoch,
} }
impl<C: RenderListener + Send> RenderTask<C> { impl<C: RenderListener + Send> RenderTask<C> {
@ -125,7 +125,7 @@ impl<C: RenderListener + Send> RenderTask<C> {
paint_permission: false, paint_permission: false,
last_paint_msg: None, last_paint_msg: None,
epoch_counter: 0, epoch: Epoch(0),
}; };
render_task.start(); render_task.start();
@ -139,24 +139,24 @@ impl<C: RenderListener + Send> RenderTask<C> {
match self.port.recv() { match self.port.recv() {
RenderMsg(render_layer) => { RenderMsg(render_layer) => {
if self.paint_permission { if self.paint_permission {
self.epoch_counter += 1; self.epoch.next();
self.compositor.set_layer_page_size(self.id, render_layer.size, self.epoch_counter); self.compositor.set_layer_page_size(self.id, render_layer.size, self.epoch);
} }
self.render_layer = Some(render_layer); self.render_layer = Some(render_layer);
} }
ReRenderMsg(tiles, scale, id, epoch) => { ReRenderMsg(tiles, scale, id, epoch) => {
if self.epoch_counter == epoch { if self.epoch == epoch {
self.render(tiles, scale, id); self.render(tiles, scale, id);
} else { } else {
debug!("renderer epoch mismatch: %? != %?", self.epoch_counter, epoch); debug!("renderer epoch mismatch: %? != %?", self.epoch, epoch);
} }
} }
PaintPermissionGranted => { PaintPermissionGranted => {
self.paint_permission = true; self.paint_permission = true;
match self.render_layer { match self.render_layer {
Some(ref render_layer) => { Some(ref render_layer) => {
self.epoch_counter += 1; self.epoch.next();
self.compositor.set_layer_page_size(self.id, render_layer.size, self.epoch_counter); self.compositor.set_layer_page_size(self.id, render_layer.size, self.epoch);
} }
None => {} None => {}
} }
@ -244,7 +244,7 @@ impl<C: RenderListener + Send> RenderTask<C> {
debug!("render_task: returning surface"); debug!("render_task: returning surface");
if self.paint_permission { 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"); debug!("caching paint msg");
self.last_paint_msg = Some((layer_buffer_set, render_layer.size)); self.last_paint_msg = Some((layer_buffer_set, render_layer.size));

View file

@ -7,7 +7,7 @@ use geom::size::Size2D;
use geom::rect::Rect; use geom::rect::Rect;
use geom::matrix::identity; use geom::matrix::identity;
use gfx::render_task::ReRenderMsg; 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 servo_msg::constellation_msg::PipelineId;
use script::dom::event::{ClickEvent, MouseDownEvent, MouseUpEvent}; use script::dom::event::{ClickEvent, MouseDownEvent, MouseUpEvent};
use script::script_task::SendEventMsg; use script::script_task::SendEventMsg;
@ -45,7 +45,7 @@ pub struct CompositorLayer {
hidden: bool, hidden: bool,
/// A monotonically increasing counter that keeps track of the current epoch. /// A monotonically increasing counter that keeps track of the current epoch.
/// add_buffer() calls that don't match the current epoch will be ignored. /// add_buffer() calls that don't match the current epoch will be ignored.
epoch: uint, epoch: Epoch,
} }
/// Helper struct for keeping CompositorLayer children organized. /// Helper struct for keeping CompositorLayer children organized.
@ -82,8 +82,8 @@ impl CompositorLayer {
max_mem)), max_mem)),
}, },
root_layer: @mut ContainerLayer(), root_layer: @mut ContainerLayer(),
hidden: page_size.is_none(), hidden: true,
epoch: 0, epoch: Epoch(0),
} }
} }
@ -98,20 +98,20 @@ impl CompositorLayer {
let container = @mut ContainerLayer(); let container = @mut ContainerLayer();
match rect { match rect {
Some(rect) => { Some(rect) => {
container.scissor = Some(Rect(Point2D(100f32, 200f32), Size2D(700f32, 800f32))); //container.scissor = Some(Rect(Point2D(100f32, 200f32), Size2D(700f32, 800f32)));
container.common.transform = identity().translate(100f32, 200f32, 0f32); //container.common.transform = identity().translate(100f32, 200f32, 0f32);
// FIXME: The top two lines are temporary until layout window sizes are fixed. // FIXME: The top two lines are temporary until layout window sizes are fixed.
// When they are, uncomment the next 2 lines: // When they are, uncomment the next 2 lines:
// container.scissor = Some(rect); container.scissor = Some(rect);
// container.common.transform = identity().translate(rect.origin.x, container.common.transform = identity().translate(rect.origin.x,
// rect.origin.y, rect.origin.y,
// 0f32); 0f32);
} }
None => {} None => {}
}; }
let child_layer = ~CompositorLayer::from_frame_tree(frame_tree, tile_size, max_mem); let child_layer = ~CompositorLayer::from_frame_tree(frame_tree, tile_size, max_mem);
container.add_child(ContainerLayerKind(child_layer.root_layer)); container.add_child(ContainerLayerKind(child_layer.root_layer));
@ -124,7 +124,6 @@ impl CompositorLayer {
layer layer
} }
// Move the layer by as relative specified amount in page coordinates. Does not change // 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 // 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 // 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. // 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. // If the layer is hidden and has a defined clipping rect, unhide it.
// This method returns false if the specified layer is not found. // This method returns false if the specified layer is not found.
pub fn resize(&mut self, pipeline_id: PipelineId, new_size: Size2D<f32>, window_size: Size2D<f32>, epoch: uint) -> bool { pub fn resize(&mut self, pipeline_id: PipelineId, new_size: Size2D<f32>, window_size: Size2D<f32>, epoch: Epoch) -> bool {
if self.pipeline.id == pipeline_id { if self.pipeline.id == pipeline_id {
self.epoch = epoch; self.epoch = epoch;
self.page_size = Some(new_size); self.page_size = Some(new_size);
@ -298,8 +297,13 @@ impl CompositorLayer {
} }
// A helper method to resize sublayers. // A helper method to resize sublayers.
<<<<<<< HEAD
fn resize_helper(&mut self, pipeline_id: PipelineId, new_size: Size2D<f32>, epoch: uint) -> bool { fn resize_helper(&mut self, pipeline_id: PipelineId, new_size: Size2D<f32>, epoch: uint) -> bool {
for child_node in self.children.mut_iter() { for child_node in self.children.mut_iter() {
=======
fn resize_helper(&mut self, pipeline_id: PipelineId, new_size: Size2D<f32>, 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 { if pipeline_id != child_node.child.pipeline.id {
loop; loop;
} }
@ -406,7 +410,7 @@ impl CompositorLayer {
// Add LayerBuffers to the specified layer. Returns false if the layer is not found. // 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. // 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.pipeline.id == pipeline_id {
if self.epoch != epoch { if self.epoch != epoch {
debug!("compositor epoch mismatch: %? != %?, id: %?", self.epoch, epoch, self.pipeline.id); debug!("compositor epoch mismatch: %? != %?, id: %?", self.epoch, epoch, self.pipeline.id);

View file

@ -11,7 +11,7 @@ use windowing::{ScrollWindowEvent, ZoomWindowEvent, NavigationWindowEvent, Finis
use windowing::{QuitWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent, MouseWindowMouseUpEvent}; use windowing::{QuitWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent, MouseWindowMouseUpEvent};
use servo_msg::compositor_msg::{RenderListener, LayerBufferSet, RenderState}; 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::{ConstellationChan, NavigateMsg, PipelineId, ResizedWindowMsg, LoadUrlMsg};
use servo_msg::constellation_msg; use servo_msg::constellation_msg;
use gfx::opts::Opts; use gfx::opts::Opts;
@ -79,7 +79,7 @@ impl RenderListener for CompositorChan {
port.recv() port.recv()
} }
fn paint(&self, id: PipelineId, layer_buffer_set: arc::Arc<LayerBufferSet>, epoch: uint) { fn paint(&self, id: PipelineId, layer_buffer_set: arc::Arc<LayerBufferSet>, epoch: Epoch) {
self.chan.send(Paint(id, layer_buffer_set, epoch)) self.chan.send(Paint(id, layer_buffer_set, epoch))
} }
@ -87,7 +87,7 @@ impl RenderListener for CompositorChan {
let Size2D { width, height } = page_size; let Size2D { width, height } = page_size;
self.chan.send(NewLayer(id, Size2D(width as f32, height as f32))) self.chan.send(NewLayer(id, Size2D(width as f32, height as f32)))
} }
fn set_layer_page_size(&self, id: PipelineId, page_size: Size2D<uint>, epoch: uint) { fn set_layer_page_size(&self, id: PipelineId, page_size: Size2D<uint>, epoch: Epoch) {
let Size2D { width, height } = page_size; let Size2D { width, height } = page_size;
self.chan.send(SetLayerPageSize(id, Size2D(width as f32, height as f32), epoch)) 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. /// Alerts the compositor that there is a new layer to be rendered.
NewLayer(PipelineId, Size2D<f32>), NewLayer(PipelineId, Size2D<f32>),
/// Alerts the compositor that the specified layer's page has changed size. /// Alerts the compositor that the specified layer's page has changed size.
SetLayerPageSize(PipelineId, Size2D<f32>, uint), SetLayerPageSize(PipelineId, Size2D<f32>, Epoch),
/// Alerts the compositor that the specified layer's clipping rect has changed. /// Alerts the compositor that the specified layer's clipping rect has changed.
SetLayerClipRect(PipelineId, Rect<f32>), SetLayerClipRect(PipelineId, Rect<f32>),
/// Alerts the compositor that the specified layer has been deleted. /// Alerts the compositor that the specified layer has been deleted.
@ -148,7 +148,7 @@ pub enum Msg {
InvalidateRect(PipelineId, Rect<uint>), InvalidateRect(PipelineId, Rect<uint>),
/// Requests that the compositor paint the given layer buffer set for the given page size. /// Requests that the compositor paint the given layer buffer set for the given page size.
Paint(PipelineId, arc::Arc<LayerBufferSet>, uint), Paint(PipelineId, arc::Arc<LayerBufferSet>, Epoch),
/// Alerts the compositor to the current status of page loading. /// Alerts the compositor to the current status of page loading.
ChangeReadyState(ReadyState), ChangeReadyState(ReadyState),
/// Alerts the compositor to the current status of rendering. /// 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), recomposite = layer.get_buffer_request(Rect(Point2D(0f32, 0f32), window_size_page),
world_zoom) || recomposite; world_zoom) || recomposite;
} else { } else {
debug!("layer is hidden!"); //eschweic debug!("Compositor: root layer is hidden!");
} }
} }
}; };

View file

@ -54,15 +54,25 @@ pub enum ReadyState {
FinishedLoading, 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 /// The interface used by the renderer to acquire draw targets for each render frame and
/// submit them to be drawn to the display. /// submit them to be drawn to the display.
pub trait RenderListener { pub trait RenderListener {
fn get_gl_context(&self) -> AzGLContext; fn get_gl_context(&self) -> AzGLContext;
fn new_layer(&self, PipelineId, Size2D<uint>); fn new_layer(&self, PipelineId, Size2D<uint>);
fn set_layer_page_size(&self, PipelineId, Size2D<uint>, uint); fn set_layer_page_size(&self, PipelineId, Size2D<uint>, Epoch);
fn set_layer_clip_rect(&self, PipelineId, Rect<uint>); fn set_layer_clip_rect(&self, PipelineId, Rect<uint>);
fn delete_layer(&self, PipelineId); fn delete_layer(&self, PipelineId);
fn paint(&self, id: PipelineId, layer_buffer_set: arc::Arc<LayerBufferSet>, uint); fn paint(&self, id: PipelineId, layer_buffer_set: arc::Arc<LayerBufferSet>, Epoch);
fn set_render_state(&self, render_state: RenderState); fn set_render_state(&self, render_state: RenderState);
} }