diff --git a/layers.rs b/layers.rs index 3877716..9c81d6f 100644 --- a/layers.rs +++ b/layers.rs @@ -18,7 +18,7 @@ use platform::surface::{NativeCompositingGraphicsContext, NativePaintingGraphics use std::cell::{RefCell, RefMut}; use std::rc::Rc; -#[deriving(PartialEq)] +#[deriving(Clone, PartialEq, PartialOrd)] pub struct ContentAge { age: uint, } @@ -29,6 +29,7 @@ impl ContentAge { age: 0, } } + pub fn next(&mut self) { self.age += 1; } @@ -113,13 +114,20 @@ pub struct BufferRequest { // The rect in page coordinates that this tile represents pub page_rect: Rect, + + /// The content age of that this BufferRequest corresponds to. + pub content_age: ContentAge, } impl BufferRequest { - pub fn new(screen_rect: Rect, page_rect: Rect) -> BufferRequest { + pub fn new(screen_rect: Rect, + page_rect: Rect, + content_age: ContentAge) + -> BufferRequest { BufferRequest { screen_rect: screen_rect, page_rect: page_rect, + content_age: content_age, } } } @@ -143,6 +151,9 @@ pub struct LayerBuffer { /// Whether or not this buffer was painted with the CPU rasterization. pub painted_with_cpu: bool, + + /// The content age of that this buffer request corresponds to. + pub content_age: ContentAge, } impl LayerBuffer { diff --git a/scene.rs b/scene.rs index c886d54..245b9dc 100755 --- a/scene.rs +++ b/scene.rs @@ -95,5 +95,20 @@ impl Scene { mem::swap(&mut unused_buffers, &mut self.unused_buffers); return unused_buffers; } + + pub fn mark_layer_contents_as_changed_recursively_for_layer(&self, layer: Rc>) { + layer.contents_changed(); + for kid in layer.children().iter() { + self.mark_layer_contents_as_changed_recursively_for_layer(kid.clone()); + } + } + + pub fn mark_layer_contents_as_changed_recursively(&self) { + let root_layer = match self.root { + Some(ref root_layer) => root_layer.clone(), + None => return, + }; + self.mark_layer_contents_as_changed_recursively_for_layer(root_layer); + } } diff --git a/tiling.rs b/tiling.rs index 0d481e7..75cbc35 100644 --- a/tiling.rs +++ b/tiling.rs @@ -24,9 +24,6 @@ pub struct Tile { /// The buffer displayed by this tile. buffer: Option>, - /// The content age of the current buffer. Only valid when buffer is not None. - content_age_of_current_buffer: ContentAge, - /// The content age of any pending buffer request to avoid re-requesting /// a buffer while waiting for it to come back from rendering. content_age_of_pending_buffer: Option, @@ -44,28 +41,27 @@ impl Tile { buffer: None, texture: Zero::zero(), transform: identity(), - content_age_of_current_buffer: ContentAge::new(), content_age_of_pending_buffer: None, } } + fn should_use_new_buffer(&self, new_buffer: &Box) -> bool { + match self.buffer { + Some(ref buffer) => new_buffer.content_age >= buffer.content_age, + None => true, + } + } + fn replace_buffer(&mut self, buffer: Box) -> Option> { + if !self.should_use_new_buffer(&buffer) { + warn!("Layer received an old buffer."); + return Some(buffer); + } + let old_buffer = self.buffer.take(); self.buffer = Some(buffer); self.texture = Zero::zero(); // The old texture is bound to the old buffer. - - // TODO: If content_age_of_pending_buffer is None, that means that we were passed - // a stale buffer at some point. We could handle this situation more gracefully if - // Servo and rust-layers shared Epoch/ContentAge values. That would make using rust-layers - // more complicated though. - match self.content_age_of_pending_buffer { - Some(pending_content_age) => { - self.content_age_of_current_buffer = pending_content_age; - }, - None => warn!("Tile content out of sync with ContentAge count!"), - } self.content_age_of_pending_buffer = None; - return old_buffer; } @@ -96,8 +92,14 @@ impl Tile { } fn should_request_buffer(&self, content_age: ContentAge) -> bool { - if self.buffer.is_some() && self.content_age_of_current_buffer == content_age { - return false; + // Don't resend a request if our buffer's content age matches the current content age. + match self.buffer { + Some(ref buffer) => { + if buffer.content_age >= content_age { + return false; + } + } + None => {} } // Don't resend a request, if we already have one pending. @@ -186,7 +188,7 @@ impl TileGrid { } tile.content_age_of_pending_buffer = Some(current_content_age); - return Some(BufferRequest::new(tile_rect, tile_screen_rect)); + return Some(BufferRequest::new(tile_rect, tile_screen_rect, current_content_age)); } pub fn get_buffer_requests_in_rect(&mut self,