mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
Auto merge of #9843 - pcwalton:optimize-flat-display-lists, r=mrobinson
Optimize flat display lists Flat display lists were a 2x regression on the spheres demo. This patch series fixes that. See the individual commits for more details. r? @mrobinson <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.svg" height="40" alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9843) <!-- Reviewable:end -->
This commit is contained in:
commit
55fc48e4c4
19 changed files with 241 additions and 231 deletions
|
@ -21,15 +21,22 @@ use euclid::approxeq::ApproxEq;
|
||||||
use euclid::num::Zero;
|
use euclid::num::Zero;
|
||||||
use euclid::rect::TypedRect;
|
use euclid::rect::TypedRect;
|
||||||
use euclid::{Matrix2D, Matrix4, Point2D, Rect, SideOffsets2D, Size2D};
|
use euclid::{Matrix2D, Matrix4, Point2D, Rect, SideOffsets2D, Size2D};
|
||||||
|
use fnv::FnvHasher;
|
||||||
use gfx_traits::{LayerId, ScrollPolicy};
|
use gfx_traits::{LayerId, ScrollPolicy};
|
||||||
use heapsize::HeapSizeOf;
|
use heapsize::HeapSizeOf;
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use net_traits::image::base::Image;
|
use net_traits::image::base::Image;
|
||||||
use paint_context::PaintContext;
|
use paint_context::PaintContext;
|
||||||
use range::Range;
|
use range::Range;
|
||||||
|
use serde::de::{self, Deserialize, Deserializer, MapVisitor, Visitor};
|
||||||
|
use serde::ser::impls::MapIteratorVisitor;
|
||||||
|
use serde::ser::{Serialize, Serializer};
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::hash::{BuildHasherDefault, Hash};
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use style::computed_values::{border_style, cursor, filter, image_rendering, mix_blend_mode};
|
use style::computed_values::{border_style, cursor, filter, image_rendering, mix_blend_mode};
|
||||||
use style::computed_values::{pointer_events};
|
use style::computed_values::{pointer_events};
|
||||||
|
@ -141,10 +148,75 @@ pub struct StackingContextOffsets {
|
||||||
pub outlines: u32,
|
pub outlines: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A FNV-based hash map. This is not serializable by `serde` by default, so we provide an
|
||||||
|
/// implementation ourselves.
|
||||||
|
pub struct FnvHashMap<K, V>(pub HashMap<K, V, BuildHasherDefault<FnvHasher>>);
|
||||||
|
|
||||||
|
impl<K, V> Deref for FnvHashMap<K, V> {
|
||||||
|
type Target = HashMap<K, V, BuildHasherDefault<FnvHasher>>;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K, V> DerefMut for FnvHashMap<K, V> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K, V> Serialize for FnvHashMap<K, V> where K: Eq + Hash + Serialize, V: Serialize {
|
||||||
|
#[inline]
|
||||||
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
|
||||||
|
serializer.visit_map(MapIteratorVisitor::new(self.iter(), Some(self.len())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K, V> Deserialize for FnvHashMap<K, V> where K: Eq + Hash + Deserialize, V: Deserialize {
|
||||||
|
#[inline]
|
||||||
|
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where D: Deserializer {
|
||||||
|
deserializer.visit_map(FnvHashMapVisitor::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A visitor that produces a map.
|
||||||
|
pub struct FnvHashMapVisitor<K, V> {
|
||||||
|
marker: PhantomData<FnvHashMap<K, V>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K, V> FnvHashMapVisitor<K, V> {
|
||||||
|
/// Construct a `FnvHashMapVisitor<T>`.
|
||||||
|
pub fn new() -> Self {
|
||||||
|
FnvHashMapVisitor {
|
||||||
|
marker: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K, V> Visitor for FnvHashMapVisitor<K, V> where K: Eq + Hash + Deserialize, V: Deserialize {
|
||||||
|
type Value = FnvHashMap<K, V>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_unit<E>(&mut self) -> Result<FnvHashMap<K, V>, E> where E: de::Error {
|
||||||
|
Ok(FnvHashMap(HashMap::with_hasher(Default::default())))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_map<Visitor>(&mut self, mut visitor: Visitor)
|
||||||
|
-> Result<FnvHashMap<K, V>, Visitor::Error>
|
||||||
|
where Visitor: MapVisitor {
|
||||||
|
let mut values = FnvHashMap(HashMap::with_hasher(Default::default()));
|
||||||
|
while let Some((key, value)) = try!(visitor.visit()) {
|
||||||
|
HashMap::insert(&mut values, key, value);
|
||||||
|
}
|
||||||
|
try!(visitor.end());
|
||||||
|
Ok(values)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(HeapSizeOf, Deserialize, Serialize)]
|
#[derive(HeapSizeOf, Deserialize, Serialize)]
|
||||||
pub struct DisplayList {
|
pub struct DisplayList {
|
||||||
pub list: Vec<DisplayListEntry>,
|
pub list: Vec<DisplayListEntry>,
|
||||||
pub offsets: HashMap<StackingContextId, StackingContextOffsets>,
|
pub offsets: FnvHashMap<StackingContextId, StackingContextOffsets>,
|
||||||
pub root_stacking_context: StackingContext,
|
pub root_stacking_context: StackingContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +229,7 @@ impl DisplayList {
|
||||||
None => panic!("Tried to create empty display list."),
|
None => panic!("Tried to create empty display list."),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut offsets = HashMap::new();
|
let mut offsets = FnvHashMap(HashMap::with_hasher(Default::default()));
|
||||||
DisplayList::sort_and_count_stacking_contexts(&mut root_stacking_context, &mut offsets, 0);
|
DisplayList::sort_and_count_stacking_contexts(&mut root_stacking_context, &mut offsets, 0);
|
||||||
|
|
||||||
let mut display_list = DisplayList {
|
let mut display_list = DisplayList {
|
||||||
|
@ -201,7 +273,9 @@ impl DisplayList {
|
||||||
|
|
||||||
fn sort_and_count_stacking_contexts(
|
fn sort_and_count_stacking_contexts(
|
||||||
stacking_context: &mut StackingContext,
|
stacking_context: &mut StackingContext,
|
||||||
offsets: &mut HashMap<StackingContextId, StackingContextOffsets>,
|
offsets: &mut HashMap<StackingContextId,
|
||||||
|
StackingContextOffsets,
|
||||||
|
BuildHasherDefault<FnvHasher>>,
|
||||||
mut current_offset: u32)
|
mut current_offset: u32)
|
||||||
-> u32 {
|
-> u32 {
|
||||||
stacking_context.children.sort();
|
stacking_context.children.sort();
|
||||||
|
@ -508,7 +582,7 @@ pub struct StackingContext {
|
||||||
pub layer_info: Option<LayerInfo>,
|
pub layer_info: Option<LayerInfo>,
|
||||||
|
|
||||||
/// Children of this StackingContext.
|
/// Children of this StackingContext.
|
||||||
pub children: Vec<StackingContext>,
|
pub children: Vec<Box<StackingContext>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StackingContext {
|
impl StackingContext {
|
||||||
|
@ -761,16 +835,13 @@ impl ClippingRegion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the intersection of this clipping region and the given rectangle.
|
/// Mutates this clipping region to intersect with the given rectangle.
|
||||||
///
|
///
|
||||||
/// TODO(pcwalton): This could more eagerly eliminate complex clipping regions, at the cost of
|
/// TODO(pcwalton): This could more eagerly eliminate complex clipping regions, at the cost of
|
||||||
/// complexity.
|
/// complexity.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn intersect_rect(self, rect: &Rect<Au>) -> ClippingRegion {
|
pub fn intersect_rect(&mut self, rect: &Rect<Au>) {
|
||||||
ClippingRegion {
|
self.main = self.main.intersection(rect).unwrap_or(Rect::zero())
|
||||||
main: self.main.intersection(rect).unwrap_or(Rect::zero()),
|
|
||||||
complex: self.complex,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if this clipping region might be nonempty. This can return false positives,
|
/// Returns true if this clipping region might be nonempty. This can return false positives,
|
||||||
|
|
|
@ -64,7 +64,6 @@ use style::properties::ComputedValues;
|
||||||
use style::values::computed::{LengthOrNone, LengthOrPercentageOrNone};
|
use style::values::computed::{LengthOrNone, LengthOrPercentageOrNone};
|
||||||
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
|
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
|
||||||
use util::geometry::MAX_RECT;
|
use util::geometry::MAX_RECT;
|
||||||
use util::opts;
|
|
||||||
use util::print_tree::PrintTree;
|
use util::print_tree::PrintTree;
|
||||||
|
|
||||||
/// Information specific to floated blocks.
|
/// Information specific to floated blocks.
|
||||||
|
@ -1622,14 +1621,18 @@ impl BlockFlow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn establishes_pseudo_stacking_context(&self) -> bool {
|
pub fn block_stacking_context_type(&self) -> BlockStackingContextType {
|
||||||
if self.fragment.establishes_stacking_context() {
|
if self.fragment.establishes_stacking_context() {
|
||||||
return false;
|
return BlockStackingContextType::StackingContext
|
||||||
}
|
}
|
||||||
|
|
||||||
self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) ||
|
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) ||
|
||||||
self.fragment.style.get_box().position != position::T::static_ ||
|
self.fragment.style.get_box().position != position::T::static_ ||
|
||||||
self.base.flags.is_float()
|
self.base.flags.is_float() {
|
||||||
|
BlockStackingContextType::PseudoStackingContext
|
||||||
|
} else {
|
||||||
|
BlockStackingContextType::NonstackingContext
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_scrolling_overflow(&self) -> bool {
|
pub fn has_scrolling_overflow(&self) -> bool {
|
||||||
|
@ -1954,8 +1957,10 @@ impl Flow for BlockFlow {
|
||||||
self.base.position.size.to_physical(self.base.writing_mode);
|
self.base.position.size.to_physical(self.base.writing_mode);
|
||||||
|
|
||||||
// Compute the origin and clipping rectangle for children.
|
// Compute the origin and clipping rectangle for children.
|
||||||
|
//
|
||||||
|
// `clip` is in the child coordinate system.
|
||||||
|
let mut clip;
|
||||||
let origin_for_children;
|
let origin_for_children;
|
||||||
let clip_in_child_coordinate_system;
|
|
||||||
let is_stacking_context = self.fragment.establishes_stacking_context();
|
let is_stacking_context = self.fragment.establishes_stacking_context();
|
||||||
if is_stacking_context {
|
if is_stacking_context {
|
||||||
// We establish a stacking context, so the position of our children is vertically
|
// We establish a stacking context, so the position of our children is vertically
|
||||||
|
@ -1966,12 +1971,11 @@ impl Flow for BlockFlow {
|
||||||
// FIXME(pcwalton): Is this vertical-writing-direction-safe?
|
// FIXME(pcwalton): Is this vertical-writing-direction-safe?
|
||||||
let margin = self.fragment.margin.to_physical(self.base.writing_mode);
|
let margin = self.fragment.margin.to_physical(self.base.writing_mode);
|
||||||
origin_for_children = Point2D::new(-margin.left, Au(0));
|
origin_for_children = Point2D::new(-margin.left, Au(0));
|
||||||
clip_in_child_coordinate_system =
|
clip = self.base.clip.translate(&-self.base.stacking_relative_position);
|
||||||
self.base.clip.translate(&-self.base.stacking_relative_position);
|
|
||||||
} else {
|
} else {
|
||||||
let relative_offset = relative_offset.to_physical(self.base.writing_mode);
|
let relative_offset = relative_offset.to_physical(self.base.writing_mode);
|
||||||
origin_for_children = self.base.stacking_relative_position + relative_offset;
|
origin_for_children = self.base.stacking_relative_position + relative_offset;
|
||||||
clip_in_child_coordinate_system = self.base.clip.clone();
|
clip = self.base.clip.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
let stacking_relative_position_of_display_port_for_children =
|
let stacking_relative_position_of_display_port_for_children =
|
||||||
|
@ -2003,8 +2007,8 @@ impl Flow for BlockFlow {
|
||||||
.early_absolute_position_info
|
.early_absolute_position_info
|
||||||
.relative_containing_block_mode,
|
.relative_containing_block_mode,
|
||||||
CoordinateSystem::Own);
|
CoordinateSystem::Own);
|
||||||
let clip = self.fragment.clipping_region_for_children(
|
self.fragment.adjust_clipping_region_for_children(
|
||||||
&clip_in_child_coordinate_system,
|
&mut clip,
|
||||||
&stacking_relative_border_box,
|
&stacking_relative_border_box,
|
||||||
self.base.flags.contains(IS_ABSOLUTELY_POSITIONED));
|
self.base.flags.contains(IS_ABSOLUTELY_POSITIONED));
|
||||||
|
|
||||||
|
@ -2109,7 +2113,7 @@ impl Flow for BlockFlow {
|
||||||
|
|
||||||
fn collect_stacking_contexts(&mut self,
|
fn collect_stacking_contexts(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
contexts: &mut Vec<StackingContext>)
|
contexts: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId {
|
-> StackingContextId {
|
||||||
self.collect_stacking_contexts_for_block(parent_id, contexts)
|
self.collect_stacking_contexts_for_block(parent_id, contexts)
|
||||||
}
|
}
|
||||||
|
@ -2117,9 +2121,6 @@ impl Flow for BlockFlow {
|
||||||
fn build_display_list(&mut self, state: &mut DisplayListBuildState) {
|
fn build_display_list(&mut self, state: &mut DisplayListBuildState) {
|
||||||
self.build_display_list_for_block(state, BorderPaintingMode::Separate);
|
self.build_display_list_for_block(state, BorderPaintingMode::Separate);
|
||||||
self.fragment.restyle_damage.remove(REPAINT);
|
self.fragment.restyle_damage.remove(REPAINT);
|
||||||
if opts::get().validate_display_list_geometry {
|
|
||||||
self.base.validate_display_list_geometry();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn repair_style(&mut self, new_style: &Arc<ComputedValues>) {
|
fn repair_style(&mut self, new_style: &Arc<ComputedValues>) {
|
||||||
|
@ -3036,3 +3037,12 @@ impl ISizeAndMarginsComputer for InlineBlockReplaced {
|
||||||
MaybeAuto::Specified(fragment.content_inline_size())
|
MaybeAuto::Specified(fragment.content_inline_size())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A stacking context, a pseudo-stacking context, or a non-stacking context.
|
||||||
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
|
pub enum BlockStackingContextType {
|
||||||
|
NonstackingContext,
|
||||||
|
PseudoStackingContext,
|
||||||
|
StackingContext,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,13 +12,13 @@
|
||||||
|
|
||||||
use app_units::{Au, AU_PER_PX};
|
use app_units::{Au, AU_PER_PX};
|
||||||
use azure::azure_hl::Color;
|
use azure::azure_hl::Color;
|
||||||
use block::BlockFlow;
|
use block::{BlockFlow, BlockStackingContextType};
|
||||||
use canvas_traits::{CanvasMsg, CanvasPixelData, CanvasData, FromLayoutMsg};
|
use canvas_traits::{CanvasMsg, CanvasPixelData, CanvasData, FromLayoutMsg};
|
||||||
use context::LayoutContext;
|
use context::LayoutContext;
|
||||||
use euclid::num::Zero;
|
use euclid::num::Zero;
|
||||||
use euclid::{Matrix4, Point2D, Point3D, Rect, SideOffsets2D, Size2D};
|
use euclid::{Matrix4, Point2D, Point3D, Rect, SideOffsets2D, Size2D};
|
||||||
use flex::FlexFlow;
|
use flex::FlexFlow;
|
||||||
use flow::{self, BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED};
|
use flow::{BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED};
|
||||||
use flow_ref;
|
use flow_ref;
|
||||||
use fragment::{CoordinateSystem, Fragment, HAS_LAYER, ImageFragmentInfo, ScannedTextFragmentInfo};
|
use fragment::{CoordinateSystem, Fragment, HAS_LAYER, ImageFragmentInfo, ScannedTextFragmentInfo};
|
||||||
use fragment::{SpecificFragmentInfo};
|
use fragment::{SpecificFragmentInfo};
|
||||||
|
@ -67,8 +67,7 @@ pub struct DisplayListBuildState<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DisplayListBuildState<'a> {
|
impl<'a> DisplayListBuildState<'a> {
|
||||||
pub fn new(layout_context: &'a LayoutContext,
|
pub fn new(layout_context: &'a LayoutContext, stacking_context_id: StackingContextId)
|
||||||
stacking_context_id: StackingContextId)
|
|
||||||
-> DisplayListBuildState<'a> {
|
-> DisplayListBuildState<'a> {
|
||||||
DisplayListBuildState {
|
DisplayListBuildState {
|
||||||
layout_context: layout_context,
|
layout_context: layout_context,
|
||||||
|
@ -87,21 +86,15 @@ impl<'a> DisplayListBuildState<'a> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_from(&mut self, other_list: &mut Option<Vec<DisplayListEntry>>) {
|
|
||||||
if let Some(mut other) = other_list.take() {
|
|
||||||
self.items.append(&mut other);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn stacking_context_id(&self) -> StackingContextId {
|
fn stacking_context_id(&self) -> StackingContextId {
|
||||||
self.stacking_context_id_stack.last().unwrap().clone()
|
self.stacking_context_id_stack.last().unwrap().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_stacking_context_id(&mut self, stacking_context_id: StackingContextId) {
|
pub fn push_stacking_context_id(&mut self, stacking_context_id: StackingContextId) {
|
||||||
self.stacking_context_id_stack.push(stacking_context_id);
|
self.stacking_context_id_stack.push(stacking_context_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pop_stacking_context_id(&mut self) {
|
pub fn pop_stacking_context_id(&mut self) {
|
||||||
self.stacking_context_id_stack.pop();
|
self.stacking_context_id_stack.pop();
|
||||||
assert!(!self.stacking_context_id_stack.is_empty());
|
assert!(!self.stacking_context_id_stack.is_empty());
|
||||||
}
|
}
|
||||||
|
@ -232,19 +225,17 @@ pub trait FragmentDisplayListBuilding {
|
||||||
clip: &ClippingRegion,
|
clip: &ClippingRegion,
|
||||||
stacking_relative_display_port: &Rect<Au>);
|
stacking_relative_display_port: &Rect<Au>);
|
||||||
|
|
||||||
/// Returns the appropriate clipping region for descendants of this fragment.
|
/// Adjusts the clipping region for descendants of this fragment as appropriate.
|
||||||
fn clipping_region_for_children(&self,
|
fn adjust_clipping_region_for_children(&self,
|
||||||
current_clip: &ClippingRegion,
|
current_clip: &mut ClippingRegion,
|
||||||
stacking_relative_border_box: &Rect<Au>,
|
stacking_relative_border_box: &Rect<Au>,
|
||||||
is_absolutely_positioned: bool)
|
is_absolutely_positioned: bool);
|
||||||
-> ClippingRegion;
|
|
||||||
|
|
||||||
/// Calculates the clipping rectangle for a fragment, taking the `clip` property into account
|
/// Adjusts the clipping rectangle for a fragment to take the `clip` property into account
|
||||||
/// per CSS 2.1 § 11.1.2.
|
/// per CSS 2.1 § 11.1.2.
|
||||||
fn calculate_style_specified_clip(&self,
|
fn adjust_clip_for_style(&self,
|
||||||
parent_clip: &ClippingRegion,
|
parent_clip: &mut ClippingRegion,
|
||||||
stacking_relative_border_box: &Rect<Au>)
|
stacking_relative_border_box: &Rect<Au>);
|
||||||
-> ClippingRegion;
|
|
||||||
|
|
||||||
/// Builds the display items necessary to paint the selection and/or caret for this fragment,
|
/// Builds the display items necessary to paint the selection and/or caret for this fragment,
|
||||||
/// if any.
|
/// if any.
|
||||||
|
@ -287,7 +278,7 @@ pub trait FragmentDisplayListBuilding {
|
||||||
base_flow: &BaseFlow,
|
base_flow: &BaseFlow,
|
||||||
scroll_policy: ScrollPolicy,
|
scroll_policy: ScrollPolicy,
|
||||||
mode: StackingContextCreationMode)
|
mode: StackingContextCreationMode)
|
||||||
-> StackingContext;
|
-> Box<StackingContext>;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_overlapping_radii(size: &Size2D<Au>, radii: &BorderRadii<Au>) -> BorderRadii<Au> {
|
fn handle_overlapping_radii(size: &Size2D<Au>, radii: &BorderRadii<Au>) -> BorderRadii<Au> {
|
||||||
|
@ -482,7 +473,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
// Clip.
|
// Clip.
|
||||||
//
|
//
|
||||||
// TODO: Check the bounds to see if a clip item is actually required.
|
// TODO: Check the bounds to see if a clip item is actually required.
|
||||||
let clip = clip.clone().intersect_rect(&bounds);
|
let mut clip = clip.clone();
|
||||||
|
clip.intersect_rect(&bounds);
|
||||||
|
|
||||||
// Background image should be positioned on the padding box basis.
|
// Background image should be positioned on the padding box basis.
|
||||||
let border = style.logical_border_width().to_physical(style.writing_mode);
|
let border = style.logical_border_width().to_physical(style.writing_mode);
|
||||||
|
@ -581,7 +573,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
clip: &ClippingRegion,
|
clip: &ClippingRegion,
|
||||||
gradient: &LinearGradient,
|
gradient: &LinearGradient,
|
||||||
style: &ComputedValues) {
|
style: &ComputedValues) {
|
||||||
let clip = clip.clone().intersect_rect(absolute_bounds);
|
let mut clip = clip.clone();
|
||||||
|
clip.intersect_rect(absolute_bounds);
|
||||||
|
|
||||||
// This is the distance between the center and the ending point; i.e. half of the distance
|
// This is the distance between the center and the ending point; i.e. half of the distance
|
||||||
// between the starting point and the ending point.
|
// between the starting point and the ending point.
|
||||||
|
@ -894,15 +887,14 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
}), DisplayListSection::Content);
|
}), DisplayListSection::Content);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_style_specified_clip(&self,
|
fn adjust_clip_for_style(&self,
|
||||||
parent_clip: &ClippingRegion,
|
parent_clip: &mut ClippingRegion,
|
||||||
stacking_relative_border_box: &Rect<Au>)
|
stacking_relative_border_box: &Rect<Au>) {
|
||||||
-> ClippingRegion {
|
|
||||||
// Account for `clip` per CSS 2.1 § 11.1.2.
|
// Account for `clip` per CSS 2.1 § 11.1.2.
|
||||||
let style_clip_rect = match (self.style().get_box().position,
|
let style_clip_rect = match (self.style().get_box().position,
|
||||||
self.style().get_effects().clip.0) {
|
self.style().get_effects().clip.0) {
|
||||||
(position::T::absolute, Some(style_clip_rect)) => style_clip_rect,
|
(position::T::absolute, Some(style_clip_rect)) => style_clip_rect,
|
||||||
_ => return (*parent_clip).clone(),
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME(pcwalton, #2795): Get the real container size.
|
// FIXME(pcwalton, #2795): Get the real container size.
|
||||||
|
@ -911,7 +903,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
let right = style_clip_rect.right.unwrap_or(stacking_relative_border_box.size.width);
|
let right = style_clip_rect.right.unwrap_or(stacking_relative_border_box.size.width);
|
||||||
let bottom = style_clip_rect.bottom.unwrap_or(stacking_relative_border_box.size.height);
|
let bottom = style_clip_rect.bottom.unwrap_or(stacking_relative_border_box.size.height);
|
||||||
let clip_size = Size2D::new(right - clip_origin.x, bottom - clip_origin.y);
|
let clip_size = Size2D::new(right - clip_origin.x, bottom - clip_origin.y);
|
||||||
(*parent_clip).clone().intersect_rect(&Rect::new(clip_origin, clip_size))
|
parent_clip.intersect_rect(&Rect::new(clip_origin, clip_size))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_display_items_for_selection_if_necessary(&self,
|
fn build_display_items_for_selection_if_necessary(&self,
|
||||||
|
@ -996,7 +988,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
|
|
||||||
// Calculate the clip rect. If there's nothing to render at all, don't even construct
|
// Calculate the clip rect. If there's nothing to render at all, don't even construct
|
||||||
// display list items.
|
// display list items.
|
||||||
let clip = self.calculate_style_specified_clip(clip, &stacking_relative_border_box);
|
let mut clip = (*clip).clone();
|
||||||
|
self.adjust_clip_for_style(&mut clip, &stacking_relative_border_box);
|
||||||
if !clip.might_intersect_rect(&stacking_relative_border_box) {
|
if !clip.might_intersect_rect(&stacking_relative_border_box) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1277,7 +1270,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
base_flow: &BaseFlow,
|
base_flow: &BaseFlow,
|
||||||
scroll_policy: ScrollPolicy,
|
scroll_policy: ScrollPolicy,
|
||||||
mode: StackingContextCreationMode)
|
mode: StackingContextCreationMode)
|
||||||
-> StackingContext {
|
-> Box<StackingContext> {
|
||||||
let border_box = match mode {
|
let border_box = match mode {
|
||||||
StackingContextCreationMode::InnerScrollWrapper => {
|
StackingContextCreationMode::InnerScrollWrapper => {
|
||||||
Rect::new(Point2D::zero(), base_flow.overflow.scroll.size)
|
Rect::new(Point2D::zero(), base_flow.overflow.scroll.size)
|
||||||
|
@ -1411,7 +1404,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
_ => StackingContextType::Real,
|
_ => StackingContextType::Real,
|
||||||
};
|
};
|
||||||
|
|
||||||
StackingContext::new(id,
|
Box::new(StackingContext::new(id,
|
||||||
context_type,
|
context_type,
|
||||||
&border_box,
|
&border_box,
|
||||||
&overflow,
|
&overflow,
|
||||||
|
@ -1422,22 +1415,20 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
perspective,
|
perspective,
|
||||||
establishes_3d_context,
|
establishes_3d_context,
|
||||||
scrolls_overflow_area,
|
scrolls_overflow_area,
|
||||||
layer_info)
|
layer_info))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clipping_region_for_children(&self,
|
fn adjust_clipping_region_for_children(&self,
|
||||||
current_clip: &ClippingRegion,
|
current_clip: &mut ClippingRegion,
|
||||||
stacking_relative_border_box: &Rect<Au>,
|
stacking_relative_border_box: &Rect<Au>,
|
||||||
is_absolutely_positioned: bool)
|
is_absolutely_positioned: bool) {
|
||||||
-> ClippingRegion {
|
|
||||||
// Don't clip if we're text.
|
// Don't clip if we're text.
|
||||||
if self.is_scanned_text_fragment() {
|
if self.is_scanned_text_fragment() {
|
||||||
return (*current_clip).clone()
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Account for style-specified `clip`.
|
// Account for style-specified `clip`.
|
||||||
let mut current_clip = self.calculate_style_specified_clip(current_clip,
|
self.adjust_clip_for_style(current_clip, stacking_relative_border_box);
|
||||||
stacking_relative_border_box);
|
|
||||||
|
|
||||||
// Clip according to the values of `overflow-x` and `overflow-y`.
|
// Clip according to the values of `overflow-x` and `overflow-y`.
|
||||||
//
|
//
|
||||||
|
@ -1453,7 +1444,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
let max_x = cmp::min(bounds.max_x(), stacking_relative_border_box.max_x());
|
let max_x = cmp::min(bounds.max_x(), stacking_relative_border_box.max_x());
|
||||||
bounds.origin.x = cmp::max(bounds.origin.x, stacking_relative_border_box.origin.x);
|
bounds.origin.x = cmp::max(bounds.origin.x, stacking_relative_border_box.origin.x);
|
||||||
bounds.size.width = max_x - bounds.origin.x;
|
bounds.size.width = max_x - bounds.origin.x;
|
||||||
current_clip = current_clip.intersect_rect(&bounds)
|
current_clip.intersect_rect(&bounds)
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -1465,12 +1456,10 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
let max_y = cmp::min(bounds.max_y(), stacking_relative_border_box.max_y());
|
let max_y = cmp::min(bounds.max_y(), stacking_relative_border_box.max_y());
|
||||||
bounds.origin.y = cmp::max(bounds.origin.y, stacking_relative_border_box.origin.y);
|
bounds.origin.y = cmp::max(bounds.origin.y, stacking_relative_border_box.origin.y);
|
||||||
bounds.size.height = max_y - bounds.origin.y;
|
bounds.size.height = max_y - bounds.origin.y;
|
||||||
current_clip = current_clip.intersect_rect(&bounds)
|
current_clip.intersect_rect(&bounds)
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
current_clip
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_display_list_for_text_fragment(&self,
|
fn build_display_list_for_text_fragment(&self,
|
||||||
|
@ -1600,7 +1589,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
pub trait BlockFlowDisplayListBuilding {
|
pub trait BlockFlowDisplayListBuilding {
|
||||||
fn collect_stacking_contexts_for_block(&mut self,
|
fn collect_stacking_contexts_for_block(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
contexts: &mut Vec<StackingContext>)
|
contexts: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId;
|
-> StackingContextId;
|
||||||
fn build_display_list_for_block(&mut self,
|
fn build_display_list_for_block(&mut self,
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
|
@ -1610,10 +1599,10 @@ pub trait BlockFlowDisplayListBuilding {
|
||||||
impl BlockFlowDisplayListBuilding for BlockFlow {
|
impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
fn collect_stacking_contexts_for_block(&mut self,
|
fn collect_stacking_contexts_for_block(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
contexts: &mut Vec<StackingContext>)
|
contexts: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId {
|
-> StackingContextId {
|
||||||
if !self.fragment.establishes_stacking_context() &&
|
let block_stacking_context_type = self.block_stacking_context_type();
|
||||||
!self.establishes_pseudo_stacking_context() {
|
if block_stacking_context_type == BlockStackingContextType::NonstackingContext {
|
||||||
self.base.stacking_context_id = parent_id;
|
self.base.stacking_context_id = parent_id;
|
||||||
self.base.collect_stacking_contexts_for_children(parent_id, contexts);
|
self.base.collect_stacking_contexts_for_children(parent_id, contexts);
|
||||||
return parent_id;
|
return parent_id;
|
||||||
|
@ -1625,8 +1614,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
self.base.stacking_context_id = stacking_context_id;
|
self.base.stacking_context_id = stacking_context_id;
|
||||||
|
|
||||||
let inner_stacking_context_id = if self.has_scrolling_overflow() {
|
let inner_stacking_context_id = if self.has_scrolling_overflow() {
|
||||||
StackingContextId::new_of_type(self.base.flow_id(),
|
StackingContextId::new_of_type(self.base.flow_id(), self.fragment.fragment_type())
|
||||||
self.fragment.fragment_type())
|
|
||||||
} else {
|
} else {
|
||||||
stacking_context_id
|
stacking_context_id
|
||||||
};
|
};
|
||||||
|
@ -1635,7 +1623,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
self.base.collect_stacking_contexts_for_children(inner_stacking_context_id,
|
self.base.collect_stacking_contexts_for_children(inner_stacking_context_id,
|
||||||
&mut child_contexts);
|
&mut child_contexts);
|
||||||
|
|
||||||
if self.establishes_pseudo_stacking_context() {
|
if block_stacking_context_type == BlockStackingContextType::PseudoStackingContext {
|
||||||
let creation_mode = if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) ||
|
let creation_mode = if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) ||
|
||||||
self.fragment.style.get_box().position != position::T::static_ {
|
self.fragment.style.get_box().position != position::T::static_ {
|
||||||
StackingContextCreationMode::PseudoPositioned
|
StackingContextCreationMode::PseudoPositioned
|
||||||
|
@ -1644,18 +1632,24 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
StackingContextCreationMode::PseudoFloat
|
StackingContextCreationMode::PseudoFloat
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut stacking_context =
|
let stacking_context_index = contexts.len();
|
||||||
self.fragment.create_stacking_context(stacking_context_id,
|
contexts.push(self.fragment.create_stacking_context(stacking_context_id,
|
||||||
&self.base,
|
&self.base,
|
||||||
ScrollPolicy::Scrollable,
|
ScrollPolicy::Scrollable,
|
||||||
creation_mode);
|
creation_mode));
|
||||||
let (mut floating, mut positioned) = child_contexts.into_iter().partition(|context| {
|
|
||||||
context.context_type == StackingContextType::PseudoFloat
|
|
||||||
});
|
|
||||||
|
|
||||||
stacking_context.children.append(&mut floating);
|
let mut floating = vec![];
|
||||||
contexts.push(stacking_context);
|
for child_context in child_contexts.into_iter() {
|
||||||
contexts.append(&mut positioned);
|
if child_context.context_type == StackingContextType::PseudoFloat {
|
||||||
|
// Floating.
|
||||||
|
floating.push(child_context)
|
||||||
|
} else {
|
||||||
|
// Positioned.
|
||||||
|
contexts.push(child_context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contexts[stacking_context_index].children = floating;
|
||||||
return stacking_context_id;
|
return stacking_context_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1671,7 +1665,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
&self.base,
|
&self.base,
|
||||||
scroll_policy,
|
scroll_policy,
|
||||||
StackingContextCreationMode::InnerScrollWrapper);
|
StackingContextCreationMode::InnerScrollWrapper);
|
||||||
inner_stacking_context.children.append(&mut child_contexts);
|
inner_stacking_context.children = child_contexts;
|
||||||
|
|
||||||
let mut outer_stacking_context = self.fragment.create_stacking_context(
|
let mut outer_stacking_context = self.fragment.create_stacking_context(
|
||||||
stacking_context_id,
|
stacking_context_id,
|
||||||
|
@ -1686,7 +1680,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
&self.base,
|
&self.base,
|
||||||
scroll_policy,
|
scroll_policy,
|
||||||
StackingContextCreationMode::Normal);
|
StackingContextCreationMode::Normal);
|
||||||
stacking_context.children.append(&mut child_contexts);
|
stacking_context.children = child_contexts;
|
||||||
stacking_context
|
stacking_context
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1697,10 +1691,11 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
fn build_display_list_for_block(&mut self,
|
fn build_display_list_for_block(&mut self,
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
border_painting_mode: BorderPaintingMode) {
|
border_painting_mode: BorderPaintingMode) {
|
||||||
|
let establishes_stacking_context = self.fragment.establishes_stacking_context();
|
||||||
let background_border_section = if self.base.flags.is_float() {
|
let background_border_section = if self.base.flags.is_float() {
|
||||||
DisplayListSection::BackgroundAndBorders
|
DisplayListSection::BackgroundAndBorders
|
||||||
} else if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
} else if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||||
if self.fragment.establishes_stacking_context() {
|
if establishes_stacking_context {
|
||||||
DisplayListSection::BackgroundAndBorders
|
DisplayListSection::BackgroundAndBorders
|
||||||
} else {
|
} else {
|
||||||
DisplayListSection::BlockBackgroundsAndBorders
|
DisplayListSection::BlockBackgroundsAndBorders
|
||||||
|
@ -1710,10 +1705,14 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add the box that starts the block context.
|
// Add the box that starts the block context.
|
||||||
let clip = if self.fragment.establishes_stacking_context() {
|
let translated_clip = if establishes_stacking_context {
|
||||||
self.base.clip.translate(&-self.base.stacking_relative_position)
|
Some(self.base.clip.translate(&-self.base.stacking_relative_position))
|
||||||
} else {
|
} else {
|
||||||
self.base.clip.clone()
|
None
|
||||||
|
};
|
||||||
|
let clip = match translated_clip {
|
||||||
|
Some(ref translated_clip) => translated_clip,
|
||||||
|
None => &self.base.clip,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.fragment
|
self.fragment
|
||||||
|
@ -1727,14 +1726,9 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
.relative_containing_block_mode,
|
.relative_containing_block_mode,
|
||||||
border_painting_mode,
|
border_painting_mode,
|
||||||
background_border_section,
|
background_border_section,
|
||||||
&clip,
|
clip,
|
||||||
&self.base.stacking_relative_position_of_display_port);
|
&self.base.stacking_relative_position_of_display_port);
|
||||||
|
|
||||||
// Add children.
|
|
||||||
for kid in self.base.children.iter_mut() {
|
|
||||||
state.append_from(&mut flow::mut_base(kid).display_list_building_result);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.base.build_display_items_for_debugging_tint(state, self.fragment.node);
|
self.base.build_display_items_for_debugging_tint(state, self.fragment.node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1742,7 +1736,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
pub trait InlineFlowDisplayListBuilding {
|
pub trait InlineFlowDisplayListBuilding {
|
||||||
fn collect_stacking_contexts_for_inline(&mut self,
|
fn collect_stacking_contexts_for_inline(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
contexts: &mut Vec<StackingContext>)
|
contexts: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId;
|
-> StackingContextId;
|
||||||
fn build_display_list_for_inline_fragment_at_index(&mut self,
|
fn build_display_list_for_inline_fragment_at_index(&mut self,
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
|
@ -1753,7 +1747,7 @@ pub trait InlineFlowDisplayListBuilding {
|
||||||
impl InlineFlowDisplayListBuilding for InlineFlow {
|
impl InlineFlowDisplayListBuilding for InlineFlow {
|
||||||
fn collect_stacking_contexts_for_inline(&mut self,
|
fn collect_stacking_contexts_for_inline(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
contexts: &mut Vec<StackingContext>)
|
contexts: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId {
|
-> StackingContextId {
|
||||||
self.base.stacking_context_id = parent_id;
|
self.base.stacking_context_id = parent_id;
|
||||||
|
|
||||||
|
@ -1799,22 +1793,6 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
|
||||||
DisplayListSection::Content,
|
DisplayListSection::Content,
|
||||||
&self.base.clip,
|
&self.base.clip,
|
||||||
&self.base.stacking_relative_position_of_display_port);
|
&self.base.stacking_relative_position_of_display_port);
|
||||||
|
|
||||||
match fragment.specific {
|
|
||||||
SpecificFragmentInfo::InlineBlock(ref mut block_flow) => {
|
|
||||||
let block_flow = flow_ref::deref_mut(&mut block_flow.flow_ref);
|
|
||||||
state.append_from(&mut flow::mut_base(block_flow).display_list_building_result)
|
|
||||||
}
|
|
||||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut block_flow) => {
|
|
||||||
let block_flow = flow_ref::deref_mut(&mut block_flow.flow_ref);
|
|
||||||
state.append_from(&mut flow::mut_base(block_flow).display_list_building_result)
|
|
||||||
}
|
|
||||||
SpecificFragmentInfo::InlineAbsolute(ref mut block_flow) => {
|
|
||||||
let block_flow = flow_ref::deref_mut(&mut block_flow.flow_ref);
|
|
||||||
state.append_from(&mut flow::mut_base(block_flow).display_list_building_result)
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_display_list_for_inline(&mut self, state: &mut DisplayListBuildState) {
|
fn build_display_list_for_inline(&mut self, state: &mut DisplayListBuildState) {
|
||||||
|
@ -1847,10 +1825,6 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
|
||||||
self.base.build_display_items_for_debugging_tint(state,
|
self.base.build_display_items_for_debugging_tint(state,
|
||||||
self.fragments.fragments[0].node);
|
self.fragments.fragments[0].node);
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts::get().validate_display_list_geometry {
|
|
||||||
self.base.validate_display_list_geometry();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@ use style::logical_geometry::LogicalSize;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::properties::style_structs;
|
use style::properties::style_structs;
|
||||||
use style::values::computed::LengthOrPercentageOrAuto;
|
use style::values::computed::LengthOrPercentageOrAuto;
|
||||||
use util::opts;
|
|
||||||
|
|
||||||
// A mode describes which logical axis a flex axis is parallel with.
|
// A mode describes which logical axis a flex axis is parallel with.
|
||||||
// The logical axises are inline and block, the flex axises are main and cross.
|
// The logical axises are inline and block, the flex axises are main and cross.
|
||||||
|
@ -422,15 +421,11 @@ impl Flow for FlexFlow {
|
||||||
|
|
||||||
fn build_display_list(&mut self, state: &mut DisplayListBuildState) {
|
fn build_display_list(&mut self, state: &mut DisplayListBuildState) {
|
||||||
self.build_display_list_for_flex(state);
|
self.build_display_list_for_flex(state);
|
||||||
|
|
||||||
if opts::get().validate_display_list_geometry {
|
|
||||||
self.block_flow.base.validate_display_list_geometry();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_stacking_contexts(&mut self,
|
fn collect_stacking_contexts(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
contexts: &mut Vec<StackingContext>)
|
contexts: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId {
|
-> StackingContextId {
|
||||||
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ use floats::Floats;
|
||||||
use flow_list::{FlowList, FlowListIterator, MutFlowListIterator};
|
use flow_list::{FlowList, FlowListIterator, MutFlowListIterator};
|
||||||
use flow_ref::{self, FlowRef, WeakFlowRef};
|
use flow_ref::{self, FlowRef, WeakFlowRef};
|
||||||
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow, SpecificFragmentInfo};
|
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow, SpecificFragmentInfo};
|
||||||
use gfx::display_list::{ClippingRegion, DisplayListEntry, StackingContext, StackingContextId};
|
use gfx::display_list::{ClippingRegion, StackingContext, StackingContextId};
|
||||||
use gfx_traits::{LayerId, LayerType};
|
use gfx_traits::{LayerId, LayerType};
|
||||||
use incremental::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RestyleDamage};
|
use incremental::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RestyleDamage};
|
||||||
use inline::InlineFlow;
|
use inline::InlineFlow;
|
||||||
|
@ -224,7 +224,7 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static {
|
||||||
|
|
||||||
fn collect_stacking_contexts(&mut self,
|
fn collect_stacking_contexts(&mut self,
|
||||||
_parent_id: StackingContextId,
|
_parent_id: StackingContextId,
|
||||||
_: &mut Vec<StackingContext>)
|
_: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId;
|
-> StackingContextId;
|
||||||
|
|
||||||
/// If this is a float, places it. The default implementation does nothing.
|
/// If this is a float, places it. The default implementation does nothing.
|
||||||
|
@ -957,9 +957,6 @@ pub struct BaseFlow {
|
||||||
/// per-stacking-context.
|
/// per-stacking-context.
|
||||||
pub stacking_relative_position_of_display_port: Rect<Au>,
|
pub stacking_relative_position_of_display_port: Rect<Au>,
|
||||||
|
|
||||||
/// The results of display list building for this flow.
|
|
||||||
pub display_list_building_result: Option<Vec<DisplayListEntry>>,
|
|
||||||
|
|
||||||
/// The writing mode for this flow.
|
/// The writing mode for this flow.
|
||||||
pub writing_mode: WritingMode,
|
pub writing_mode: WritingMode,
|
||||||
|
|
||||||
|
@ -1129,7 +1126,6 @@ impl BaseFlow {
|
||||||
block_container_writing_mode: writing_mode,
|
block_container_writing_mode: writing_mode,
|
||||||
block_container_explicit_block_size: None,
|
block_container_explicit_block_size: None,
|
||||||
absolute_cb: ContainingBlockLink::new(),
|
absolute_cb: ContainingBlockLink::new(),
|
||||||
display_list_building_result: None,
|
|
||||||
early_absolute_position_info: EarlyAbsolutePositionInfo::new(writing_mode),
|
early_absolute_position_info: EarlyAbsolutePositionInfo::new(writing_mode),
|
||||||
late_absolute_position_info: LateAbsolutePositionInfo::new(),
|
late_absolute_position_info: LateAbsolutePositionInfo::new(),
|
||||||
clip: ClippingRegion::max(),
|
clip: ClippingRegion::max(),
|
||||||
|
@ -1147,8 +1143,6 @@ impl BaseFlow {
|
||||||
children: children,
|
children: children,
|
||||||
restyle_damage: self.restyle_damage | REPAINT | REFLOW_OUT_OF_FLOW | REFLOW,
|
restyle_damage: self.restyle_damage | REPAINT | REFLOW_OUT_OF_FLOW | REFLOW,
|
||||||
parallel: FlowParallelInfo::new(),
|
parallel: FlowParallelInfo::new(),
|
||||||
display_list_building_result: None,
|
|
||||||
|
|
||||||
floats: self.floats.clone(),
|
floats: self.floats.clone(),
|
||||||
abs_descendants: self.abs_descendants.clone(),
|
abs_descendants: self.abs_descendants.clone(),
|
||||||
absolute_cb: self.absolute_cb.clone(),
|
absolute_cb: self.absolute_cb.clone(),
|
||||||
|
@ -1167,43 +1161,13 @@ impl BaseFlow {
|
||||||
p as usize
|
p as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensures that all display list items generated by this flow are within the flow's overflow
|
|
||||||
/// rect. This should only be used for debugging.
|
|
||||||
pub fn validate_display_list_geometry(&self) {
|
|
||||||
// FIXME(pcwalton, #2795): Get the real container size.
|
|
||||||
let container_size = Size2D::zero();
|
|
||||||
let position_with_overflow = self.position
|
|
||||||
.to_physical(self.writing_mode, container_size)
|
|
||||||
.union(&self.overflow.paint);
|
|
||||||
let bounds = Rect::new(self.stacking_relative_position, position_with_overflow.size);
|
|
||||||
|
|
||||||
let items = match self.display_list_building_result {
|
|
||||||
Some(ref items) => items,
|
|
||||||
None => return,
|
|
||||||
};
|
|
||||||
|
|
||||||
for item in items.iter() {
|
|
||||||
let base_item = item.item.base();
|
|
||||||
let paint_bounds = base_item.clip.clone().intersect_rect(&base_item.bounds);
|
|
||||||
if !paint_bounds.might_be_nonempty() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if bounds.union(&paint_bounds.bounding_rect()) != bounds {
|
|
||||||
error!("DisplayList item {:?} outside of Flow overflow ({:?})",
|
|
||||||
item.item,
|
|
||||||
paint_bounds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn flow_id(&self) -> usize {
|
pub fn flow_id(&self) -> usize {
|
||||||
return self as *const BaseFlow as usize;
|
return self as *const BaseFlow as usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn collect_stacking_contexts_for_children(&mut self,
|
pub fn collect_stacking_contexts_for_children(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
contexts: &mut Vec<StackingContext>) {
|
contexts: &mut Vec<Box<StackingContext>>) {
|
||||||
for kid in self.children.iter_mut() {
|
for kid in self.children.iter_mut() {
|
||||||
kid.collect_stacking_contexts(parent_id, contexts);
|
kid.collect_stacking_contexts(parent_id, contexts);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1680,7 +1680,8 @@ impl Flow for InlineFlow {
|
||||||
CoordinateSystem::Parent);
|
CoordinateSystem::Parent);
|
||||||
let stacking_relative_content_box =
|
let stacking_relative_content_box =
|
||||||
fragment.stacking_relative_content_box(&stacking_relative_border_box);
|
fragment.stacking_relative_content_box(&stacking_relative_border_box);
|
||||||
let clip = fragment.clipping_region_for_children(&self.base.clip,
|
let mut clip = self.base.clip.clone();
|
||||||
|
fragment.adjust_clipping_region_for_children(&mut clip,
|
||||||
&stacking_relative_border_box,
|
&stacking_relative_border_box,
|
||||||
false);
|
false);
|
||||||
let is_positioned = fragment.is_positioned();
|
let is_positioned = fragment.is_positioned();
|
||||||
|
@ -1750,7 +1751,7 @@ impl Flow for InlineFlow {
|
||||||
|
|
||||||
fn collect_stacking_contexts(&mut self,
|
fn collect_stacking_contexts(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
contexts: &mut Vec<StackingContext>)
|
contexts: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId {
|
-> StackingContextId {
|
||||||
self.collect_stacking_contexts_for_inline(parent_id, contexts)
|
self.collect_stacking_contexts_for_inline(parent_id, contexts)
|
||||||
}
|
}
|
||||||
|
|
|
@ -875,6 +875,7 @@ impl LayoutThread {
|
||||||
false,
|
false,
|
||||||
None);
|
None);
|
||||||
|
|
||||||
|
let display_list_entries =
|
||||||
sequential::build_display_list_for_subtree(layout_root,
|
sequential::build_display_list_for_subtree(layout_root,
|
||||||
&mut root_stacking_context,
|
&mut root_stacking_context,
|
||||||
shared_layout_context);
|
shared_layout_context);
|
||||||
|
@ -900,11 +901,9 @@ impl LayoutThread {
|
||||||
ScrollPolicy::Scrollable,
|
ScrollPolicy::Scrollable,
|
||||||
None,
|
None,
|
||||||
root_background_color));
|
root_background_color));
|
||||||
let display_list = DisplayList::new(
|
|
||||||
root_stacking_context,
|
|
||||||
&mut flow::mut_base(flow_ref::deref_mut(layout_root))
|
|
||||||
.display_list_building_result);
|
|
||||||
|
|
||||||
|
let display_list = DisplayList::new(root_stacking_context,
|
||||||
|
&mut Some(display_list_entries));
|
||||||
if opts::get().dump_display_list {
|
if opts::get().dump_display_list {
|
||||||
display_list.print();
|
display_list.print();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ use style::computed_values::{list_style_type, position};
|
||||||
use style::logical_geometry::LogicalSize;
|
use style::logical_geometry::LogicalSize;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use text;
|
use text;
|
||||||
use util::opts;
|
|
||||||
|
|
||||||
/// A block with the CSS `display` property equal to `list-item`.
|
/// A block with the CSS `display` property equal to `list-item`.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -144,14 +143,11 @@ impl Flow for ListItemFlow {
|
||||||
|
|
||||||
fn build_display_list(&mut self, state: &mut DisplayListBuildState) {
|
fn build_display_list(&mut self, state: &mut DisplayListBuildState) {
|
||||||
self.build_display_list_for_list_item(state);
|
self.build_display_list_for_list_item(state);
|
||||||
if opts::get().validate_display_list_geometry {
|
|
||||||
self.block_flow.base.validate_display_list_geometry();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_stacking_contexts(&mut self,
|
fn collect_stacking_contexts(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
contexts: &mut Vec<StackingContext>)
|
contexts: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId {
|
-> StackingContextId {
|
||||||
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,7 +186,7 @@ impl Flow for MulticolFlow {
|
||||||
|
|
||||||
fn collect_stacking_contexts(&mut self,
|
fn collect_stacking_contexts(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
contexts: &mut Vec<StackingContext>)
|
contexts: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId {
|
-> StackingContextId {
|
||||||
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,7 @@ impl Flow for MulticolColumnFlow {
|
||||||
|
|
||||||
fn collect_stacking_contexts(&mut self,
|
fn collect_stacking_contexts(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
contexts: &mut Vec<StackingContext>)
|
contexts: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId {
|
-> StackingContextId {
|
||||||
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,14 @@
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use context::{LayoutContext, SharedLayoutContext};
|
use context::{LayoutContext, SharedLayoutContext};
|
||||||
|
use display_list_builder::DisplayListBuildState;
|
||||||
use euclid::point::Point2D;
|
use euclid::point::Point2D;
|
||||||
use flow::{PostorderFlowTraversal, PreorderFlowTraversal};
|
use flow::{PostorderFlowTraversal, PreorderFlowTraversal};
|
||||||
use flow::{self, Flow, ImmutableFlowUtils, InorderFlowTraversal, MutableFlowUtils};
|
use flow::{self, Flow, ImmutableFlowUtils, InorderFlowTraversal, MutableFlowUtils};
|
||||||
use flow_ref::{self, FlowRef};
|
use flow_ref::{self, FlowRef};
|
||||||
use fragment::FragmentBorderBoxIterator;
|
use fragment::FragmentBorderBoxIterator;
|
||||||
use generated_content::ResolveGeneratedContent;
|
use generated_content::ResolveGeneratedContent;
|
||||||
use gfx::display_list::StackingContext;
|
use gfx::display_list::{DisplayListEntry, StackingContext};
|
||||||
use style::dom::TNode;
|
use style::dom::TNode;
|
||||||
use style::traversal::DomTraversalContext;
|
use style::traversal::DomTraversalContext;
|
||||||
use traversal::{AssignBSizesAndStoreOverflow, AssignISizes};
|
use traversal::{AssignBSizesAndStoreOverflow, AssignISizes};
|
||||||
|
@ -77,13 +78,19 @@ pub fn traverse_flow_tree_preorder(root: &mut FlowRef,
|
||||||
|
|
||||||
pub fn build_display_list_for_subtree(root: &mut FlowRef,
|
pub fn build_display_list_for_subtree(root: &mut FlowRef,
|
||||||
root_stacking_context: &mut StackingContext,
|
root_stacking_context: &mut StackingContext,
|
||||||
shared_layout_context: &SharedLayoutContext) {
|
shared_layout_context: &SharedLayoutContext)
|
||||||
|
-> Vec<DisplayListEntry> {
|
||||||
let flow_root = flow_ref::deref_mut(root);
|
let flow_root = flow_ref::deref_mut(root);
|
||||||
let layout_context = LayoutContext::new(shared_layout_context);
|
let layout_context = LayoutContext::new(shared_layout_context);
|
||||||
flow_root.traverse_preorder(&ComputeAbsolutePositions { layout_context: &layout_context });
|
flow_root.traverse_preorder(&ComputeAbsolutePositions { layout_context: &layout_context });
|
||||||
flow_root.collect_stacking_contexts(root_stacking_context.id,
|
flow_root.collect_stacking_contexts(root_stacking_context.id,
|
||||||
&mut root_stacking_context.children);
|
&mut root_stacking_context.children);
|
||||||
flow_root.traverse_postorder(&BuildDisplayList { layout_context: &layout_context });
|
let mut build_display_list = BuildDisplayList {
|
||||||
|
state: DisplayListBuildState::new(&layout_context,
|
||||||
|
flow::base(&**root).stacking_context_id),
|
||||||
|
};
|
||||||
|
build_display_list.traverse(&mut *flow_root);
|
||||||
|
build_display_list.state.items
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iterate_through_flow_tree_fragment_border_boxes(root: &mut FlowRef,
|
pub fn iterate_through_flow_tree_fragment_border_boxes(root: &mut FlowRef,
|
||||||
|
|
|
@ -467,7 +467,7 @@ impl Flow for TableFlow {
|
||||||
|
|
||||||
fn collect_stacking_contexts(&mut self,
|
fn collect_stacking_contexts(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
contexts: &mut Vec<StackingContext>)
|
contexts: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId {
|
-> StackingContextId {
|
||||||
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ impl Flow for TableCaptionFlow {
|
||||||
|
|
||||||
fn collect_stacking_contexts(&mut self,
|
fn collect_stacking_contexts(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
contexts: &mut Vec<StackingContext>)
|
contexts: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId {
|
-> StackingContextId {
|
||||||
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,7 +193,7 @@ impl Flow for TableCellFlow {
|
||||||
|
|
||||||
fn collect_stacking_contexts(&mut self,
|
fn collect_stacking_contexts(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
contexts: &mut Vec<StackingContext>)
|
contexts: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId {
|
-> StackingContextId {
|
||||||
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ impl Flow for TableColGroupFlow {
|
||||||
|
|
||||||
fn collect_stacking_contexts(&mut self,
|
fn collect_stacking_contexts(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
_: &mut Vec<StackingContext>)
|
_: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId {
|
-> StackingContextId {
|
||||||
parent_id
|
parent_id
|
||||||
}
|
}
|
||||||
|
|
|
@ -435,7 +435,7 @@ impl Flow for TableRowFlow {
|
||||||
|
|
||||||
fn collect_stacking_contexts(&mut self,
|
fn collect_stacking_contexts(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
contexts: &mut Vec<StackingContext>)
|
contexts: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId {
|
-> StackingContextId {
|
||||||
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,7 +212,7 @@ impl Flow for TableRowGroupFlow {
|
||||||
|
|
||||||
fn collect_stacking_contexts(&mut self,
|
fn collect_stacking_contexts(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
contexts: &mut Vec<StackingContext>)
|
contexts: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId {
|
-> StackingContextId {
|
||||||
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
||||||
}
|
}
|
||||||
|
|
|
@ -451,7 +451,7 @@ impl Flow for TableWrapperFlow {
|
||||||
|
|
||||||
fn collect_stacking_contexts(&mut self,
|
fn collect_stacking_contexts(&mut self,
|
||||||
parent_id: StackingContextId,
|
parent_id: StackingContextId,
|
||||||
contexts: &mut Vec<StackingContext>)
|
contexts: &mut Vec<Box<StackingContext>>)
|
||||||
-> StackingContextId {
|
-> StackingContextId {
|
||||||
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
self.block_flow.collect_stacking_contexts(parent_id, contexts)
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,23 +215,27 @@ impl<'a> PreorderFlowTraversal for ComputeAbsolutePositions<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct BuildDisplayList<'a> {
|
pub struct BuildDisplayList<'a> {
|
||||||
pub layout_context: &'a LayoutContext<'a>,
|
pub state: DisplayListBuildState<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PostorderFlowTraversal for BuildDisplayList<'a> {
|
impl<'a> BuildDisplayList<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn process(&self, flow: &mut Flow) {
|
pub fn traverse(&mut self, flow: &mut Flow) {
|
||||||
let mut state = DisplayListBuildState::new(
|
if self.should_process() {
|
||||||
self.layout_context, flow::base(flow).stacking_context_id);
|
self.state.push_stacking_context_id(flow::base(flow).stacking_context_id);
|
||||||
flow.build_display_list(&mut state);
|
flow.build_display_list(&mut self.state);
|
||||||
flow::mut_base(flow).display_list_building_result = Some(state.items);
|
|
||||||
flow::mut_base(flow).restyle_damage.remove(REPAINT);
|
flow::mut_base(flow).restyle_damage.remove(REPAINT);
|
||||||
|
self.state.pop_stacking_context_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
for kid in flow::child_iter(flow) {
|
||||||
|
self.traverse(kid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn should_process(&self, _: &mut Flow) -> bool {
|
fn should_process(&self) -> bool {
|
||||||
self.layout_context.shared_context().goal == ReflowGoal::ForDisplay
|
self.state.layout_context.shared_context().goal == ReflowGoal::ForDisplay
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,9 +163,6 @@ pub struct Opts {
|
||||||
/// Emits notifications when there is a relayout.
|
/// Emits notifications when there is a relayout.
|
||||||
pub relayout_event: bool,
|
pub relayout_event: bool,
|
||||||
|
|
||||||
/// Whether to show an error when display list geometry escapes flow overflow regions.
|
|
||||||
pub validate_display_list_geometry: bool,
|
|
||||||
|
|
||||||
/// Whether Style Sharing Cache is used
|
/// Whether Style Sharing Cache is used
|
||||||
pub disable_share_style_cache: bool,
|
pub disable_share_style_cache: bool,
|
||||||
|
|
||||||
|
@ -254,9 +251,6 @@ pub struct DebugOptions {
|
||||||
/// Write layout trace to an external file for debugging.
|
/// Write layout trace to an external file for debugging.
|
||||||
pub trace_layout: bool,
|
pub trace_layout: bool,
|
||||||
|
|
||||||
/// Display an error when display list geometry escapes overflow region.
|
|
||||||
pub validate_display_list_geometry: bool,
|
|
||||||
|
|
||||||
/// Disable the style sharing cache.
|
/// Disable the style sharing cache.
|
||||||
pub disable_share_style_cache: bool,
|
pub disable_share_style_cache: bool,
|
||||||
|
|
||||||
|
@ -308,7 +302,6 @@ impl DebugOptions {
|
||||||
"show-parallel-layout" => debug_options.show_parallel_layout = true,
|
"show-parallel-layout" => debug_options.show_parallel_layout = true,
|
||||||
"paint-flashing" => debug_options.paint_flashing = true,
|
"paint-flashing" => debug_options.paint_flashing = true,
|
||||||
"trace-layout" => debug_options.trace_layout = true,
|
"trace-layout" => debug_options.trace_layout = true,
|
||||||
"validate-display-list-geometry" => debug_options.validate_display_list_geometry = true,
|
|
||||||
"disable-share-style-cache" => debug_options.disable_share_style_cache = true,
|
"disable-share-style-cache" => debug_options.disable_share_style_cache = true,
|
||||||
"convert-mouse-to-touch" => debug_options.convert_mouse_to_touch = true,
|
"convert-mouse-to-touch" => debug_options.convert_mouse_to_touch = true,
|
||||||
"replace-surrogates" => debug_options.replace_surrogates = true,
|
"replace-surrogates" => debug_options.replace_surrogates = true,
|
||||||
|
@ -351,8 +344,6 @@ pub fn print_debug_usage(app: &str) -> ! {
|
||||||
print_option("show-parallel-layout", "Mark which thread laid each flow out with colors.");
|
print_option("show-parallel-layout", "Mark which thread laid each flow out with colors.");
|
||||||
print_option("paint-flashing", "Overlay repainted areas with a random color.");
|
print_option("paint-flashing", "Overlay repainted areas with a random color.");
|
||||||
print_option("trace-layout", "Write layout trace to an external file for debugging.");
|
print_option("trace-layout", "Write layout trace to an external file for debugging.");
|
||||||
print_option("validate-display-list-geometry",
|
|
||||||
"Display an error when display list geometry escapes overflow region.");
|
|
||||||
print_option("disable-share-style-cache",
|
print_option("disable-share-style-cache",
|
||||||
"Disable the style sharing cache.");
|
"Disable the style sharing cache.");
|
||||||
print_option("parallel-display-list-building", "Build display lists in parallel.");
|
print_option("parallel-display-list-building", "Build display lists in parallel.");
|
||||||
|
@ -486,7 +477,6 @@ pub fn default_opts() -> Opts {
|
||||||
dump_display_list_optimized: false,
|
dump_display_list_optimized: false,
|
||||||
dump_layer_tree: false,
|
dump_layer_tree: false,
|
||||||
relayout_event: false,
|
relayout_event: false,
|
||||||
validate_display_list_geometry: false,
|
|
||||||
profile_script_events: false,
|
profile_script_events: false,
|
||||||
profile_heartbeats: false,
|
profile_heartbeats: false,
|
||||||
disable_share_style_cache: false,
|
disable_share_style_cache: false,
|
||||||
|
@ -727,7 +717,6 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
|
||||||
dump_display_list_optimized: debug_options.dump_display_list_optimized,
|
dump_display_list_optimized: debug_options.dump_display_list_optimized,
|
||||||
dump_layer_tree: debug_options.dump_layer_tree,
|
dump_layer_tree: debug_options.dump_layer_tree,
|
||||||
relayout_event: debug_options.relayout_event,
|
relayout_event: debug_options.relayout_event,
|
||||||
validate_display_list_geometry: debug_options.validate_display_list_geometry,
|
|
||||||
disable_share_style_cache: debug_options.disable_share_style_cache,
|
disable_share_style_cache: debug_options.disable_share_style_cache,
|
||||||
convert_mouse_to_touch: debug_options.convert_mouse_to_touch,
|
convert_mouse_to_touch: debug_options.convert_mouse_to_touch,
|
||||||
exit_after_load: opt_match.opt_present("x"),
|
exit_after_load: opt_match.opt_present("x"),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue