aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/compositing/compositor.rs20
-rw-r--r--components/compositing/compositor_layer.rs8
-rw-r--r--components/gfx/display_list/mod.rs212
-rw-r--r--components/gfx/paint_task.rs17
-rw-r--r--components/layout/display_list_builder.rs52
-rw-r--r--components/layout/fragment.rs6
-rw-r--r--components/layout/inline.rs2
-rw-r--r--components/msg/compositor_msg.rs13
-rw-r--r--components/servo/Cargo.lock2
-rw-r--r--ports/cef/Cargo.lock2
-rw-r--r--ports/gonk/Cargo.lock2
-rw-r--r--tests/wpt/mozilla/tests/css/stacked_layers.html16
-rw-r--r--tests/wpt/mozilla/tests/css/stacked_layers_ref.html10
13 files changed, 271 insertions, 91 deletions
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs
index dc7d54cfa5e..739cc1ddb44 100644
--- a/components/compositing/compositor.rs
+++ b/components/compositing/compositor.rs
@@ -670,7 +670,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
scroll_policy: ScrollPolicy::Scrollable,
transform: Matrix4::identity(),
perspective: Matrix4::identity(),
- subpage_layer_info: None,
+ subpage_pipeline_id: None,
establishes_3d_context: true,
scrolls_overflow_area: false,
};
@@ -819,18 +819,16 @@ impl<Window: WindowMethods> IOCompositor<Window> {
}
// If this layer contains a subpage, then create the root layer for that subpage now.
- if let Some(ref subpage_layer_info) = layer_properties.subpage_layer_info {
+ if let Some(ref subpage_pipeline_id) = layer_properties.subpage_pipeline_id {
let subpage_layer_properties = LayerProperties {
id: LayerId::null(),
parent_id: None,
- rect: Rect::new(Point2D::new(subpage_layer_info.origin.x.to_f32_px(),
- subpage_layer_info.origin.y.to_f32_px()),
- layer_properties.rect.size),
+ rect: Rect::new(Point2D::zero(), layer_properties.rect.size),
background_color: layer_properties.background_color,
scroll_policy: ScrollPolicy::Scrollable,
transform: Matrix4::identity(),
perspective: Matrix4::identity(),
- subpage_layer_info: layer_properties.subpage_layer_info,
+ subpage_pipeline_id: layer_properties.subpage_pipeline_id,
establishes_3d_context: true,
scrolls_overflow_area: true,
};
@@ -840,13 +838,13 @@ impl<Window: WindowMethods> IOCompositor<Window> {
} else {
WantsScrollEventsFlag::DoesntWantScrollEvents
};
- let subpage_layer = CompositorData::new_layer(subpage_layer_info.pipeline_id,
+ let subpage_layer = CompositorData::new_layer(*subpage_pipeline_id,
subpage_layer_properties,
wants_scroll_events,
new_layer.tile_size);
*subpage_layer.masks_to_bounds.borrow_mut() = true;
new_layer.add_child(subpage_layer);
- self.pending_subpages.insert(subpage_layer_info.pipeline_id);
+ self.pending_subpages.insert(*subpage_pipeline_id);
}
parent_layer.add_child(new_layer.clone());
@@ -871,13 +869,13 @@ impl<Window: WindowMethods> IOCompositor<Window> {
/// Sends the size of the given subpage up to the constellation. This will often trigger a
/// reflow of that subpage.
fn update_subpage_size_if_necessary(&self, layer_properties: &LayerProperties) {
- let subpage_layer_info = match layer_properties.subpage_layer_info {
- Some(ref subpage_layer_info) => *subpage_layer_info,
+ let subpage_pipeline_id = match layer_properties.subpage_pipeline_id {
+ Some(ref subpage_pipeline_id) => subpage_pipeline_id,
None => return,
};
let ConstellationChan(ref chan) = self.constellation_chan;
- chan.send(ConstellationMsg::FrameSize(subpage_layer_info.pipeline_id,
+ chan.send(ConstellationMsg::FrameSize(*subpage_pipeline_id,
layer_properties.rect.size)).unwrap();
}
diff --git a/components/compositing/compositor_layer.rs b/components/compositing/compositor_layer.rs
index 525135fd208..e3661987a78 100644
--- a/components/compositing/compositor_layer.rs
+++ b/components/compositing/compositor_layer.rs
@@ -61,9 +61,7 @@ impl CompositorData {
requested_epoch: Epoch(0),
painted_epoch: Epoch(0),
scroll_offset: Point2D::typed(0., 0.),
- subpage_info: layer_properties.subpage_layer_info.map(|subpage_layer_info| {
- subpage_layer_info.pipeline_id
- }),
+ subpage_info: layer_properties.subpage_pipeline_id,
};
Rc::new(Layer::new(Rect::from_untyped(&layer_properties.rect),
@@ -485,8 +483,8 @@ impl RcCompositorLayer for Rc<Layer<CompositorData>> {
if let Some(layer_pipeline_id) = layer_pipeline_id {
for layer_properties in new_layers.iter() {
// Keep this layer if a reference to it exists.
- if let Some(ref subpage_layer_info) = layer_properties.subpage_layer_info {
- if subpage_layer_info.pipeline_id == layer_pipeline_id {
+ if let Some(ref subpage_pipeline_id) = layer_properties.subpage_pipeline_id {
+ if *subpage_pipeline_id == layer_pipeline_id {
return true
}
}
diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs
index 07f32519ab9..5fb8b99d990 100644
--- a/components/gfx/display_list/mod.rs
+++ b/components/gfx/display_list/mod.rs
@@ -23,7 +23,8 @@ 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, SubpageLayerInfo};
+use msg::compositor_msg::{LayerId, LayerKind, ScrollPolicy};
+use msg::constellation_msg::PipelineId;
use net_traits::image::base::Image;
use paint_context::PaintContext;
use paint_task::{PaintLayerContents, PaintLayer};
@@ -88,7 +89,7 @@ pub struct LayerInfo {
pub scroll_policy: ScrollPolicy,
/// The subpage that this layer represents, if there is one.
- pub subpage_layer_info: Option<SubpageLayerInfo>,
+ pub subpage_pipeline_id: Option<PipelineId>,
/// The id for the next layer in the sequence. This is used for synthesizing
/// layers for content that needs to be displayed on top of this layer.
@@ -98,12 +99,12 @@ pub struct LayerInfo {
impl LayerInfo {
pub fn new(id: LayerId,
scroll_policy: ScrollPolicy,
- subpage_layer_info: Option<SubpageLayerInfo>)
+ subpage_pipeline_id: Option<PipelineId>)
-> LayerInfo {
LayerInfo {
layer_id: id,
scroll_policy: scroll_policy,
- subpage_layer_info: subpage_layer_info,
+ subpage_pipeline_id: subpage_pipeline_id,
next_layer_id: id.companion_layer_id(),
}
}
@@ -144,6 +145,8 @@ pub struct DisplayList {
pub children: LinkedList<Arc<StackingContext>>,
/// Child PaintLayers that will be rendered on top of everything else.
pub layered_children: LinkedList<Arc<PaintLayer>>,
+ /// Information about child layers.
+ pub layer_info: LinkedList<LayerInfo>,
}
impl DisplayList {
@@ -159,6 +162,7 @@ impl DisplayList {
outlines: LinkedList::new(),
children: LinkedList::new(),
layered_children: LinkedList::new(),
+ layer_info: LinkedList::new(),
}
}
@@ -174,6 +178,7 @@ impl DisplayList {
self.outlines.append(&mut other.outlines);
self.children.append(&mut other.children);
self.layered_children.append(&mut other.layered_children);
+ self.layer_info.append(&mut other.layer_info);
}
/// Merges all display items from all non-float stacking levels to the `float` stacking level.
@@ -554,6 +559,29 @@ impl DisplayList {
bounds
}
+
+ #[inline]
+ fn get_section_mut(&mut self, section: DisplayListSection) -> &mut LinkedList<DisplayItem> {
+ match section {
+ DisplayListSection::BackgroundAndBorders => &mut self.background_and_borders,
+ DisplayListSection::BlockBackgroundsAndBorders =>
+ &mut self.block_backgrounds_and_borders,
+ DisplayListSection::Floats => &mut self.floats,
+ DisplayListSection::Content => &mut self.content,
+ DisplayListSection::PositionedContent => &mut self.positioned_content,
+ DisplayListSection::Outlines => &mut self.outlines,
+ }
+ }
+}
+
+#[derive(Clone, Copy, Debug)]
+enum DisplayListSection {
+ BackgroundAndBorders,
+ BlockBackgroundsAndBorders,
+ Floats,
+ Content,
+ PositionedContent,
+ Outlines,
}
#[derive(HeapSizeOf, Deserialize, Serialize)]
@@ -591,6 +619,9 @@ pub struct StackingContext {
/// The layer info for this stacking context, if there is any.
pub layer_info: Option<LayerInfo>,
+
+ /// The LayerId of the last child layer of this stacking context.
+ pub last_child_layer_info: Option<LayerInfo>,
}
impl StackingContext {
@@ -620,29 +651,12 @@ impl StackingContext {
establishes_3d_context: establishes_3d_context,
scrolls_overflow_area: scrolls_overflow_area,
layer_info: layer_info,
+ last_child_layer_info: None,
};
StackingContextLayerCreator::add_layers_to_preserve_drawing_order(&mut stacking_context);
stacking_context
}
- pub fn create_layered_child(&self,
- layer_info: LayerInfo,
- display_list: Box<DisplayList>) -> StackingContext {
- StackingContext {
- display_list: display_list,
- bounds: self.bounds.clone(),
- overflow: self.overflow.clone(),
- z_index: self.z_index,
- filters: self.filters.clone(),
- blend_mode: self.blend_mode,
- transform: Matrix4::identity(),
- perspective: Matrix4::identity(),
- establishes_3d_context: false,
- scrolls_overflow_area: self.scrolls_overflow_area,
- layer_info: Some(layer_info),
- }
- }
-
/// Draws the stacking context in the proper order according to the steps in CSS 2.1 § E.2.
pub fn draw_into_context(&self,
display_list: &DisplayList,
@@ -752,11 +766,22 @@ impl StackingContext {
None => ScrollPolicy::Scrollable,
}
}
+
+ fn get_layer_info(&mut self, layer_id: LayerId) -> &mut LayerInfo {
+ for layer_info in self.display_list.layer_info.iter_mut() {
+ if layer_info.layer_id == layer_id {
+ return layer_info;
+ }
+ }
+
+ panic!("Could not find LayerInfo with id: {:?}", layer_id);
+ }
}
struct StackingContextLayerCreator {
display_list_for_next_layer: Option<DisplayList>,
next_layer_info: Option<LayerInfo>,
+ building_ordering_layer: bool,
}
impl StackingContextLayerCreator {
@@ -764,6 +789,7 @@ impl StackingContextLayerCreator {
StackingContextLayerCreator {
display_list_for_next_layer: None,
next_layer_info: None,
+ building_ordering_layer: false,
}
}
@@ -771,6 +797,15 @@ impl StackingContextLayerCreator {
fn add_layers_to_preserve_drawing_order(stacking_context: &mut StackingContext) {
let mut state = StackingContextLayerCreator::new();
+ state.layerize_display_list_section(DisplayListSection::BackgroundAndBorders,
+ stacking_context);
+ state.layerize_display_list_section(DisplayListSection::BlockBackgroundsAndBorders,
+ stacking_context);
+ state.layerize_display_list_section(DisplayListSection::Floats, stacking_context);
+ state.layerize_display_list_section(DisplayListSection::Content, stacking_context);
+ state.layerize_display_list_section(DisplayListSection::PositionedContent, stacking_context);
+ state.layerize_display_list_section(DisplayListSection::Outlines, stacking_context);
+
// First we need to sort child stacking contexts by z-index, so we can detect
// situations where unlayered ones should be on top of layered ones.
let existing_children = mem::replace(&mut stacking_context.display_list.children,
@@ -779,12 +814,12 @@ impl StackingContextLayerCreator {
sorted_children.extend(existing_children.into_iter());
sorted_children.sort_by(|this, other| this.z_index.cmp(&other.z_index));
- // FIXME(#7566, mrobinson): This should properly handle unlayered children that are on
- // top of unlayered children which have child stacking contexts with layers.
for child_stacking_context in sorted_children.into_iter() {
state.add_stacking_context(child_stacking_context, stacking_context);
}
state.finish_building_current_layer(stacking_context);
+ stacking_context.last_child_layer_info =
+ StackingContextLayerCreator::find_last_child_layer_info(stacking_context);
}
#[inline]
@@ -793,6 +828,97 @@ impl StackingContextLayerCreator {
}
#[inline]
+ fn layerize_display_list_section(&mut self,
+ section: DisplayListSection,
+ stacking_context: &mut StackingContext) {
+ let section_list = stacking_context.display_list.get_section_mut(section).split_off(0);
+ for item in section_list.into_iter() {
+ self.add_display_item(item, section, stacking_context);
+ }
+ }
+
+ #[inline]
+ fn display_item_needs_layer(&mut self, item: &DisplayItem) -> bool {
+ match *item {
+ LayeredItemClass(_) => true,
+ _ => self.all_following_children_need_layers(),
+ }
+ }
+
+ #[inline]
+ fn prepare_ordering_layer(&mut self,
+ stacking_context: &mut StackingContext) {
+ if self.building_ordering_layer {
+ assert!(self.next_layer_info.is_some());
+ return;
+ }
+
+ let next_layer_info = Some(stacking_context
+ .get_layer_info(self.next_layer_info.unwrap().layer_id)
+ .next_with_scroll_policy(ScrollPolicy::Scrollable));
+ self.finish_building_current_layer(stacking_context);
+ self.next_layer_info = next_layer_info;
+
+ self.building_ordering_layer = true;
+ }
+
+ fn add_display_item(&mut self,
+ item: DisplayItem,
+ section: DisplayListSection,
+ stacking_context: &mut StackingContext) {
+ if !self.display_item_needs_layer(&item) {
+ stacking_context.display_list.get_section_mut(section).push_back(item);
+ return;
+ }
+
+ if let LayeredItemClass(ref item) = item {
+ if let Some(ref next_layer_info) = self.next_layer_info {
+ if item.layer_id == next_layer_info.layer_id && !self.building_ordering_layer {
+ return;
+ }
+ }
+
+ self.finish_building_current_layer(stacking_context);
+ self.building_ordering_layer = false;
+ self.next_layer_info = Some(stacking_context.get_layer_info(item.layer_id).clone());
+ } else {
+ self.prepare_ordering_layer(stacking_context);
+ }
+
+ match item {
+ LayeredItemClass(layered_item) =>
+ self.add_display_item_to_display_list(layered_item.item, section),
+ _ => self.add_display_item_to_display_list(item, section),
+ }
+ }
+
+ fn add_display_item_to_display_list(&mut self,
+ item: DisplayItem,
+ section: DisplayListSection) {
+ if self.display_list_for_next_layer.is_none() {
+ self.display_list_for_next_layer = Some(DisplayList::new());
+ }
+
+ if let Some(ref mut display_list) = self.display_list_for_next_layer {
+ display_list.get_section_mut(section).push_back(item);
+ }
+ }
+
+ fn find_last_child_layer_info(stacking_context: &mut StackingContext) -> Option<LayerInfo> {
+ if let Some(layer) = stacking_context.display_list.layered_children.back() {
+ return Some(LayerInfo::new(layer.id, ScrollPolicy::Scrollable, None));
+ }
+
+ // We only care about the last child, because a layer in a child's hierarchy
+ // automatically gives following children a layer, so they will be in the
+ // 'layered_children' list instead of 'children'.
+ match stacking_context.display_list.children.back() {
+ Some(child) => child.last_child_layer_info,
+ None => None,
+ }
+ }
+
+ #[inline]
fn finish_building_current_layer(&mut self, stacking_context: &mut StackingContext) {
if let Some(display_list) = self.display_list_for_next_layer.take() {
let layer_info = self.next_layer_info.take().unwrap();
@@ -810,6 +936,15 @@ impl StackingContextLayerCreator {
return;
}
+ // This StackingContext has a layered child somewhere in its children.
+ // We need to give all new StackingContexts their own layer, so that they
+ // draw on top of this layered child.
+ if let Some(layer_info) = stacking_context.last_child_layer_info {
+ self.building_ordering_layer = true;
+ self.next_layer_info =
+ Some(layer_info.clone().next_with_scroll_policy(ScrollPolicy::Scrollable));
+ }
+
parent_stacking_context.display_list.children.push_back(stacking_context);
}
@@ -822,8 +957,10 @@ impl StackingContextLayerCreator {
// 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.
+ self.building_ordering_layer = true;
self.next_layer_info =
Some(layer_info.next_with_scroll_policy(parent_stacking_context.scroll_policy()));
+
parent_stacking_context.display_list.layered_children.push_back(
Arc::new(PaintLayer::new_with_stacking_context(layer_info,
stacking_context,
@@ -831,6 +968,8 @@ impl StackingContextLayerCreator {
return;
}
+ self.prepare_ordering_layer(parent_stacking_context);
+
if self.display_list_for_next_layer.is_none() {
self.display_list_for_next_layer = Some(DisplayList::new());
}
@@ -850,6 +989,8 @@ pub enum DisplayItem {
GradientClass(Box<GradientDisplayItem>),
LineClass(Box<LineDisplayItem>),
BoxShadowClass(Box<BoxShadowDisplayItem>),
+ LayeredItemClass(Box<LayeredItem>),
+ NoopClass(Box<BaseDisplayItem>),
}
/// Information common to all display items.
@@ -1254,6 +1395,16 @@ pub struct BoxShadowDisplayItem {
pub clip_mode: BoxShadowClipMode,
}
+/// Contains an item that should get its own layer during layer creation.
+#[derive(Clone, HeapSizeOf, Deserialize, Serialize)]
+pub struct LayeredItem {
+ /// Fields common to all display items.
+ pub item: DisplayItem,
+
+ /// The id of the layer this item belongs to.
+ pub layer_id: LayerId,
+}
+
/// How a box shadow should be clipped.
#[derive(Clone, Copy, Debug, PartialEq, HeapSizeOf, Deserialize, Serialize)]
pub enum BoxShadowClipMode {
@@ -1337,8 +1488,12 @@ impl DisplayItem {
box_shadow.color,
box_shadow.blur_radius,
box_shadow.spread_radius,
- box_shadow.clip_mode)
+ box_shadow.clip_mode);
}
+
+ DisplayItem::LayeredItemClass(_) => panic!("Found layered item during drawing."),
+
+ DisplayItem::NoopClass(_) => { }
}
}
@@ -1351,6 +1506,8 @@ impl DisplayItem {
DisplayItem::GradientClass(ref gradient) => &gradient.base,
DisplayItem::LineClass(ref line) => &line.base,
DisplayItem::BoxShadowClass(ref box_shadow) => &box_shadow.base,
+ DisplayItem::LayeredItemClass(ref layered_item) => layered_item.item.base(),
+ DisplayItem::NoopClass(ref base_item) => base_item,
}
}
@@ -1363,6 +1520,8 @@ impl DisplayItem {
DisplayItem::GradientClass(ref mut gradient) => &mut gradient.base,
DisplayItem::LineClass(ref mut line) => &mut line.base,
DisplayItem::BoxShadowClass(ref mut box_shadow) => &mut box_shadow.base,
+ DisplayItem::LayeredItemClass(ref mut layered_item) => layered_item.item.mut_base(),
+ DisplayItem::NoopClass(ref mut base_item) => base_item,
}
}
@@ -1395,6 +1554,9 @@ impl fmt::Debug for DisplayItem {
DisplayItem::GradientClass(_) => "Gradient".to_owned(),
DisplayItem::LineClass(_) => "Line".to_owned(),
DisplayItem::BoxShadowClass(_) => "BoxShadow".to_owned(),
+ DisplayItem::LayeredItemClass(ref layered_item) =>
+ format!("LayeredItem({:?})", layered_item.item),
+ DisplayItem::NoopClass(_) => "Noop".to_owned(),
},
self.base().bounds,
self.base().metadata.node.id()
diff --git a/components/gfx/paint_task.rs b/components/gfx/paint_task.rs
index 0c58155ab2d..e33432caf57 100644
--- a/components/gfx/paint_task.rs
+++ b/components/gfx/paint_task.rs
@@ -19,11 +19,10 @@ use gfx_traits::color;
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, LayerProperties, PaintListener};
-use msg::compositor_msg::{ScrollPolicy, SubpageLayerInfo};
+use msg::compositor_msg::{Epoch, FrameTreeId, LayerId, LayerKind, LayerProperties};
+use msg::compositor_msg::{PaintListener, ScrollPolicy};
use msg::constellation_msg::Msg as ConstellationMsg;
-use msg::constellation_msg::PipelineExitType;
-use msg::constellation_msg::{ConstellationChan, Failure, PipelineId};
+use msg::constellation_msg::{ConstellationChan, Failure, PipelineExitType, PipelineId};
use paint_context::PaintContext;
use profile_traits::mem::{self, ReportsChan};
use profile_traits::time::{self, profile};
@@ -60,8 +59,8 @@ pub struct PaintLayer {
pub bounds: Rect<Au>,
/// The scrolling policy of this layer.
pub scroll_policy: ScrollPolicy,
- /// The subpage that this layer represents, if there is one.
- pub subpage_layer_info: Option<SubpageLayerInfo>,
+ /// The pipeline of the subpage that this layer represents, if there is one.
+ pub subpage_pipeline_id: Option<PipelineId>,
}
impl PaintLayer {
@@ -78,7 +77,7 @@ impl PaintLayer {
contents: PaintLayerContents::StackingContext(stacking_context),
bounds: bounds,
scroll_policy: layer_info.scroll_policy,
- subpage_layer_info: layer_info.subpage_layer_info,
+ subpage_pipeline_id: layer_info.subpage_pipeline_id,
}
}
@@ -93,7 +92,7 @@ impl PaintLayer {
contents: PaintLayerContents::DisplayList(Arc::new(display_list)),
bounds: bounds,
scroll_policy: layer_info.scroll_policy,
- subpage_layer_info: layer_info.subpage_layer_info,
+ subpage_pipeline_id: layer_info.subpage_pipeline_id,
}
}
@@ -149,7 +148,7 @@ impl PaintLayer {
perspective: perspective,
establishes_3d_context: establishes_3d_context,
scrolls_overflow_area: scrolls_overflow_area,
- subpage_layer_info: self.subpage_layer_info,
+ subpage_pipeline_id: self.subpage_pipeline_id,
}
}
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index 299f0155e4d..37a3a543794 100644
--- a/components/layout/display_list_builder.rs
+++ b/components/layout/display_list_builder.rs
@@ -15,6 +15,7 @@ use azure::azure_hl::Color;
use block::BlockFlow;
use canvas_traits::{CanvasMsg, FromLayoutMsg};
use context::LayoutContext;
+use euclid::num::Zero;
use euclid::{Matrix4, Point2D, Point3D, Rect, SideOffsets2D, Size2D};
use flex::FlexFlow;
use flow::{self, BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED};
@@ -25,8 +26,8 @@ use gfx::display_list::{BLUR_INFLATION_FACTOR, BaseDisplayItem, BorderDisplayIte
use gfx::display_list::{BorderRadii, BoxShadowClipMode, BoxShadowDisplayItem, ClippingRegion};
use gfx::display_list::{DisplayItem, DisplayItemMetadata, DisplayList};
use gfx::display_list::{GradientDisplayItem};
-use gfx::display_list::{GradientStop, ImageDisplayItem, LayerInfo, LineDisplayItem};
-use gfx::display_list::{OpaqueNode, SolidColorDisplayItem};
+use gfx::display_list::{GradientStop, ImageDisplayItem, LayeredItem, LayerInfo};
+use gfx::display_list::{LineDisplayItem, OpaqueNode, SolidColorDisplayItem};
use gfx::display_list::{StackingContext, TextDisplayItem, TextOrientation};
use gfx::paint_task::THREAD_TINT_COLORS;
use gfx::text::glyph::CharIndex;
@@ -35,7 +36,7 @@ use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT};
use ipc_channel::ipc::{self, IpcSharedMemory};
use list_item::ListItemFlow;
use model::{self, MaybeAuto, ToGfxMatrix};
-use msg::compositor_msg::{ScrollPolicy, SubpageLayerInfo};
+use msg::compositor_msg::ScrollPolicy;
use net_traits::image::base::{Image, PixelFormat};
use net_traits::image_cache_task::UsePlaceholder;
use std::default::Default;
@@ -1098,7 +1099,6 @@ impl FragmentDisplayListBuilding for Fragment {
}
SpecificFragmentInfo::Generic |
SpecificFragmentInfo::GeneratedContent(..) |
- SpecificFragmentInfo::Iframe(..) |
SpecificFragmentInfo::Table |
SpecificFragmentInfo::TableCell |
SpecificFragmentInfo::TableRow |
@@ -1112,6 +1112,27 @@ impl FragmentDisplayListBuilding for Fragment {
clip);
}
}
+ SpecificFragmentInfo::Iframe(ref fragment_info) => {
+ // TODO(mrobinson): When https://github.com/servo/euclid/issues/109 is fixed this
+ // check can just become stacking_relative_content_box.is_empty().
+ if stacking_relative_content_box.size.width != Zero::zero() &&
+ stacking_relative_content_box.size.height != Zero::zero() {
+ let layer_id = self.layer_id();
+ display_list.content.push_back(DisplayItem::LayeredItemClass(box LayeredItem {
+ item: DisplayItem::NoopClass(
+ box BaseDisplayItem::new(stacking_relative_content_box,
+ DisplayItemMetadata::new(self.node,
+ &*self.style,
+ Cursor::DefaultCursor),
+ (*clip).clone())),
+ layer_id: layer_id
+ }));
+
+ display_list.layer_info.push_back(LayerInfo::new(layer_id,
+ ScrollPolicy::Scrollable,
+ Some(fragment_info.pipeline_id)));
+ }
+ }
SpecificFragmentInfo::Image(ref mut image_fragment) => {
// Place the image into the display list.
if let Some(ref image) = image_fragment.image {
@@ -1284,19 +1305,8 @@ impl FragmentDisplayListBuilding for Fragment {
filters.push(Filter::Opacity(effects.opacity))
}
- let subpage_layer_info = match self.specific {
- SpecificFragmentInfo::Iframe(ref iframe_fragment_info) => {
- let border_padding = self.border_padding.to_physical(self.style().writing_mode);
- Some(SubpageLayerInfo {
- pipeline_id: iframe_fragment_info.pipeline_id,
- origin: Point2D::new(border_padding.left, border_padding.top),
- })
- }
- _ => None,
- };
-
- let canvas_or_iframe = match self.specific {
- SpecificFragmentInfo::Canvas(_) | SpecificFragmentInfo::Iframe(_) => true,
+ let canvas = match self.specific {
+ SpecificFragmentInfo::Canvas(_) => true,
_ => false
};
@@ -1304,11 +1314,9 @@ impl FragmentDisplayListBuilding for Fragment {
// flag, when this is a canvas or iframe fragment, and when we are building a layer
// tree for overflow scrolling.
let layer_info = if mode == StackingContextCreationMode::InnerScrollWrapper {
- Some(LayerInfo::new(self.layer_id_for_overflow_scroll(),
- scroll_policy,
- subpage_layer_info))
- } else if self.flags.contains(HAS_LAYER) || canvas_or_iframe {
- Some(LayerInfo::new(self.layer_id(), scroll_policy, subpage_layer_info))
+ Some(LayerInfo::new(self.layer_id_for_overflow_scroll(), scroll_policy, None))
+ } else if self.flags.contains(HAS_LAYER) || canvas {
+ Some(LayerInfo::new(self.layer_id(), scroll_policy, None))
} else {
None
};
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index 308532d9768..3623e1c5d76 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -2107,11 +2107,11 @@ impl Fragment {
}
/// Returns true if this fragment unconditionally layerizes.
- pub fn needs_layer(&self) -> bool {
+ pub fn needs_layered_stacking_context(&self) -> bool {
// Canvas and iframes always layerize, as an special case
// FIXME(pcwalton): Don't unconditionally form stacking contexts for each canvas.
match self.specific {
- SpecificFragmentInfo::Canvas(_) | SpecificFragmentInfo::Iframe(_) => true,
+ SpecificFragmentInfo::Canvas(_) => true,
_ => false,
}
}
@@ -2140,7 +2140,7 @@ impl Fragment {
transform_style::T::auto => {}
}
- if self.needs_layer() {
+ if self.needs_layered_stacking_context() {
return true
}
diff --git a/components/layout/inline.rs b/components/layout/inline.rs
index d6704405e1b..dbe61662b12 100644
--- a/components/layout/inline.rs
+++ b/components/layout/inline.rs
@@ -1496,7 +1496,7 @@ impl Flow for InlineFlow {
for fragment_index in line.range.each_index() {
let fragment = &mut self.fragments.fragments[fragment_index.to_usize()];
- if fragment.needs_layer() && !fragment.is_positioned() {
+ if fragment.needs_layered_stacking_context() && !fragment.is_positioned() {
layers_needed_for_descendants = true
}
diff --git a/components/msg/compositor_msg.rs b/components/msg/compositor_msg.rs
index 8c411148c9a..e7612351724 100644
--- a/components/msg/compositor_msg.rs
+++ b/components/msg/compositor_msg.rs
@@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use app_units::Au;
use azure::azure_hl::Color;
use constellation_msg::{Key, KeyModifiers, KeyState, PipelineId};
use euclid::{Matrix4, Point2D, Rect, Size2D};
@@ -120,7 +119,7 @@ pub struct LayerProperties {
pub perspective: Matrix4,
/// The subpage that this layer represents. If this is `Some`, this layer represents an
/// iframe.
- pub subpage_layer_info: Option<SubpageLayerInfo>,
+ pub subpage_pipeline_id: Option<PipelineId>,
/// Whether this layer establishes a new 3d rendering context.
pub establishes_3d_context: bool,
/// Whether this layer scrolls its overflow area.
@@ -163,13 +162,3 @@ pub enum ScriptToCompositorMsg {
ResizeTo(Size2D<u32>),
Exit,
}
-
-/// Subpage (i.e. iframe)-specific information about each layer.
-#[derive(Clone, Copy, Debug, Deserialize, Serialize, HeapSizeOf)]
-pub struct SubpageLayerInfo {
- /// The ID of the pipeline.
- pub pipeline_id: PipelineId,
- /// The offset of the subpage within this layer (to account for borders).
- pub origin: Point2D<Au>,
-}
-
diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock
index 20c56d42776..81b62bf7a1f 100644
--- a/components/servo/Cargo.lock
+++ b/components/servo/Cargo.lock
@@ -978,7 +978,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "layers"
version = "0.1.0"
-source = "git+https://github.com/servo/rust-layers#497a54e403ff737c35e47b29c664ed8ae8ee26cf"
+source = "git+https://github.com/servo/rust-layers#5af8c6bb9801e4f8d337c6a74a0bb2641ab48e0e"
dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock
index b92931c5a7c..04a658e73fe 100644
--- a/ports/cef/Cargo.lock
+++ b/ports/cef/Cargo.lock
@@ -928,7 +928,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "layers"
version = "0.1.0"
-source = "git+https://github.com/servo/rust-layers#497a54e403ff737c35e47b29c664ed8ae8ee26cf"
+source = "git+https://github.com/servo/rust-layers#5af8c6bb9801e4f8d337c6a74a0bb2641ab48e0e"
dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock
index c5b2291d0d8..ef5b60b87ad 100644
--- a/ports/gonk/Cargo.lock
+++ b/ports/gonk/Cargo.lock
@@ -808,7 +808,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "layers"
version = "0.1.0"
-source = "git+https://github.com/servo/rust-layers#497a54e403ff737c35e47b29c664ed8ae8ee26cf"
+source = "git+https://github.com/servo/rust-layers#5af8c6bb9801e4f8d337c6a74a0bb2641ab48e0e"
dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/tests/wpt/mozilla/tests/css/stacked_layers.html b/tests/wpt/mozilla/tests/css/stacked_layers.html
index a0edbaf667c..d135ab144cd 100644
--- a/tests/wpt/mozilla/tests/css/stacked_layers.html
+++ b/tests/wpt/mozilla/tests/css/stacked_layers.html
@@ -8,6 +8,7 @@
.gray { background: rgb(200, 200, 200); }
.grayer { background: rgb(80, 80, 80); }
.grayest { background: rgb(0, 0, 0); }
+ iframe { display: block; border: 0; }
</style>
</head>
<body>
@@ -27,5 +28,20 @@
<div class="grayer box" style="margin-left: 10px; margin-top: 10px; opacity: 0.999; z-index: -1;"></div>
<div class="gray box" style="margin-left: 20px; margin-top: -40px; opacity: 0.999;"> </div>
</div>
+
+ <!-- The iframe should be painted in tree order since it is not positioned and
+ the following div is. -->
+ <div class="test grayest box">
+ <iframe class="box" style="margin-left: 10px; margin-top: 10px;" src="data:text/html;charset=utf-8;base64,PGh0bWw+PGJvZHkgc3R5bGU9ImJhY2tncm91bmQ6IHJnYig4MCwgODAsIDgwKTsiPjwvYm9keT48L2Rpdj4="></iframe>
+ <div class="gray box" style="position: relative; left: 20px; top: -40px;"> </div>
+ </div>
+
+ <!-- The iframe should be painted in tree order since both it and the inner div are
+ not positioned elements. -->
+ <div class="test grayest box">
+ <iframe class="box" style="position: relative; left: 10px; top: 10px;" src="data:text/html;charset=utf-8;base64,PGh0bWw+PGJvZHkgc3R5bGU9ImJhY2tncm91bmQ6IHJnYig4MCwgODAsIDgwKTsiPjwvYm9keT48L2Rpdj4="></iframe>
+ <div class="gray box" style="position: relative; left: 20px; top: -30px;"> </div>
+ </div>
+
</body>
</html>
diff --git a/tests/wpt/mozilla/tests/css/stacked_layers_ref.html b/tests/wpt/mozilla/tests/css/stacked_layers_ref.html
index fbec3c30c7d..a166e23cae7 100644
--- a/tests/wpt/mozilla/tests/css/stacked_layers_ref.html
+++ b/tests/wpt/mozilla/tests/css/stacked_layers_ref.html
@@ -24,5 +24,15 @@
<div class="grayer box" style="margin-left: 10px; margin-top: 10px; position: absolute; opacity: 0.999;"></div>
<div class="gray box" style="margin-left: 20px; margin-top: 20px; position: relative; opacity: 0.999;"></div>
</div>
+
+ <div class="test grayest box">
+ <div class="grayer box" style="margin-left: 10px; margin-top: 10px;"></div>
+ <div class="gray box" style="margin-left: 20px; margin-top: -40px;"></div>
+ </div>
+
+ <div class="test grayest box">
+ <div class="grayer box" style="margin-left: 10px; margin-top: 10px;"></div>
+ <div class="gray box" style="margin-left: 20px; margin-top: -40px;"></div>
+ </div>
</body>
</html>