Restructure compositor layers to work with iframes

When a frame is selected via set_ids, a tree of root compositor
layers is also created, matching the tree of pipelines in the frame.
This decouples the chronological ordering dependency for parent frames
and child iframes sending CreateOrUpdateRootLayer &
CreateOrUpdateDescendentLayer messages.

Change the Compositor ready and render states to per pipeline.
This ensures the compositor doesn't composite for an epoch until
every *pipeline* in the epoch is finished rendering.

For iframes it fixes a bug where the compositor didnt wait on the
child pipeline ready state before compositing the window.

Gotchas:
* layout task or script task failure on exit ("task '' failed at sending
  on a closed channel"), this happens if the child iframe shares the
  same script task as the parent and can be avoided by adding the
  sandbox attribute to the iframe.

Other changes:
* Inline set_clipping_rect in compositor.rs
* Commented out ref test simple_iframe.html fails on os x
This commit is contained in:
Bryan Bell 2014-07-19 04:54:57 -07:00
parent ca96821902
commit 0c9f469f64
17 changed files with 572 additions and 159 deletions

View file

@ -246,6 +246,7 @@ impl<C:RenderListener + Send> RenderTask<C> {
}
let mut replies = Vec::new();
self.compositor.set_render_state(RenderingRenderState, self.id);
for ReRenderRequest { buffer_requests, scale, layer_id, epoch }
in requests.move_iter() {
if self.epoch == epoch {
@ -254,6 +255,7 @@ impl<C:RenderListener + Send> RenderTask<C> {
debug!("renderer epoch mismatch: {:?} != {:?}", self.epoch, epoch);
}
}
self.compositor.set_render_state(IdleRenderState, self.id);
debug!("render_task: returning surfaces");
self.compositor.paint(self.id, self.epoch, replies);
@ -265,17 +267,11 @@ impl<C:RenderListener + Send> RenderTask<C> {
}
PaintPermissionGranted => {
self.paint_permission = true;
// Here we assume that the main layer—the layer responsible for the page size—
// is the first layer. This is a pretty fragile assumption. It will be fixed
// once we use the layers-based scrolling infrastructure for all scrolling.
if self.render_layers.len() > 1 {
self.epoch.next();
initialize_layers(&mut self.compositor,
self.id,
self.epoch,
self.render_layers.as_slice());
}
self.epoch.next();
initialize_layers(&mut self.compositor,
self.id,
self.epoch,
self.render_layers.as_slice());
}
PaintPermissionRevoked => {
self.paint_permission = false;
@ -305,8 +301,6 @@ impl<C:RenderListener + Send> RenderTask<C> {
None => return,
};
self.compositor.set_render_state(RenderingRenderState);
// Divide up the layer into tiles.
for tile in tiles.iter() {
// Optimize the display list for this tile.
@ -443,8 +437,6 @@ impl<C:RenderListener + Send> RenderTask<C> {
};
replies.push((render_layer.id, layer_buffer_set));
self.compositor.set_render_state(IdleRenderState);
})
}
}