mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
Merge pull request #2788 from mrobinson/compositor-cleanup
Make compositor layer creation atomic
This commit is contained in:
commit
396cbb4bee
4 changed files with 151 additions and 259 deletions
|
@ -3,9 +3,8 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use compositor_data::CompositorData;
|
use compositor_data::CompositorData;
|
||||||
use compositor_task::{Msg, CompositorTask, Exit, ChangeReadyState, SetUnRenderedColor};
|
use compositor_task::{Msg, CompositorTask, Exit, ChangeReadyState, SetIds, LayerProperties};
|
||||||
use compositor_task::{SetIds, GetGraphicsMetadata, CreateRootCompositorLayerIfNecessary};
|
use compositor_task::{GetGraphicsMetadata, CreateOrUpdateRootLayer, CreateOrUpdateDescendantLayer};
|
||||||
use compositor_task::{CreateDescendantCompositorLayerIfNecessary, SetLayerPageSize};
|
|
||||||
use compositor_task::{SetLayerClipRect, Paint, ScrollFragmentPoint, LoadComplete};
|
use compositor_task::{SetLayerClipRect, Paint, ScrollFragmentPoint, LoadComplete};
|
||||||
use compositor_task::{ShutdownComplete, ChangeRenderState};
|
use compositor_task::{ShutdownComplete, ChangeRenderState};
|
||||||
use constellation::SendableFrameTree;
|
use constellation::SendableFrameTree;
|
||||||
|
@ -19,12 +18,12 @@ use windowing::{QuitWindowEvent, RefreshWindowEvent, ResizeWindowEvent, ScrollWi
|
||||||
use windowing::{WindowEvent, WindowMethods, WindowNavigateMsg, ZoomWindowEvent};
|
use windowing::{WindowEvent, WindowMethods, WindowNavigateMsg, ZoomWindowEvent};
|
||||||
use windowing::PinchZoomWindowEvent;
|
use windowing::PinchZoomWindowEvent;
|
||||||
|
|
||||||
use azure::azure_hl::{SourceSurfaceMethods, Color};
|
use azure::azure_hl::SourceSurfaceMethods;
|
||||||
use azure::azure_hl;
|
use azure::azure_hl;
|
||||||
use geom::matrix::identity;
|
use geom::matrix::identity;
|
||||||
use geom::point::{Point2D, TypedPoint2D};
|
use geom::point::{Point2D, TypedPoint2D};
|
||||||
use geom::rect::Rect;
|
use geom::rect::Rect;
|
||||||
use geom::size::{Size2D, TypedSize2D};
|
use geom::size::TypedSize2D;
|
||||||
use geom::scale_factor::ScaleFactor;
|
use geom::scale_factor::ScaleFactor;
|
||||||
use layers::layers::LayerBufferSet;
|
use layers::layers::LayerBufferSet;
|
||||||
use layers::platform::surface::NativeCompositingGraphicsContext;
|
use layers::platform::surface::NativeCompositingGraphicsContext;
|
||||||
|
@ -35,7 +34,7 @@ use layers::layers::Layer;
|
||||||
use opengles::gl2;
|
use opengles::gl2;
|
||||||
use png;
|
use png;
|
||||||
use servo_msg::compositor_msg::{Blank, Epoch, FinishedLoading, IdleRenderState};
|
use servo_msg::compositor_msg::{Blank, Epoch, FinishedLoading, IdleRenderState};
|
||||||
use servo_msg::compositor_msg::{LayerId, ReadyState, RenderState, ScrollPolicy, Scrollable};
|
use servo_msg::compositor_msg::{LayerId, ReadyState, RenderState};
|
||||||
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, LoadUrlMsg, NavigateMsg};
|
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, LoadUrlMsg, NavigateMsg};
|
||||||
use servo_msg::constellation_msg::{PipelineId, ResizedWindowMsg, WindowSizeData};
|
use servo_msg::constellation_msg::{PipelineId, ResizedWindowMsg, WindowSizeData};
|
||||||
use servo_msg::constellation_msg;
|
use servo_msg::constellation_msg;
|
||||||
|
@ -279,10 +278,6 @@ impl IOCompositor {
|
||||||
self.change_render_state(render_state);
|
self.change_render_state(render_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
(Ok(SetUnRenderedColor(pipeline_id, layer_id, color)), NotShuttingDown) => {
|
|
||||||
self.set_unrendered_color(pipeline_id, layer_id, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
(Ok(SetIds(frame_tree, response_chan, new_constellation_chan)), _) => {
|
(Ok(SetIds(frame_tree, response_chan, new_constellation_chan)), _) => {
|
||||||
self.set_ids(frame_tree, response_chan, new_constellation_chan);
|
self.set_ids(frame_tree, response_chan, new_constellation_chan);
|
||||||
}
|
}
|
||||||
|
@ -291,27 +286,14 @@ impl IOCompositor {
|
||||||
chan.send(Some(azure_hl::current_graphics_metadata()));
|
chan.send(Some(azure_hl::current_graphics_metadata()));
|
||||||
}
|
}
|
||||||
|
|
||||||
(Ok(CreateRootCompositorLayerIfNecessary(pipeline_id, layer_id, size, color)),
|
(Ok(CreateOrUpdateRootLayer(layer_properties)),
|
||||||
NotShuttingDown) => {
|
NotShuttingDown) => {
|
||||||
self.create_root_compositor_layer_if_necessary(pipeline_id,
|
self.create_or_update_root_layer(layer_properties);
|
||||||
layer_id,
|
|
||||||
size,
|
|
||||||
color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(Ok(CreateDescendantCompositorLayerIfNecessary(pipeline_id,
|
(Ok(CreateOrUpdateDescendantLayer(layer_properties)),
|
||||||
layer_id,
|
|
||||||
rect,
|
|
||||||
scroll_behavior)),
|
|
||||||
NotShuttingDown) => {
|
NotShuttingDown) => {
|
||||||
self.create_descendant_compositor_layer_if_necessary(pipeline_id,
|
self.create_or_update_descendant_layer(layer_properties);
|
||||||
layer_id,
|
|
||||||
rect,
|
|
||||||
scroll_behavior);
|
|
||||||
}
|
|
||||||
|
|
||||||
(Ok(SetLayerPageSize(pipeline_id, layer_id, new_size, epoch)), NotShuttingDown) => {
|
|
||||||
self.set_layer_page_size(pipeline_id, layer_id, new_size, epoch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(Ok(SetLayerClipRect(pipeline_id, layer_id, new_rect)), NotShuttingDown) => {
|
(Ok(SetLayerClipRect(pipeline_id, layer_id, new_rect)), NotShuttingDown) => {
|
||||||
|
@ -346,20 +328,6 @@ impl IOCompositor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_unrendered_color(&mut self, pipeline_id: PipelineId, layer_id: LayerId, color: Color) {
|
|
||||||
match self.scene.root {
|
|
||||||
Some(ref root_layer) => {
|
|
||||||
match CompositorData::find_layer_with_pipeline_and_layer_id(root_layer.clone(),
|
|
||||||
pipeline_id,
|
|
||||||
layer_id) {
|
|
||||||
Some(ref layer) => CompositorData::set_unrendered_color(layer.clone(), color),
|
|
||||||
None => { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_ids(&mut self,
|
fn set_ids(&mut self,
|
||||||
frame_tree: SendableFrameTree,
|
frame_tree: SendableFrameTree,
|
||||||
response_chan: Sender<()>,
|
response_chan: Sender<()>,
|
||||||
|
@ -373,40 +341,41 @@ impl IOCompositor {
|
||||||
self.send_window_size();
|
self.send_window_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_root_compositor_layer_if_necessary(&mut self,
|
fn update_layer_if_exists(&mut self, properties: LayerProperties) -> bool {
|
||||||
id: PipelineId,
|
match self.scene.root {
|
||||||
layer_id: LayerId,
|
Some(ref root_layer) => {
|
||||||
size: Size2D<f32>,
|
match CompositorData::find_layer_with_pipeline_and_layer_id(root_layer.clone(),
|
||||||
unrendered_color: Color) {
|
properties.pipeline_id,
|
||||||
let (root_pipeline, root_layer_id) = match self.scene.root {
|
properties.id) {
|
||||||
Some(ref root_layer) if root_layer.extra_data.borrow().pipeline.id == id => {
|
Some(existing_layer) => {
|
||||||
(root_layer.extra_data.borrow().pipeline.clone(),
|
CompositorData::update_layer(existing_layer.clone(), properties);
|
||||||
CompositorData::id_of_first_child(root_layer.clone()))
|
true
|
||||||
|
}
|
||||||
|
None => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
None => false,
|
||||||
match self.root_pipeline {
|
}
|
||||||
Some(ref root_pipeline) => {
|
}
|
||||||
(root_pipeline.clone(), LayerId::null())
|
|
||||||
},
|
|
||||||
_ => fail!("Compositor: Received new layer without initialized pipeline"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if layer_id != root_layer_id {
|
fn create_or_update_root_layer(&mut self, layer_properties: LayerProperties) {
|
||||||
|
let need_new_root_layer = !self.update_layer_if_exists(layer_properties);
|
||||||
|
if need_new_root_layer {
|
||||||
|
let root_pipeline = match self.root_pipeline {
|
||||||
|
Some(ref root_pipeline) => root_pipeline.clone(),
|
||||||
|
None => fail!("Compositor: Making new layer without initialized pipeline"),
|
||||||
|
};
|
||||||
let new_compositor_data = CompositorData::new_root(root_pipeline,
|
let new_compositor_data = CompositorData::new_root(root_pipeline,
|
||||||
size,
|
layer_properties.epoch,
|
||||||
self.opts.cpu_painting);
|
layer_properties.rect.size,
|
||||||
|
self.opts.cpu_painting,
|
||||||
|
layer_properties.background_color);
|
||||||
|
let size = layer_properties.rect.size;
|
||||||
let new_root = Rc::new(Layer::new(size,
|
let new_root = Rc::new(Layer::new(size,
|
||||||
self.opts.tile_size,
|
self.opts.tile_size,
|
||||||
new_compositor_data));
|
new_compositor_data));
|
||||||
new_root.extra_data.borrow_mut().unrendered_color = unrendered_color;
|
|
||||||
|
|
||||||
CompositorData::add_child_if_necessary(new_root.clone(),
|
CompositorData::add_child(new_root.clone(), layer_properties, size);
|
||||||
layer_id,
|
|
||||||
Rect(Point2D(0f32, 0f32), size),
|
|
||||||
size,
|
|
||||||
Scrollable);
|
|
||||||
|
|
||||||
// Release all tiles from the layer before dropping it.
|
// Release all tiles from the layer before dropping it.
|
||||||
match self.scene.root {
|
match self.scene.root {
|
||||||
|
@ -416,27 +385,30 @@ impl IOCompositor {
|
||||||
self.scene.root = Some(new_root);
|
self.scene.root = Some(new_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.scroll_layer_to_fragment_point_if_necessary(layer_properties.pipeline_id,
|
||||||
|
layer_properties.id);
|
||||||
self.ask_for_tiles();
|
self.ask_for_tiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_descendant_compositor_layer_if_necessary(&mut self,
|
fn create_or_update_descendant_layer(&mut self, layer_properties: LayerProperties) {
|
||||||
pipeline_id: PipelineId,
|
if !self.update_layer_if_exists(layer_properties) {
|
||||||
layer_id: LayerId,
|
self.create_descendant_layer(layer_properties);
|
||||||
rect: Rect<f32>,
|
}
|
||||||
scroll_policy: ScrollPolicy) {
|
self.scroll_layer_to_fragment_point_if_necessary(layer_properties.pipeline_id,
|
||||||
|
layer_properties.id);
|
||||||
|
self.ask_for_tiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_descendant_layer(&self, layer_properties: LayerProperties) {
|
||||||
match self.scene.root {
|
match self.scene.root {
|
||||||
Some(ref root_layer) => {
|
Some(ref root_layer) => {
|
||||||
let parent_layer_id = root_layer.extra_data.borrow().id;
|
let parent_layer_id = root_layer.extra_data.borrow().id;
|
||||||
match CompositorData::find_layer_with_pipeline_and_layer_id(root_layer.clone(),
|
match CompositorData::find_layer_with_pipeline_and_layer_id(root_layer.clone(),
|
||||||
pipeline_id,
|
layer_properties.pipeline_id,
|
||||||
parent_layer_id) {
|
parent_layer_id) {
|
||||||
Some(ref mut parent_layer) => {
|
Some(ref mut parent_layer) => {
|
||||||
let page_size = root_layer.extra_data.borrow().page_size.unwrap();
|
let page_size = root_layer.extra_data.borrow().page_size.unwrap();
|
||||||
CompositorData::add_child_if_necessary(parent_layer.clone(),
|
CompositorData::add_child(parent_layer.clone(), layer_properties, page_size);
|
||||||
layer_id,
|
|
||||||
rect,
|
|
||||||
page_size,
|
|
||||||
scroll_policy);
|
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
fail!("Compositor: couldn't find parent layer");
|
fail!("Compositor: couldn't find parent layer");
|
||||||
|
@ -445,8 +417,6 @@ impl IOCompositor {
|
||||||
}
|
}
|
||||||
None => fail!("Compositor: Received new layer without initialized pipeline")
|
None => fail!("Compositor: Received new layer without initialized pipeline")
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ask_for_tiles();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The size of the content area in CSS px at the current zoom level
|
/// The size of the content area in CSS px at the current zoom level
|
||||||
|
@ -467,33 +437,24 @@ impl IOCompositor {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_layer_page_size(&mut self,
|
fn scroll_layer_to_fragment_point_if_necessary(&mut self,
|
||||||
pipeline_id: PipelineId,
|
pipeline_id: PipelineId,
|
||||||
layer_id: LayerId,
|
layer_id: LayerId) {
|
||||||
new_size: Size2D<f32>,
|
|
||||||
epoch: Epoch) {
|
|
||||||
let page_window = self.page_window();
|
let page_window = self.page_window();
|
||||||
let (ask, move): (bool, bool) = match self.scene.root {
|
let needs_recomposite = match self.scene.root {
|
||||||
Some(ref layer) => {
|
Some(ref mut root_layer) => {
|
||||||
CompositorData::resize(layer.clone(),
|
self.fragment_point.take().map_or(false, |fragment_point| {
|
||||||
pipeline_id,
|
CompositorData::move(root_layer.clone(),
|
||||||
layer_id,
|
pipeline_id,
|
||||||
new_size,
|
layer_id,
|
||||||
page_window,
|
fragment_point,
|
||||||
epoch);
|
page_window)
|
||||||
let move = self.fragment_point.take().map_or(false, |point| {
|
})
|
||||||
CompositorData::move(layer.clone(), pipeline_id, layer_id, point, page_window)
|
|
||||||
});
|
|
||||||
|
|
||||||
(true, move)
|
|
||||||
}
|
}
|
||||||
None => (false, false)
|
None => fail!("Compositor: Tried to scroll to fragment without root layer."),
|
||||||
};
|
};
|
||||||
|
|
||||||
if ask {
|
self.recomposite_if(needs_recomposite);
|
||||||
self.recomposite_if(move);
|
|
||||||
self.ask_for_tiles();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_layer_clip_rect(&mut self,
|
fn set_layer_clip_rect(&mut self,
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use compositor_task::LayerProperties;
|
||||||
use pipeline::CompositionPipeline;
|
use pipeline::CompositionPipeline;
|
||||||
use windowing::{MouseWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent};
|
use windowing::{MouseWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent};
|
||||||
use windowing::{MouseWindowMouseUpEvent};
|
use windowing::{MouseWindowMouseUpEvent};
|
||||||
|
@ -13,7 +14,6 @@ use geom::point::{Point2D, TypedPoint2D};
|
||||||
use geom::rect::{Rect, TypedRect};
|
use geom::rect::{Rect, TypedRect};
|
||||||
use geom::size::{Size2D, TypedSize2D};
|
use geom::size::{Size2D, TypedSize2D};
|
||||||
use gfx::render_task::{ReRenderMsg, UnusedBufferMsg};
|
use gfx::render_task::{ReRenderMsg, UnusedBufferMsg};
|
||||||
use gfx;
|
|
||||||
use layers::layers::{Layer, Flip, LayerBuffer, LayerBufferSet, NoFlip, TextureLayer};
|
use layers::layers::{Layer, Flip, LayerBuffer, LayerBufferSet, NoFlip, TextureLayer};
|
||||||
use layers::quadtree::{Tile, Normal, Hidden};
|
use layers::quadtree::{Tile, Normal, Hidden};
|
||||||
use layers::platform::surface::{NativeCompositingGraphicsContext, NativeSurfaceMethods};
|
use layers::platform::surface::{NativeCompositingGraphicsContext, NativeSurfaceMethods};
|
||||||
|
@ -103,77 +103,67 @@ impl Clampable for f32 {
|
||||||
impl CompositorData {
|
impl CompositorData {
|
||||||
pub fn new(pipeline: CompositionPipeline,
|
pub fn new(pipeline: CompositionPipeline,
|
||||||
layer_id: LayerId,
|
layer_id: LayerId,
|
||||||
|
epoch: Epoch,
|
||||||
bounds: Rect<f32>,
|
bounds: Rect<f32>,
|
||||||
page_size: Option<Size2D<f32>>,
|
page_size: Option<Size2D<f32>>,
|
||||||
cpu_painting: bool,
|
cpu_painting: bool,
|
||||||
wants_scroll_events: WantsScrollEventsFlag,
|
wants_scroll_events: WantsScrollEventsFlag,
|
||||||
scroll_policy: ScrollPolicy,
|
scroll_policy: ScrollPolicy,
|
||||||
hidden: bool) -> CompositorData {
|
unrendered_color: Color)
|
||||||
|
-> CompositorData {
|
||||||
CompositorData {
|
CompositorData {
|
||||||
pipeline: pipeline,
|
pipeline: pipeline,
|
||||||
id: layer_id,
|
id: layer_id,
|
||||||
scroll_offset: TypedPoint2D(0f32, 0f32),
|
scroll_offset: TypedPoint2D(0f32, 0f32),
|
||||||
bounds: bounds,
|
bounds: bounds,
|
||||||
page_size: page_size,
|
page_size: page_size,
|
||||||
hidden: hidden,
|
hidden: false,
|
||||||
wants_scroll_events: wants_scroll_events,
|
wants_scroll_events: wants_scroll_events,
|
||||||
scroll_policy: scroll_policy,
|
scroll_policy: scroll_policy,
|
||||||
cpu_painting: cpu_painting,
|
cpu_painting: cpu_painting,
|
||||||
unrendered_color: gfx::color::rgba(0.0, 0.0, 0.0, 0.0),
|
unrendered_color: unrendered_color,
|
||||||
scissor: None,
|
scissor: None,
|
||||||
epoch: Epoch(0),
|
epoch: epoch,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_root(pipeline: CompositionPipeline,
|
pub fn new_root(pipeline: CompositionPipeline,
|
||||||
|
epoch: Epoch,
|
||||||
page_size: Size2D<f32>,
|
page_size: Size2D<f32>,
|
||||||
cpu_painting: bool) -> CompositorData {
|
cpu_painting: bool,
|
||||||
|
unrendered_color: Color) -> CompositorData {
|
||||||
CompositorData::new(pipeline,
|
CompositorData::new(pipeline,
|
||||||
LayerId::null(),
|
LayerId::null(),
|
||||||
|
epoch,
|
||||||
Rect(Point2D(0f32, 0f32), page_size),
|
Rect(Point2D(0f32, 0f32), page_size),
|
||||||
Some(page_size),
|
Some(page_size),
|
||||||
cpu_painting,
|
cpu_painting,
|
||||||
WantsScrollEvents,
|
WantsScrollEvents,
|
||||||
FixedPosition,
|
FixedPosition,
|
||||||
false)
|
unrendered_color)
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn id_of_first_child(layer: Rc<Layer<CompositorData>>) -> LayerId {
|
|
||||||
layer.children().iter().next().expect("no first child!").extra_data.borrow().id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a child layer to the layer with the given ID and the given pipeline, if it doesn't
|
/// Adds a child layer to the layer with the given ID and the given pipeline, if it doesn't
|
||||||
/// exist yet. The child layer will have the same pipeline, tile size, memory limit, and CPU
|
/// exist yet. The child layer will have the same pipeline, tile size, memory limit, and CPU
|
||||||
/// painting status as its parent.
|
/// painting status as its parent.
|
||||||
pub fn add_child_if_necessary(layer: Rc<Layer<CompositorData>>,
|
pub fn add_child(layer: Rc<Layer<CompositorData>>,
|
||||||
child_layer_id: LayerId,
|
layer_properties: LayerProperties,
|
||||||
rect: Rect<f32>,
|
page_size: Size2D<f32>) {
|
||||||
page_size: Size2D<f32>,
|
|
||||||
scroll_policy: ScrollPolicy) {
|
|
||||||
// See if we've already made this child layer.
|
|
||||||
let pipeline_id = layer.extra_data.borrow().pipeline.id;
|
|
||||||
if layer.children().iter().any(|kid| {
|
|
||||||
kid.extra_data.borrow().pipeline.id == pipeline_id &&
|
|
||||||
kid.extra_data.borrow().id == child_layer_id
|
|
||||||
}) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let new_compositor_data = CompositorData::new(layer.extra_data.borrow().pipeline.clone(),
|
let new_compositor_data = CompositorData::new(layer.extra_data.borrow().pipeline.clone(),
|
||||||
child_layer_id,
|
layer_properties.id,
|
||||||
rect,
|
layer_properties.epoch,
|
||||||
|
layer_properties.rect,
|
||||||
Some(page_size),
|
Some(page_size),
|
||||||
layer.extra_data.borrow().cpu_painting,
|
layer.extra_data.borrow().cpu_painting,
|
||||||
DoesntWantScrollEvents,
|
DoesntWantScrollEvents,
|
||||||
scroll_policy,
|
layer_properties.scroll_policy,
|
||||||
false);
|
layer_properties.background_color);
|
||||||
let new_kid = Rc::new(Layer::new(page_size,
|
let new_kid = Rc::new(Layer::new(page_size,
|
||||||
Layer::tile_size(layer.clone()),
|
Layer::tile_size(layer.clone()),
|
||||||
new_compositor_data));
|
new_compositor_data));
|
||||||
|
|
||||||
new_kid.extra_data.borrow_mut().scissor = Some(rect);
|
new_kid.extra_data.borrow_mut().scissor = Some(layer_properties.rect);
|
||||||
*new_kid.origin.borrow_mut() = rect.origin;
|
*new_kid.origin.borrow_mut() = layer_properties.rect.origin;
|
||||||
|
|
||||||
// Place the kid's layer in the container passed in.
|
// Place the kid's layer in the container passed in.
|
||||||
Layer::add_child(layer.clone(), new_kid.clone());
|
Layer::add_child(layer.clone(), new_kid.clone());
|
||||||
|
@ -423,46 +413,42 @@ impl CompositorData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the layer's page size. This signals that the renderer is ready for BufferRequests.
|
pub fn update_layer(layer: Rc<Layer<CompositorData>>, layer_properties: LayerProperties) {
|
||||||
// If the layer is hidden and has a defined clipping rect, unhide it.
|
layer.extra_data.borrow_mut().epoch = layer_properties.epoch;
|
||||||
// This method returns false if the specified layer is not found.
|
layer.extra_data.borrow_mut().unrendered_color = layer_properties.background_color;
|
||||||
pub fn resize(layer: Rc<Layer<CompositorData>>,
|
CompositorData::resize(layer.clone(), layer_properties.rect.size);
|
||||||
pipeline_id: PipelineId,
|
}
|
||||||
layer_id: LayerId,
|
|
||||||
new_size: Size2D<f32>,
|
|
||||||
window_size: TypedSize2D<PagePx, f32>,
|
|
||||||
epoch: Epoch)
|
|
||||||
-> bool {
|
|
||||||
debug!("compositor_data: starting resize()");
|
|
||||||
if layer.extra_data.borrow().pipeline.id != pipeline_id ||
|
|
||||||
layer.extra_data.borrow().id != layer_id {
|
|
||||||
return CompositorData::resize_helper(layer.clone(),
|
|
||||||
pipeline_id,
|
|
||||||
layer_id,
|
|
||||||
new_size,
|
|
||||||
epoch)
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!("compositor_data: layer found for resize()");
|
// Resize and unhide a pre-existing layer. A new layer's size is set during creation.
|
||||||
layer.extra_data.borrow_mut().epoch = epoch;
|
fn resize(layer: Rc<Layer<CompositorData>>,
|
||||||
|
new_size: Size2D<f32>) {
|
||||||
|
debug!("compositor_data: starting resize_helper()");
|
||||||
|
|
||||||
|
debug!("compositor_data: layer found for resize_helper()");
|
||||||
layer.extra_data.borrow_mut().page_size = Some(new_size);
|
layer.extra_data.borrow_mut().page_size = Some(new_size);
|
||||||
|
|
||||||
let unused_buffers = Layer::resize(layer.clone(), new_size);
|
let unused_buffers = Layer::resize(layer.clone(), new_size);
|
||||||
if !unused_buffers.is_empty() {
|
if !unused_buffers.is_empty() {
|
||||||
let _ = layer.extra_data.borrow().pipeline
|
let msg = UnusedBufferMsg(unused_buffers);
|
||||||
.render_chan
|
let _ = layer.extra_data.borrow().pipeline.render_chan.send_opt(msg);
|
||||||
.send_opt(UnusedBufferMsg(unused_buffers));
|
}
|
||||||
|
|
||||||
|
let scissor_clone = layer.extra_data.borrow().scissor.clone();
|
||||||
|
match scissor_clone {
|
||||||
|
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.
|
||||||
|
let size: TypedSize2D<PagePx, f32> = Size2D::from_untyped(&scissor.size);
|
||||||
|
CompositorData::handle_scroll_event(layer.clone(),
|
||||||
|
TypedPoint2D(0f32, 0f32),
|
||||||
|
TypedPoint2D(-1f32, -1f32),
|
||||||
|
size);
|
||||||
|
layer.extra_data.borrow_mut().hidden = false;
|
||||||
|
}
|
||||||
|
None => {} // Nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
|
||||||
CompositorData::handle_scroll_event(layer.clone(),
|
|
||||||
TypedPoint2D(0f32, 0f32),
|
|
||||||
TypedPoint2D(-1f32, -1f32),
|
|
||||||
window_size);
|
|
||||||
layer.extra_data.borrow_mut().hidden = false;
|
|
||||||
CompositorData::set_occlusions(layer.clone());
|
CompositorData::set_occlusions(layer.clone());
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move(layer: Rc<Layer<CompositorData>>,
|
pub fn move(layer: Rc<Layer<CompositorData>>,
|
||||||
|
@ -537,8 +523,6 @@ impl CompositorData {
|
||||||
(NoFlip, TextureTarget2D)
|
(NoFlip, TextureTarget2D)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn find_child_with_pipeline_and_layer_id(layer: Rc<Layer<CompositorData>>,
|
fn find_child_with_pipeline_and_layer_id(layer: Rc<Layer<CompositorData>>,
|
||||||
pipeline_id: PipelineId,
|
pipeline_id: PipelineId,
|
||||||
layer_id: LayerId)
|
layer_id: LayerId)
|
||||||
|
@ -573,60 +557,6 @@ impl CompositorData {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A helper method to resize sublayers.
|
|
||||||
fn resize_helper(layer: Rc<Layer<CompositorData>>,
|
|
||||||
pipeline_id: PipelineId,
|
|
||||||
layer_id: LayerId,
|
|
||||||
new_size: Size2D<f32>,
|
|
||||||
epoch: Epoch)
|
|
||||||
-> bool {
|
|
||||||
debug!("compositor_data: starting resize_helper()");
|
|
||||||
|
|
||||||
let found = match CompositorData::find_child_with_pipeline_and_layer_id(layer.clone(),
|
|
||||||
pipeline_id,
|
|
||||||
layer_id) {
|
|
||||||
Some(child) => {
|
|
||||||
debug!("compositor_data: layer found for resize_helper()");
|
|
||||||
child.extra_data.borrow_mut().epoch = epoch;
|
|
||||||
child.extra_data.borrow_mut().page_size = Some(new_size);
|
|
||||||
|
|
||||||
let unused_buffers = Layer::resize(child.clone(), new_size);
|
|
||||||
if !unused_buffers.is_empty() {
|
|
||||||
let msg = UnusedBufferMsg(unused_buffers);
|
|
||||||
let _ = child.extra_data.borrow().pipeline.render_chan.send_opt(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
let scissor_clone = child.extra_data.borrow().scissor.clone();
|
|
||||||
match scissor_clone {
|
|
||||||
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.
|
|
||||||
let size: TypedSize2D<PagePx, f32> = Size2D::from_untyped(&scissor.size);
|
|
||||||
CompositorData::handle_scroll_event(child.clone(),
|
|
||||||
TypedPoint2D(0f32, 0f32),
|
|
||||||
TypedPoint2D(-1f32, -1f32),
|
|
||||||
size);
|
|
||||||
child.extra_data.borrow_mut().hidden = false;
|
|
||||||
}
|
|
||||||
None => {} // Nothing to do
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
None => false,
|
|
||||||
};
|
|
||||||
|
|
||||||
if found { // Boolean flag to get around double borrow of self
|
|
||||||
CompositorData::set_occlusions(layer.clone());
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we got here, the layer's ID does not match ours, so recurse on descendents (including
|
|
||||||
// hidden children).
|
|
||||||
layer.children().iter().any(|kid| {
|
|
||||||
CompositorData::resize_helper(kid.clone(), pipeline_id, layer_id, new_size, epoch)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect buffers from the quadtree. This method IS NOT recursive, so child layers
|
// Collect buffers from the quadtree. This method IS NOT recursive, so child layers
|
||||||
// are not rebuilt directly from this method.
|
// are not rebuilt directly from this method.
|
||||||
pub fn build_layer_tree(layer: Rc<Layer<CompositorData>>,
|
pub fn build_layer_tree(layer: Rc<Layer<CompositorData>>,
|
||||||
|
@ -766,9 +696,5 @@ impl CompositorData {
|
||||||
CompositorData::forget_all_tiles(kid.clone());
|
CompositorData::forget_all_tiles(kid.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_unrendered_color(layer: Rc<Layer<CompositorData>>, color: Color) {
|
|
||||||
layer.extra_data.borrow_mut().unrendered_color = color;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,31 @@ impl ScriptListener for CompositorChan {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct LayerProperties {
|
||||||
|
pub pipeline_id: PipelineId,
|
||||||
|
pub epoch: Epoch,
|
||||||
|
pub id: LayerId,
|
||||||
|
pub rect: Rect<f32>,
|
||||||
|
pub background_color: Color,
|
||||||
|
pub scroll_policy: ScrollPolicy,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LayerProperties {
|
||||||
|
fn new(pipeline_id: PipelineId, epoch: Epoch, metadata: &LayerMetadata) -> LayerProperties {
|
||||||
|
LayerProperties {
|
||||||
|
pipeline_id: pipeline_id,
|
||||||
|
epoch: epoch,
|
||||||
|
id: metadata.id,
|
||||||
|
rect: Rect(Point2D(metadata.position.origin.x as f32,
|
||||||
|
metadata.position.origin.y as f32),
|
||||||
|
Size2D(metadata.position.size.width as f32,
|
||||||
|
metadata.position.size.height as f32)),
|
||||||
|
background_color: metadata.background_color,
|
||||||
|
scroll_policy: metadata.scroll_policy,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Implementation of the abstract `RenderListener` interface.
|
/// Implementation of the abstract `RenderListener` interface.
|
||||||
impl RenderListener for CompositorChan {
|
impl RenderListener for CompositorChan {
|
||||||
fn get_graphics_metadata(&self) -> Option<NativeGraphicsMetadata> {
|
fn get_graphics_metadata(&self) -> Option<NativeGraphicsMetadata> {
|
||||||
|
@ -86,30 +111,15 @@ impl RenderListener for CompositorChan {
|
||||||
// `position: fixed` but will not be sufficient to handle `overflow: scroll` or transforms.
|
// `position: fixed` but will not be sufficient to handle `overflow: scroll` or transforms.
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
for metadata in metadata.iter() {
|
for metadata in metadata.iter() {
|
||||||
let origin = Point2D(metadata.position.origin.x as f32,
|
let layer_properties = LayerProperties::new(pipeline_id, epoch, metadata);
|
||||||
metadata.position.origin.y as f32);
|
|
||||||
let size = Size2D(metadata.position.size.width as f32,
|
|
||||||
metadata.position.size.height as f32);
|
|
||||||
let rect = Rect(origin, size);
|
|
||||||
if first {
|
if first {
|
||||||
self.chan.send(CreateRootCompositorLayerIfNecessary(pipeline_id,
|
self.chan.send(CreateOrUpdateRootLayer(layer_properties));
|
||||||
metadata.id,
|
|
||||||
size,
|
|
||||||
metadata.background_color));
|
|
||||||
first = false
|
first = false
|
||||||
} else {
|
} else {
|
||||||
self.chan
|
self.chan.send(CreateOrUpdateDescendantLayer(layer_properties));
|
||||||
.send(CreateDescendantCompositorLayerIfNecessary(pipeline_id,
|
|
||||||
metadata.id,
|
|
||||||
rect,
|
|
||||||
metadata.scroll_policy));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.chan.send(SetUnRenderedColor(pipeline_id,
|
self.chan.send(SetLayerClipRect(pipeline_id, metadata.id, layer_properties.rect));
|
||||||
metadata.id,
|
|
||||||
metadata.background_color));
|
|
||||||
self.chan.send(SetLayerPageSize(pipeline_id, metadata.id, size, epoch));
|
|
||||||
self.chan.send(SetLayerClipRect(pipeline_id, metadata.id, rect));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,12 +171,10 @@ pub enum Msg {
|
||||||
|
|
||||||
/// Tells the compositor to create the root layer for a pipeline if necessary (i.e. if no layer
|
/// Tells the compositor to create the root layer for a pipeline if necessary (i.e. if no layer
|
||||||
/// with that ID exists).
|
/// with that ID exists).
|
||||||
CreateRootCompositorLayerIfNecessary(PipelineId, LayerId, Size2D<f32>, Color),
|
CreateOrUpdateRootLayer(LayerProperties),
|
||||||
/// Tells the compositor to create a descendant layer for a pipeline if necessary (i.e. if no
|
/// Tells the compositor to create a descendant layer for a pipeline if necessary (i.e. if no
|
||||||
/// layer with that ID exists).
|
/// layer with that ID exists).
|
||||||
CreateDescendantCompositorLayerIfNecessary(PipelineId, LayerId, Rect<f32>, ScrollPolicy),
|
CreateOrUpdateDescendantLayer(LayerProperties),
|
||||||
/// Alerts the compositor that the specified layer has changed size.
|
|
||||||
SetLayerPageSize(PipelineId, LayerId, 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, LayerId, Rect<f32>),
|
SetLayerClipRect(PipelineId, LayerId, Rect<f32>),
|
||||||
/// Scroll a page in a window
|
/// Scroll a page in a window
|
||||||
|
@ -179,8 +187,6 @@ pub enum Msg {
|
||||||
ChangeRenderState(RenderState),
|
ChangeRenderState(RenderState),
|
||||||
/// Sets the channel to the current layout and render tasks, along with their id
|
/// Sets the channel to the current layout and render tasks, along with their id
|
||||||
SetIds(SendableFrameTree, Sender<()>, ConstellationChan),
|
SetIds(SendableFrameTree, Sender<()>, ConstellationChan),
|
||||||
/// Sets the color of unrendered content for a layer.
|
|
||||||
SetUnRenderedColor(PipelineId, LayerId, Color),
|
|
||||||
/// The load of a page for a given URL has completed.
|
/// The load of a page for a given URL has completed.
|
||||||
LoadComplete(PipelineId, Url),
|
LoadComplete(PipelineId, Url),
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,8 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use compositor_task::{Msg, Exit, ChangeReadyState, SetUnRenderedColor};
|
use compositor_task::{Msg, Exit, ChangeReadyState, SetIds};
|
||||||
use compositor_task::{SetIds, GetGraphicsMetadata, CreateRootCompositorLayerIfNecessary};
|
use compositor_task::{GetGraphicsMetadata, CreateOrUpdateRootLayer, CreateOrUpdateDescendantLayer};
|
||||||
use compositor_task::{CreateDescendantCompositorLayerIfNecessary, SetLayerPageSize};
|
|
||||||
use compositor_task::{SetLayerClipRect, Paint, ScrollFragmentPoint, LoadComplete};
|
use compositor_task::{SetLayerClipRect, Paint, ScrollFragmentPoint, LoadComplete};
|
||||||
use compositor_task::{ShutdownComplete, ChangeRenderState};
|
use compositor_task::{ShutdownComplete, ChangeRenderState};
|
||||||
|
|
||||||
|
@ -89,11 +88,11 @@ impl NullCompositor {
|
||||||
// we'll notice and think about whether it needs a response, like
|
// we'll notice and think about whether it needs a response, like
|
||||||
// SetIds.
|
// SetIds.
|
||||||
|
|
||||||
CreateRootCompositorLayerIfNecessary(..) |
|
CreateOrUpdateRootLayer(..) |
|
||||||
CreateDescendantCompositorLayerIfNecessary(..) | SetLayerPageSize(..) |
|
CreateOrUpdateDescendantLayer(..) |
|
||||||
SetLayerClipRect(..) | Paint(..) |
|
SetLayerClipRect(..) | Paint(..) |
|
||||||
ChangeReadyState(..) | ChangeRenderState(..) | ScrollFragmentPoint(..) |
|
ChangeReadyState(..) | ChangeRenderState(..) | ScrollFragmentPoint(..) |
|
||||||
SetUnRenderedColor(..) | LoadComplete(..) => ()
|
LoadComplete(..) => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue