From 1dff6551d5c732b495cae4d027ad69658e6849d5 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Sat, 2 Aug 2014 18:17:00 -0700 Subject: [PATCH 1/2] Track content_age of LayerBuffer in the struct itself Instead of relying on the TileGrid to track content age, just store the information in the LayerBuffer itself. This means that we must pass it with BufferRequests as well, so that the renderer can populate th LayerBuffer properly. --- layers.rs | 15 +++++++++++++-- tiling.rs | 40 +++++++++++++++++++++------------------- 2 files changed, 34 insertions(+), 21 deletions(-) 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/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, From 94d683b9d3a3a78a1f8e902069d5ae0daa451ae6 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Sat, 2 Aug 2014 18:18:22 -0700 Subject: [PATCH 2/2] Add a method marking all tiles as having changed contents --- scene.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) 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); + } }