mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Better layer resize methods
This commit is contained in:
parent
2c44288c26
commit
8993434c39
5 changed files with 76 additions and 30 deletions
|
@ -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 => {}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 => {}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue