Better layer resize methods

This commit is contained in:
eschweic 2013-08-08 15:22:02 -07:00 committed by Tim Kuehn
parent 2c44288c26
commit 8993434c39
5 changed files with 76 additions and 30 deletions

View file

@ -136,7 +136,7 @@ impl<C: RenderListener + Send> RenderTask<C> {
match self.port.recv() {
RenderMsg(render_layer) => {
if self.paint_permission {
self.compositor.resize_layer(self.id, render_layer.size);
self.compositor.set_layer_page_size(self.id, render_layer.size);
}
self.render_layer = Some(render_layer);
}
@ -147,7 +147,7 @@ impl<C: RenderListener + Send> RenderTask<C> {
self.paint_permission = true;
match self.render_layer {
Some(ref render_layer) => {
self.compositor.resize_layer(self.id, render_layer.size);
self.compositor.set_layer_page_size(self.id, render_layer.size);
}
None => {}
}

View file

@ -62,7 +62,8 @@ enum MaybeQuadtree {
}
impl CompositorLayer {
/// Creates a new CompositorLayer without a page size that is initially hidden.
/// Creates a new CompositorLayer with an optional page size. If no page size is given,
/// the layer is initially hidden and initialized without a quadtree.
pub fn new(pipeline: Pipeline, page_size: Option<Size2D<f32>>, tile_size: uint, max_mem: Option<uint>)
-> CompositorLayer {
CompositorLayer {
@ -82,6 +83,7 @@ impl CompositorLayer {
}
}
/// Constructs a CompositorLayer tree from a frame tree.
pub fn from_frame_tree(frame_tree: SendableFrameTree,
tile_size: uint,
max_mem: Option<uint>) -> CompositorLayer {
@ -225,6 +227,7 @@ impl CompositorLayer {
// 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.
// If the layer is hidden and has a defined page size, unhide it.
// This method returns false if the specified layer is not found.
pub fn set_clipping_rect(&mut self, pipeline_id: PipelineId, new_rect: Rect<f32>) -> bool {
for child_node in self.children.iter() {
@ -236,6 +239,10 @@ impl CompositorLayer {
new_rect.origin.y,
0.0));
con.scissor = Some(new_rect);
// If possible, unhide child
if child_node.child.hidden && child_node.child.page_size.is_some() {
child_node.child.hidden = false;
}
return true;
}
@ -244,7 +251,8 @@ impl CompositorLayer {
}
// Called when the layer changes size (NOT as a result of a zoom event).
// 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<f32>, window_size: Size2D<f32>) -> bool {
if self.pipeline.id == pipeline_id {
@ -257,27 +265,47 @@ impl CompositorLayer {
tile_size,
max_mem)),
}
// Call scroll for bounds checking of the page shrunk. Use (-1, -1) as the cursor position
// Call scroll for bounds checking if the page shrunk. Use (-1, -1) as the cursor position
// to make sure the scroll isn't propagated downwards.
self.scroll(Point2D(0f32, 0f32), Point2D(-1f32, -1f32), window_size);
self.hidden = false;
return true;
}
self.resize_helper(pipeline_id, new_size)
}
// A helper method to resize sublayers.
fn resize_helper(&mut self, pipeline_id: PipelineId, new_size: Size2D<f32>) -> bool {
for self.children.mut_iter().advance |child_node| {
if pipeline_id != child_node.child.pipeline.id {
loop;
}
let child = &mut child_node.child;
child.page_size = Some(new_size);
// TODO: might get buffers back here
match child.quadtree {
Tree(ref mut quadtree) => quadtree.resize(new_size.width as uint, new_size.height as uint),
NoTree(tile_size, max_mem) => child.quadtree = Tree(Quadtree::new(new_size.width as uint,
new_size.height as uint,
tile_size,
max_mem)),
}
match child_node.container.scissor {
Some(scissor) => {
// Call scroll for bounds checking if the page shrunk. Use (-1, -1) as the cursor position
// to make sure the scroll isn't propagated downwards.
child.scroll(Point2D(0f32, 0f32), Point2D(-1f32, -1f32), scissor.size);
child.hidden = false;
}
None => {} // Nothing to do
}
return true;
}
// ID does not match ours, so recurse on descendents (including hidden children)
let transform = |x: &mut CompositorLayerChild| -> bool {
match x.container.scissor {
Some(scissor) => {
x.child.resize(pipeline_id, new_size, scissor.size)
}
None => {
fail!("CompositorLayer: Child layer not clipped");
}
}
};
self.children.mut_iter().any(transform)
self.children.mut_iter().transform(|x| &mut x.child).any(|x| x.resize_helper(pipeline_id, new_size))
}
// Collect buffers from the quadtree. This method IS NOT recursive, so child CompositorLayers
// are not rebuilt directly from this method.
pub fn build_layer_tree(&mut self) {

View file

@ -87,10 +87,18 @@ impl RenderListener for CompositorChan {
let Size2D { width, height } = page_size;
self.chan.send(NewLayer(id, Size2D(width as f32, height as f32)))
}
fn resize_layer(&self, id: PipelineId, page_size: Size2D<uint>) {
fn set_layer_page_size(&self, id: PipelineId, page_size: Size2D<uint>) {
let Size2D { width, height } = page_size;
self.chan.send(ResizeLayer(id, Size2D(width as f32, height as f32)))
self.chan.send(SetLayerPageSize(id, Size2D(width as f32, height as f32)))
}
fn set_layer_clip_rect(&self, id: PipelineId, new_rect: Rect<uint>) {
let new_rect = Rect(Point2D(new_rect.origin.x as f32,
new_rect.origin.y as f32),
Size2D(new_rect.size.width as f32,
new_rect.size.height as f32));
self.chan.send(SetLayerClipRect(id, new_rect))
}
fn delete_layer(&self, id: PipelineId) {
self.chan.send(DeleteLayer(id))
}
@ -131,8 +139,10 @@ pub enum Msg {
// TODO: Attach epochs to these messages
/// Alerts the compositor that there is a new layer to be rendered.
NewLayer(PipelineId, Size2D<f32>),
/// Alerts the compositor that the specified layer has changed size.
ResizeLayer(PipelineId, Size2D<f32>),
/// Alerts the compositor that the specified layer's page has changed size.
SetLayerPageSize(PipelineId, Size2D<f32>),
/// Alerts the compositor that the specified layer's clipping rect has changed.
SetLayerClipRect(PipelineId, Rect<f32>),
/// Alerts the compositor that the specified layer has been deleted.
DeleteLayer(PipelineId),
/// Invalidate a rect for a given layer
@ -288,15 +298,22 @@ impl CompositorTask {
ask_for_tiles();
}
ResizeLayer(id, new_size) => {
SetLayerPageSize(id, new_size) => {
match compositor_layer {
Some(ref mut layer) => {
let page_window = Size2D(window_size.width as f32 / world_zoom,
window_size.height as f32 / world_zoom);
assert!(layer.resize(id,
Size2D(new_size.width as f32,
new_size.height as f32),
page_window));
assert!(layer.resize(id, new_size, page_window));
ask_for_tiles();
}
None => {}
}
}
SetLayerClipRect(id, new_rect) => {
match compositor_layer {
Some(ref mut layer) => {
assert!(layer.set_clipping_rect(id, new_rect));
ask_for_tiles();
}
None => {}

View file

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use compositing::{CompositorChan, SetIds, ResizeLayer};
use compositing::{CompositorChan, SetIds, SetLayerClipRect};
use script::dom::event::ResizeEvent;
use std::cell::Cell;
@ -412,7 +412,7 @@ impl Constellation {
pipeline.script_chan.send(SendEventMsg(pipeline.id.clone(),
ResizeEvent(width as uint,
height as uint)));
self.compositor_chan.send(ResizeLayer(pipeline.id, rect.size));
self.compositor_chan.send(SetLayerClipRect(pipeline.id, rect));
already_sent.insert(pipeline.id.clone());
break;
}

View file

@ -59,7 +59,8 @@ pub enum ReadyState {
pub trait RenderListener {
fn get_gl_context(&self) -> AzGLContext;
fn new_layer(&self, PipelineId, Size2D<uint>);
fn resize_layer(&self, PipelineId, Size2D<uint>);
fn set_layer_page_size(&self, PipelineId, Size2D<uint>);
fn set_layer_clip_rect(&self, PipelineId, Rect<uint>);
fn delete_layer(&self, PipelineId);
fn paint(&self, id: PipelineId, layer_buffer_set: arc::Arc<LayerBufferSet>);
fn set_render_state(&self, render_state: RenderState);