mirror of
https://github.com/servo/servo.git
synced 2025-08-01 19:50:30 +01:00
Create root compositor layers for all frames eagerly
Instead of waiting to create the root layer, create them as soon as the Compositor receives the frame tree. This allows the compositor to create a layer tree skeleton of which to hang the base layers when they are ready.
This commit is contained in:
parent
0e86679464
commit
e17cc2d5e2
1 changed files with 67 additions and 48 deletions
|
@ -36,7 +36,7 @@ use layers::scene::Scene;
|
||||||
use opengles::gl2;
|
use opengles::gl2;
|
||||||
use png;
|
use png;
|
||||||
use servo_msg::compositor_msg::{Blank, Epoch, FixedPosition, FinishedLoading, IdleRenderState};
|
use servo_msg::compositor_msg::{Blank, Epoch, FixedPosition, FinishedLoading, IdleRenderState};
|
||||||
use servo_msg::compositor_msg::{LayerId, ReadyState, RenderState};
|
use servo_msg::compositor_msg::{LayerId, ReadyState, RenderingRenderState, 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;
|
||||||
|
@ -293,7 +293,9 @@ impl IOCompositor {
|
||||||
}
|
}
|
||||||
|
|
||||||
(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_frame_tree(&frame_tree,
|
||||||
|
response_chan,
|
||||||
|
new_constellation_chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
(Ok(GetGraphicsMetadata(chan)), NotShuttingDown) => {
|
(Ok(GetGraphicsMetadata(chan)), NotShuttingDown) => {
|
||||||
|
@ -391,19 +393,52 @@ impl IOCompositor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_ids(&mut self,
|
fn set_frame_tree(&mut self,
|
||||||
frame_tree: SendableFrameTree,
|
frame_tree: &SendableFrameTree,
|
||||||
response_chan: Sender<()>,
|
response_chan: Sender<()>,
|
||||||
new_constellation_chan: ConstellationChan) {
|
new_constellation_chan: ConstellationChan) {
|
||||||
response_chan.send(());
|
response_chan.send(());
|
||||||
|
|
||||||
self.root_pipeline = Some(frame_tree.pipeline.clone());
|
self.root_pipeline = Some(frame_tree.pipeline.clone());
|
||||||
|
|
||||||
|
// If we have an old root layer, release all old tiles before replacing it.
|
||||||
|
match self.scene.root {
|
||||||
|
Some(ref mut layer) => CompositorData::clear_all_tiles(layer.clone()),
|
||||||
|
None => { }
|
||||||
|
}
|
||||||
|
self.scene.root = Some(self.create_frame_tree_root_layers(frame_tree));
|
||||||
|
|
||||||
// Initialize the new constellation channel by sending it the root window size.
|
// Initialize the new constellation channel by sending it the root window size.
|
||||||
self.constellation_chan = new_constellation_chan;
|
self.constellation_chan = new_constellation_chan;
|
||||||
self.send_window_size();
|
self.send_window_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_frame_tree_root_layers(&mut self,
|
||||||
|
frame_tree: &SendableFrameTree)
|
||||||
|
-> Rc<Layer<CompositorData>> {
|
||||||
|
// Initialize the ReadyState and RenderState for this pipeline.
|
||||||
|
self.ready_states.insert(frame_tree.pipeline.id, Blank);
|
||||||
|
self.render_states.insert(frame_tree.pipeline.id, RenderingRenderState);
|
||||||
|
|
||||||
|
let layer_properties = LayerProperties {
|
||||||
|
pipeline_id: frame_tree.pipeline.id,
|
||||||
|
epoch: Epoch(0),
|
||||||
|
id: LayerId::null(),
|
||||||
|
rect: Rect::zero(),
|
||||||
|
background_color: azure_hl::Color::new(0., 0., 0., 0.),
|
||||||
|
scroll_policy: FixedPosition,
|
||||||
|
};
|
||||||
|
let root_layer = CompositorData::new_layer(frame_tree.pipeline.clone(),
|
||||||
|
layer_properties,
|
||||||
|
WantsScrollEvents,
|
||||||
|
self.opts.tile_size);
|
||||||
|
|
||||||
|
for kid in frame_tree.children.iter() {
|
||||||
|
root_layer.add_child(self.create_frame_tree_root_layers(&kid.frame_tree));
|
||||||
|
}
|
||||||
|
return root_layer;
|
||||||
|
}
|
||||||
|
|
||||||
fn find_layer_with_pipeline_and_layer_id(&self,
|
fn find_layer_with_pipeline_and_layer_id(&self,
|
||||||
pipeline_id: PipelineId,
|
pipeline_id: PipelineId,
|
||||||
layer_id: LayerId)
|
layer_id: LayerId)
|
||||||
|
@ -419,6 +454,13 @@ impl IOCompositor {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_pipeline_root_layer(&self, pipeline_id: PipelineId) -> Rc<Layer<CompositorData>> {
|
||||||
|
match self.find_layer_with_pipeline_and_layer_id(pipeline_id, LayerId::null()) {
|
||||||
|
Some(ref layer) => layer.clone(),
|
||||||
|
None => fail!("Tried to create or update layer for unknown pipeline"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn update_layer_if_exists(&mut self, properties: LayerProperties) -> bool {
|
fn update_layer_if_exists(&mut self, properties: LayerProperties) -> bool {
|
||||||
match self.find_layer_with_pipeline_and_layer_id(properties.pipeline_id, properties.id) {
|
match self.find_layer_with_pipeline_and_layer_id(properties.pipeline_id, properties.id) {
|
||||||
Some(existing_layer) => {
|
Some(existing_layer) => {
|
||||||
|
@ -440,35 +482,20 @@ impl IOCompositor {
|
||||||
|
|
||||||
let need_new_root_layer = !self.update_layer_if_exists(layer_properties);
|
let need_new_root_layer = !self.update_layer_if_exists(layer_properties);
|
||||||
if need_new_root_layer {
|
if need_new_root_layer {
|
||||||
let root_pipeline = match self.root_pipeline {
|
let root_layer = self.find_pipeline_root_layer(layer_properties.pipeline_id);
|
||||||
Some(ref root_pipeline) => root_pipeline.clone(),
|
CompositorData::update_layer(root_layer.clone(), layer_properties);
|
||||||
None => fail!("Compositor: Making new layer without initialized pipeline"),
|
|
||||||
};
|
|
||||||
|
|
||||||
let root_properties = LayerProperties {
|
let root_layer_pipeline = root_layer.extra_data.borrow().pipeline.clone();
|
||||||
pipeline_id: root_pipeline.id,
|
let first_child = CompositorData::new_layer(root_layer_pipeline.clone(),
|
||||||
epoch: layer_properties.epoch,
|
|
||||||
id: LayerId::null(),
|
|
||||||
rect: layer_properties.rect,
|
|
||||||
background_color: layer_properties.background_color,
|
|
||||||
scroll_policy: FixedPosition,
|
|
||||||
};
|
|
||||||
let new_root = CompositorData::new_layer(root_pipeline.clone(),
|
|
||||||
root_properties,
|
|
||||||
WantsScrollEvents,
|
|
||||||
self.opts.tile_size);
|
|
||||||
let first_chid = CompositorData::new_layer(root_pipeline.clone(),
|
|
||||||
layer_properties,
|
layer_properties,
|
||||||
DoesntWantScrollEvents,
|
DoesntWantScrollEvents,
|
||||||
self.opts.tile_size);
|
self.opts.tile_size);
|
||||||
new_root.add_child(first_chid);
|
|
||||||
|
|
||||||
// Release all tiles from the layer before dropping it.
|
// Add the first child / base layer to the front of the child list, so that
|
||||||
match self.scene.root {
|
// child iframe layers are rendered on top of the base layer. These iframe
|
||||||
Some(ref mut layer) => CompositorData::clear_all_tiles(layer.clone()),
|
// layers were added previously when creating the layer tree skeleton in
|
||||||
None => { }
|
// create_frame_tree_root_layers.
|
||||||
}
|
root_layer.children().insert(0, first_child);
|
||||||
self.scene.root = Some(new_root);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.scroll_layer_to_fragment_point_if_necessary(layer_properties.pipeline_id,
|
self.scroll_layer_to_fragment_point_if_necessary(layer_properties.pipeline_id,
|
||||||
|
@ -487,22 +514,14 @@ impl IOCompositor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_descendant_layer(&self, layer_properties: LayerProperties) {
|
fn create_descendant_layer(&self, layer_properties: LayerProperties) {
|
||||||
match self.scene.root {
|
let root_layer = self.find_pipeline_root_layer(layer_properties.pipeline_id);
|
||||||
Some(ref root_layer) => {
|
|
||||||
let root_layer_pipeline = root_layer.extra_data.borrow().pipeline.clone();
|
let root_layer_pipeline = root_layer.extra_data.borrow().pipeline.clone();
|
||||||
if root_layer_pipeline.id != layer_properties.pipeline_id {
|
|
||||||
fail!("Compositor: New layer pipeline does not match root layer pipeline");
|
|
||||||
}
|
|
||||||
|
|
||||||
let new_layer = CompositorData::new_layer(root_layer_pipeline,
|
let new_layer = CompositorData::new_layer(root_layer_pipeline,
|
||||||
layer_properties,
|
layer_properties,
|
||||||
DoesntWantScrollEvents,
|
DoesntWantScrollEvents,
|
||||||
root_layer.tile_size);
|
root_layer.tile_size);
|
||||||
root_layer.add_child(new_layer);
|
root_layer.add_child(new_layer);
|
||||||
}
|
}
|
||||||
None => fail!("Compositor: Received new layer without root layer")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_window_size(&self) {
|
fn send_window_size(&self) {
|
||||||
let dppx = self.page_zoom * self.device_pixels_per_screen_px();
|
let dppx = self.page_zoom * self.device_pixels_per_screen_px();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue