mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Ensure compositor layers are collected when removed from layout.
This commit is contained in:
parent
e44ae6404f
commit
6506468e19
2 changed files with 57 additions and 0 deletions
|
@ -379,6 +379,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
(Msg::InitializeLayersForPipeline(pipeline_id, epoch, properties),
|
(Msg::InitializeLayersForPipeline(pipeline_id, epoch, properties),
|
||||||
ShutdownState::NotShuttingDown) => {
|
ShutdownState::NotShuttingDown) => {
|
||||||
self.get_or_create_pipeline_details(pipeline_id).current_epoch = epoch;
|
self.get_or_create_pipeline_details(pipeline_id).current_epoch = epoch;
|
||||||
|
self.collect_old_layers(pipeline_id, &properties);
|
||||||
for (index, layer_properties) in properties.iter().enumerate() {
|
for (index, layer_properties) in properties.iter().enumerate() {
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
self.create_or_update_base_layer(pipeline_id, *layer_properties);
|
self.create_or_update_base_layer(pipeline_id, *layer_properties);
|
||||||
|
@ -671,6 +672,17 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
self.find_layer_with_pipeline_and_layer_id(pipeline_id, LayerId::null())
|
self.find_layer_with_pipeline_and_layer_id(pipeline_id, LayerId::null())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn collect_old_layers(&mut self,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
new_layers: &Vec<LayerProperties>) {
|
||||||
|
let root_layer = match self.scene.root {
|
||||||
|
Some(ref root_layer) => root_layer.clone(),
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
root_layer.collect_old_layers(self, pipeline_id, new_layers);
|
||||||
|
}
|
||||||
|
|
||||||
fn remove_pipeline_root_layer(&mut self, pipeline_id: PipelineId) {
|
fn remove_pipeline_root_layer(&mut self, pipeline_id: PipelineId) {
|
||||||
let root_layer = match self.scene.root {
|
let root_layer = match self.scene.root {
|
||||||
Some(ref root_layer) => root_layer.clone(),
|
Some(ref root_layer) => root_layer.clone(),
|
||||||
|
|
|
@ -98,6 +98,14 @@ pub trait CompositorLayer {
|
||||||
pipeline_id: PipelineId)
|
pipeline_id: PipelineId)
|
||||||
where Window: WindowMethods;
|
where Window: WindowMethods;
|
||||||
|
|
||||||
|
/// Traverses the existing layer hierarchy and removes any layers that
|
||||||
|
/// currently exist but which are no longer required.
|
||||||
|
fn collect_old_layers<Window>(&self,
|
||||||
|
compositor: &mut IOCompositor<Window>,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
new_layers: &Vec<LayerProperties>)
|
||||||
|
where Window: WindowMethods;
|
||||||
|
|
||||||
/// Destroys all tiles of all layers, including children, *without* sending them back to the
|
/// Destroys all tiles of all layers, including children, *without* sending them back to the
|
||||||
/// painter. You must call this only when the paint task is destined to be going down;
|
/// painter. You must call this only when the paint task is destined to be going down;
|
||||||
/// otherwise, you will leak tiles.
|
/// otherwise, you will leak tiles.
|
||||||
|
@ -272,6 +280,43 @@ impl CompositorLayer for Layer<CompositorData> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn collect_old_layers<Window>(&self,
|
||||||
|
compositor: &mut IOCompositor<Window>,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
new_layers: &Vec<LayerProperties>)
|
||||||
|
where Window: WindowMethods {
|
||||||
|
// Traverse children first so that layers are removed
|
||||||
|
// bottom up - allowing each layer being removed to properly
|
||||||
|
// clean up any tiles it owns.
|
||||||
|
for kid in self.children().iter() {
|
||||||
|
kid.collect_old_layers(compositor, pipeline_id, new_layers);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retain child layers that also exist in the new layer list.
|
||||||
|
self.children().retain(|child| {
|
||||||
|
let extra_data = child.extra_data.borrow();
|
||||||
|
|
||||||
|
// Never remove root layers or layers from other pipelines.
|
||||||
|
if pipeline_id != extra_data.pipeline_id ||
|
||||||
|
extra_data.id == LayerId::null() {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
// Keep this layer if it exists in the new layer list.
|
||||||
|
let keep_layer = new_layers.iter().position(|properties| {
|
||||||
|
properties.id == extra_data.id
|
||||||
|
}).is_some();
|
||||||
|
|
||||||
|
// When removing a layer, clear any tiles and surfaces
|
||||||
|
// associated with the layer.
|
||||||
|
if !keep_layer {
|
||||||
|
child.clear_all_tiles(compositor);
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_layer
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Destroys all tiles of all layers, including children, *without* sending them back to the
|
/// Destroys all tiles of all layers, including children, *without* sending them back to the
|
||||||
/// painter. You must call this only when the paint task is destined to be going down;
|
/// painter. You must call this only when the paint task is destined to be going down;
|
||||||
/// otherwise, you will leak tiles.
|
/// otherwise, you will leak tiles.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue