Auto merge of #7423 - pcwalton:iframe-stacking-context-position, r=glennw

layout: Make the compositor rather than layout determine the position of each iframe.

The old code that attempted to do this during layout wasn't able to work
for multiple reasons: it couldn't know where the iframe was going to be
on the page (because of nested iframes), and at the time it was building
the display list for a fragment it couldn't know where that fragment was
going to be in page coordinates.

This patch rewrites that code so that only the size of an iframe is
determined during layout, and the position is determined by the
compositor. Layout layerizes iframes and marks the iframe layers with
the appropriate subpage ID so that the compositor can place them
correctly.

Closes #7377.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7423)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-09-29 19:26:49 -06:00
commit a0cb657fe8
20 changed files with 602 additions and 389 deletions

View file

@ -22,7 +22,7 @@ use euclid::num::Zero;
use euclid::{Matrix2D, Matrix4, Point2D, Rect, SideOffsets2D, Size2D};
use gfx_traits::color;
use libc::uintptr_t;
use msg::compositor_msg::{LayerId, LayerKind, ScrollPolicy};
use msg::compositor_msg::{LayerId, LayerKind, ScrollPolicy, SubpageLayerInfo};
use net_traits::image::base::Image;
use paint_context::PaintContext;
use paint_task::PaintLayer;
@ -364,6 +364,9 @@ pub struct StackingContext {
/// The layer id for this stacking context, if there is one.
pub layer_id: Option<LayerId>,
/// The subpage that this stacking context represents, if there is one.
pub subpage_layer_info: Option<SubpageLayerInfo>,
}
impl StackingContext {
@ -380,7 +383,8 @@ impl StackingContext {
establishes_3d_context: bool,
scrolls_overflow_area: bool,
scroll_policy: ScrollPolicy,
layer_id: Option<LayerId>)
layer_id: Option<LayerId>,
subpage_layer_info: Option<SubpageLayerInfo>)
-> StackingContext {
let mut stacking_context = StackingContext {
display_list: display_list,
@ -395,6 +399,7 @@ impl StackingContext {
scrolls_overflow_area: scrolls_overflow_area,
scroll_policy: scroll_policy,
layer_id: layer_id,
subpage_layer_info: subpage_layer_info,
};
StackingContextLayerCreator::add_layers_to_preserve_drawing_order(&mut stacking_context);
stacking_context
@ -416,6 +421,7 @@ impl StackingContext {
scrolls_overflow_area: self.scrolls_overflow_area,
scroll_policy: self.scroll_policy,
layer_id: Some(layer_id),
subpage_layer_info: self.subpage_layer_info,
}
}
@ -679,11 +685,19 @@ impl StackingContextLayerCreator {
fn finish_building_current_layer(&mut self, stacking_context: &mut StackingContext) {
if let Some(display_list) = self.display_list_for_next_layer.take() {
let next_layer_id =
stacking_context.display_list.layered_children.back().unwrap().id.companion_layer_id();
stacking_context.display_list
.layered_children
.back()
.unwrap()
.id
.companion_layer_id();
let child_stacking_context =
Arc::new(stacking_context.create_layered_child(next_layer_id, display_list));
stacking_context.display_list.layered_children.push_back(Arc::new(
PaintLayer::new(next_layer_id, color::transparent(), child_stacking_context)));
stacking_context.display_list.layered_children.push_back(
Arc::new(PaintLayer::new(next_layer_id,
color::transparent(),
child_stacking_context,
ScrollPolicy::Scrollable)));
self.all_following_children_need_layers = true;
}
}
@ -694,7 +708,10 @@ impl StackingContextLayerCreator {
if let Some(layer_id) = stacking_context.layer_id {
self.finish_building_current_layer(parent_stacking_context);
parent_stacking_context.display_list.layered_children.push_back(
Arc::new(PaintLayer::new(layer_id, color::transparent(), stacking_context)));
Arc::new(PaintLayer::new(layer_id,
color::transparent(),
stacking_context,
ScrollPolicy::Scrollable)));
// We have started processing layered stacking contexts, so any stacking context that
// we process from now on needs its own layer to ensure proper rendering order.

View file

@ -17,8 +17,8 @@ use font_context::FontContext;
use ipc_channel::ipc::IpcSender;
use layers::layers::{BufferRequest, LayerBuffer, LayerBufferSet};
use layers::platform::surface::{NativeDisplay, NativeSurface};
use msg::compositor_msg::{Epoch, FrameTreeId, LayerId, LayerKind};
use msg::compositor_msg::{LayerProperties, PaintListener};
use msg::compositor_msg::{Epoch, FrameTreeId, LayerId, LayerKind, LayerProperties, PaintListener};
use msg::compositor_msg::{ScrollPolicy};
use msg::constellation_msg::Msg as ConstellationMsg;
use msg::constellation_msg::PipelineExitType;
use msg::constellation_msg::{ConstellationChan, Failure, PipelineId};
@ -48,15 +48,22 @@ pub struct PaintLayer {
pub background_color: Color,
/// The stacking context that represents the content of this layer.
pub stacking_context: Arc<StackingContext>,
/// The scrolling policy of this layer.
pub scroll_policy: ScrollPolicy,
}
impl PaintLayer {
/// Creates a new `PaintLayer`.
pub fn new(id: LayerId, background_color: Color, stacking_context: Arc<StackingContext>) -> PaintLayer {
pub fn new(id: LayerId,
background_color: Color,
stacking_context: Arc<StackingContext>,
scroll_policy: ScrollPolicy)
-> PaintLayer {
PaintLayer {
id: id,
background_color: background_color,
stacking_context: stacking_context,
scroll_policy: scroll_policy,
}
}
@ -355,9 +362,9 @@ impl<C> PaintTask<C> where C: PaintListener + Send + 'static {
let transform = transform.mul(&paint_layer.stacking_context.transform);
let perspective = perspective.mul(&paint_layer.stacking_context.perspective);
let overflow_size =
Size2D::new(paint_layer.stacking_context.overflow.size.width.to_nearest_px() as f32,
paint_layer.stacking_context.overflow.size.height.to_nearest_px() as f32);
let overflow_size = Size2D::new(
paint_layer.stacking_context.overflow.size.width.to_nearest_px() as f32,
paint_layer.stacking_context.overflow.size.height.to_nearest_px() as f32);
// Layers start at the top left of their overflow rect, as far as the info
// we give to the compositor is concerned.
@ -379,6 +386,7 @@ impl<C> PaintTask<C> where C: PaintListener + Send + 'static {
perspective: perspective,
establishes_3d_context: paint_layer.stacking_context.establishes_3d_context,
scrolls_overflow_area: paint_layer.stacking_context.scrolls_overflow_area,
subpage_layer_info: paint_layer.stacking_context.subpage_layer_info,
});
// When there is a new layer, the transforms and origin are handled by the compositor,