Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure compositor layers are collected when removed from layout. #7182

Merged
merged 1 commit into from Aug 13, 2015
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Ensure compositor layers are collected when removed from layout.

  • Loading branch information
gw3583 committed Aug 12, 2015
commit 6506468e193be9363972ce58e70cf93755f9f8ec
@@ -379,6 +379,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
(Msg::InitializeLayersForPipeline(pipeline_id, epoch, properties),
ShutdownState::NotShuttingDown) => {
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() {
if index == 0 {
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())
}

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) {
let root_layer = match self.scene.root {
Some(ref root_layer) => root_layer.clone(),
@@ -98,6 +98,14 @@ pub trait CompositorLayer {
pipeline_id: PipelineId)
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
/// painter. You must call this only when the paint task is destined to be going down;
/// 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
/// painter. You must call this only when the paint task is destined to be going down;
/// otherwise, you will leak tiles.
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.