mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Auto merge of #13346 - pcwalton:cnn, r=notriddle
layout: Make some major improvements to incremental layout to improve CNN. CNN is still too slow to be usable, but this is a partial solution. r? @notriddle (feel free to reassign if you like) <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13346) <!-- Reviewable:end -->
This commit is contained in:
commit
cbe5458272
7 changed files with 284 additions and 199 deletions
|
@ -51,6 +51,7 @@ use model::{self, IntrinsicISizes, MarginCollapseInfo};
|
||||||
use model::{CollapsibleMargins, MaybeAuto, specified, specified_or_none};
|
use model::{CollapsibleMargins, MaybeAuto, specified, specified_or_none};
|
||||||
use rustc_serialize::{Encodable, Encoder};
|
use rustc_serialize::{Encodable, Encoder};
|
||||||
use script_layout_interface::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW};
|
use script_layout_interface::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW};
|
||||||
|
use script_layout_interface::restyle_damage::REPOSITION;
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -1842,6 +1843,8 @@ impl Flow for BlockFlow {
|
||||||
self.fragment.assign_replaced_block_size_if_necessary(containing_block_block_size);
|
self.fragment.assign_replaced_block_size_if_necessary(containing_block_block_size);
|
||||||
if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||||
self.base.position.size.block = self.fragment.border_box.size.block;
|
self.base.position.size.block = self.fragment.border_box.size.block;
|
||||||
|
self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
|
||||||
|
self.fragment.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
} else if self.is_root() || self.formatting_context_type() != FormattingContextType::None {
|
} else if self.is_root() || self.formatting_context_type() != FormattingContextType::None {
|
||||||
|
@ -2114,6 +2117,8 @@ impl Flow for BlockFlow {
|
||||||
flow::mut_base(kid).stacking_relative_position_of_display_port =
|
flow::mut_base(kid).stacking_relative_position_of_display_port =
|
||||||
stacking_relative_position_of_display_port_for_children;
|
stacking_relative_position_of_display_port_for_children;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.base.restyle_damage.remove(REPOSITION)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mark_as_root(&mut self) {
|
fn mark_as_root(&mut self) {
|
||||||
|
|
|
@ -42,7 +42,8 @@ use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo};
|
||||||
use multicol::MulticolFlow;
|
use multicol::MulticolFlow;
|
||||||
use parallel::FlowParallelInfo;
|
use parallel::FlowParallelInfo;
|
||||||
use rustc_serialize::{Encodable, Encoder};
|
use rustc_serialize::{Encodable, Encoder};
|
||||||
use script_layout_interface::restyle_damage::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RestyleDamage};
|
use script_layout_interface::restyle_damage::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW};
|
||||||
|
use script_layout_interface::restyle_damage::{REPAINT, REPOSITION, RestyleDamage};
|
||||||
use script_layout_interface::wrapper_traits::{PseudoElementType, ThreadSafeLayoutNode};
|
use script_layout_interface::wrapper_traits::{PseudoElementType, ThreadSafeLayoutNode};
|
||||||
use std::{fmt, mem, raw};
|
use std::{fmt, mem, raw};
|
||||||
use std::iter::Zip;
|
use std::iter::Zip;
|
||||||
|
@ -320,6 +321,7 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static {
|
||||||
/// Phase 4 of reflow: computes absolute positions.
|
/// Phase 4 of reflow: computes absolute positions.
|
||||||
fn compute_absolute_position(&mut self, _: &SharedLayoutContext) {
|
fn compute_absolute_position(&mut self, _: &SharedLayoutContext) {
|
||||||
// The default implementation is a no-op.
|
// The default implementation is a no-op.
|
||||||
|
mut_base(self).restyle_damage.remove(REPOSITION)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Phase 5 of reflow: builds display lists.
|
/// Phase 5 of reflow: builds display lists.
|
||||||
|
|
|
@ -25,8 +25,8 @@ use gfx_traits::print_tree::PrintTree;
|
||||||
use layout_debug;
|
use layout_debug;
|
||||||
use model::IntrinsicISizesContribution;
|
use model::IntrinsicISizesContribution;
|
||||||
use range::{Range, RangeIndex};
|
use range::{Range, RangeIndex};
|
||||||
use script_layout_interface::restyle_damage::{BUBBLE_ISIZES, REFLOW};
|
use script_layout_interface::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW};
|
||||||
use script_layout_interface::restyle_damage::{REFLOW_OUT_OF_FLOW, RESOLVE_GENERATED_CONTENT};
|
use script_layout_interface::restyle_damage::{REPOSITION, RESOLVE_GENERATED_CONTENT};
|
||||||
use script_layout_interface::wrapper_traits::PseudoElementType;
|
use script_layout_interface::wrapper_traits::PseudoElementType;
|
||||||
use std::{fmt, i32, isize, mem};
|
use std::{fmt, i32, isize, mem};
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
|
@ -1650,6 +1650,8 @@ impl Flow for InlineFlow {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.base.restyle_damage.remove(REPOSITION)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_late_computed_inline_position_if_necessary(&mut self, _: Au) {}
|
fn update_late_computed_inline_position_if_necessary(&mut self, _: Au) {}
|
||||||
|
|
|
@ -17,7 +17,7 @@ use generated_content::ResolveGeneratedContent;
|
||||||
use gfx::display_list::{DisplayItem, StackingContext};
|
use gfx::display_list::{DisplayItem, StackingContext};
|
||||||
use script_layout_interface::restyle_damage::{REFLOW, STORE_OVERFLOW};
|
use script_layout_interface::restyle_damage::{REFLOW, STORE_OVERFLOW};
|
||||||
use style::context::StyleContext;
|
use style::context::StyleContext;
|
||||||
use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList, ComputeAbsolutePositions};
|
use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList};
|
||||||
use util::opts;
|
use util::opts;
|
||||||
|
|
||||||
pub use style::sequential::traverse_dom;
|
pub use style::sequential::traverse_dom;
|
||||||
|
@ -78,7 +78,6 @@ pub fn build_display_list_for_subtree(flow_root: &mut Flow,
|
||||||
root_stacking_context: &mut StackingContext,
|
root_stacking_context: &mut StackingContext,
|
||||||
shared_layout_context: &SharedLayoutContext)
|
shared_layout_context: &SharedLayoutContext)
|
||||||
-> Vec<DisplayItem> {
|
-> Vec<DisplayItem> {
|
||||||
flow_root.traverse_preorder(&ComputeAbsolutePositions { layout_context: shared_layout_context });
|
|
||||||
let mut children = vec![];
|
let mut children = vec![];
|
||||||
flow_root.collect_stacking_contexts(root_stacking_context.id,
|
flow_root.collect_stacking_contexts(root_stacking_context.id,
|
||||||
&mut children);
|
&mut children);
|
||||||
|
|
|
@ -21,6 +21,7 @@ use gfx_traits::print_tree::PrintTree;
|
||||||
use layout_debug;
|
use layout_debug;
|
||||||
use model::MaybeAuto;
|
use model::MaybeAuto;
|
||||||
use rustc_serialize::{Encodable, Encoder};
|
use rustc_serialize::{Encodable, Encoder};
|
||||||
|
use script_layout_interface::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW};
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::iter::{Enumerate, IntoIterator, Peekable};
|
use std::iter::{Enumerate, IntoIterator, Peekable};
|
||||||
|
@ -106,14 +107,16 @@ impl TableRowFlow {
|
||||||
/// methods
|
/// methods
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn assign_block_size_table_row_base(&mut self, layout_context: &LayoutContext) {
|
fn assign_block_size_table_row_base(&mut self, layout_context: &LayoutContext) {
|
||||||
// Per CSS 2.1 § 17.5.3, find max_y = max(computed `block-size`, minimum block-size of all
|
if self.block_flow.base.restyle_damage.contains(REFLOW) {
|
||||||
// cells).
|
// Per CSS 2.1 § 17.5.3, find max_y = max(computed `block-size`, minimum block-size of
|
||||||
|
// all cells).
|
||||||
let mut max_block_size = Au(0);
|
let mut max_block_size = Au(0);
|
||||||
let thread_id = self.block_flow.base.thread_id;
|
let thread_id = self.block_flow.base.thread_id;
|
||||||
for kid in self.block_flow.base.child_iter_mut() {
|
for kid in self.block_flow.base.child_iter_mut() {
|
||||||
kid.place_float_if_applicable();
|
kid.place_float_if_applicable();
|
||||||
if !flow::base(kid).flags.is_float() {
|
if !flow::base(kid).flags.is_float() {
|
||||||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context, thread_id);
|
kid.assign_block_size_for_inorder_child_if_necessary(layout_context,
|
||||||
|
thread_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -165,16 +168,25 @@ impl TableRowFlow {
|
||||||
// Now we know the cell height, vertical align the cell's children.
|
// Now we know the cell height, vertical align the cell's children.
|
||||||
child_table_cell.valign_children();
|
child_table_cell.valign_children();
|
||||||
|
|
||||||
// Write in the size of the relative containing block for children. (This information
|
// Write in the size of the relative containing block for children. (This
|
||||||
// is also needed to handle RTL.)
|
// information is also needed to handle RTL.)
|
||||||
child_table_cell.block_flow.base.early_absolute_position_info =
|
child_table_cell.block_flow.base.early_absolute_position_info =
|
||||||
EarlyAbsolutePositionInfo {
|
EarlyAbsolutePositionInfo {
|
||||||
relative_containing_block_size: self.block_flow.fragment.content_box().size,
|
relative_containing_block_size: self.block_flow
|
||||||
relative_containing_block_mode: self.block_flow.fragment.style().writing_mode,
|
.fragment
|
||||||
|
.content_box()
|
||||||
|
.size,
|
||||||
|
relative_containing_block_mode: self.block_flow
|
||||||
|
.fragment
|
||||||
|
.style()
|
||||||
|
.writing_mode,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.block_flow.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn populate_collapsed_border_spacing<'a, I>(
|
pub fn populate_collapsed_border_spacing<'a, I>(
|
||||||
&mut self,
|
&mut self,
|
||||||
collapsed_inline_direction_border_widths_for_table: &[Au],
|
collapsed_inline_direction_border_widths_for_table: &[Au],
|
||||||
|
|
|
@ -65,7 +65,7 @@ use layout::animation;
|
||||||
use layout::construct::ConstructionResult;
|
use layout::construct::ConstructionResult;
|
||||||
use layout::context::{LayoutContext, SharedLayoutContext, heap_size_of_local_context};
|
use layout::context::{LayoutContext, SharedLayoutContext, heap_size_of_local_context};
|
||||||
use layout::display_list_builder::ToGfxColor;
|
use layout::display_list_builder::ToGfxColor;
|
||||||
use layout::flow::{self, Flow, ImmutableFlowUtils, MutableOwnedFlowUtils};
|
use layout::flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils};
|
||||||
use layout::flow_ref::{self, FlowRef};
|
use layout::flow_ref::{self, FlowRef};
|
||||||
use layout::incremental::{LayoutDamageComputation, REFLOW_ENTIRE_DOCUMENT};
|
use layout::incremental::{LayoutDamageComputation, REFLOW_ENTIRE_DOCUMENT};
|
||||||
use layout::layout_debug;
|
use layout::layout_debug;
|
||||||
|
@ -75,7 +75,7 @@ use layout::query::{process_margin_style_query, process_node_overflow_request, p
|
||||||
use layout::query::{process_node_geometry_request, process_node_layer_id_request, process_node_scroll_area_request};
|
use layout::query::{process_node_geometry_request, process_node_layer_id_request, process_node_scroll_area_request};
|
||||||
use layout::query::process_offset_parent_query;
|
use layout::query::process_offset_parent_query;
|
||||||
use layout::sequential;
|
use layout::sequential;
|
||||||
use layout::traversal::RecalcStyleAndConstructFlows;
|
use layout::traversal::{ComputeAbsolutePositions, RecalcStyleAndConstructFlows};
|
||||||
use layout::webrender_helpers::{WebRenderDisplayListConverter, WebRenderFrameBuilder};
|
use layout::webrender_helpers::{WebRenderDisplayListConverter, WebRenderFrameBuilder};
|
||||||
use layout::wrapper::{LayoutNodeLayoutData, NonOpaqueStyleAndLayoutData};
|
use layout::wrapper::{LayoutNodeLayoutData, NonOpaqueStyleAndLayoutData};
|
||||||
use layout_traits::LayoutThreadFactory;
|
use layout_traits::LayoutThreadFactory;
|
||||||
|
@ -89,7 +89,8 @@ use script::layout_wrapper::{ServoLayoutDocument, ServoLayoutNode};
|
||||||
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialStyleAndLayoutData};
|
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialStyleAndLayoutData};
|
||||||
use script_layout_interface::message::{Msg, NewLayoutThreadInfo, Reflow, ReflowQueryType, ScriptReflow};
|
use script_layout_interface::message::{Msg, NewLayoutThreadInfo, Reflow, ReflowQueryType, ScriptReflow};
|
||||||
use script_layout_interface::reporter::CSSErrorReporter;
|
use script_layout_interface::reporter::CSSErrorReporter;
|
||||||
use script_layout_interface::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, STORE_OVERFLOW};
|
use script_layout_interface::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION};
|
||||||
|
use script_layout_interface::restyle_damage::STORE_OVERFLOW;
|
||||||
use script_layout_interface::rpc::{LayoutRPC, MarginStyleResponse, NodeOverflowResponse, OffsetParentResponse};
|
use script_layout_interface::rpc::{LayoutRPC, MarginStyleResponse, NodeOverflowResponse, OffsetParentResponse};
|
||||||
use script_layout_interface::wrapper_traits::LayoutNode;
|
use script_layout_interface::wrapper_traits::LayoutNode;
|
||||||
use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg};
|
use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg};
|
||||||
|
@ -629,6 +630,7 @@ impl LayoutThread {
|
||||||
reflow_info.goal);
|
reflow_info.goal);
|
||||||
|
|
||||||
self.perform_post_style_recalc_layout_passes(&reflow_info,
|
self.perform_post_style_recalc_layout_passes(&reflow_info,
|
||||||
|
None,
|
||||||
None,
|
None,
|
||||||
&mut *rw_data,
|
&mut *rw_data,
|
||||||
&mut layout_context);
|
&mut layout_context);
|
||||||
|
@ -900,8 +902,11 @@ impl LayoutThread {
|
||||||
traversal);
|
traversal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Computes the stacking-relative positions of all flows and, if the painting is dirty and the
|
||||||
|
/// reflow goal and query type need it, builds the display list.
|
||||||
fn compute_abs_pos_and_build_display_list(&mut self,
|
fn compute_abs_pos_and_build_display_list(&mut self,
|
||||||
data: &Reflow,
|
data: &Reflow,
|
||||||
|
query_type: Option<&ReflowQueryType>,
|
||||||
document: Option<&ServoLayoutDocument>,
|
document: Option<&ServoLayoutDocument>,
|
||||||
layout_root: &mut Flow,
|
layout_root: &mut Flow,
|
||||||
shared_layout_context: &mut SharedLayoutContext,
|
shared_layout_context: &mut SharedLayoutContext,
|
||||||
|
@ -919,9 +924,20 @@ impl LayoutThread {
|
||||||
flow::mut_base(layout_root).clip =
|
flow::mut_base(layout_root).clip =
|
||||||
ClippingRegion::from_rect(&data.page_clip_rect);
|
ClippingRegion::from_rect(&data.page_clip_rect);
|
||||||
|
|
||||||
|
if flow::base(layout_root).restyle_damage.contains(REPOSITION) {
|
||||||
|
layout_root.traverse_preorder(&ComputeAbsolutePositions {
|
||||||
|
layout_context: shared_layout_context
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if flow::base(layout_root).restyle_damage.contains(REPAINT) ||
|
if flow::base(layout_root).restyle_damage.contains(REPAINT) ||
|
||||||
rw_data.display_list.is_none() {
|
rw_data.display_list.is_none() {
|
||||||
let mut root_stacking_context = StackingContext::new(StackingContextId::new(0),
|
let display_list_needed = query_type.map(reflow_query_type_needs_display_list)
|
||||||
|
.unwrap_or(false);
|
||||||
|
match (data.goal, display_list_needed) {
|
||||||
|
(ReflowGoal::ForDisplay, _) | (ReflowGoal::ForScriptQuery, true) => {
|
||||||
|
let mut root_stacking_context =
|
||||||
|
StackingContext::new(StackingContextId::new(0),
|
||||||
StackingContextType::Real,
|
StackingContextType::Real,
|
||||||
&Rect::zero(),
|
&Rect::zero(),
|
||||||
&Rect::zero(),
|
&Rect::zero(),
|
||||||
|
@ -961,7 +977,11 @@ impl LayoutThread {
|
||||||
root_background_color));
|
root_background_color));
|
||||||
|
|
||||||
rw_data.display_list =
|
rw_data.display_list =
|
||||||
Some(Arc::new(DisplayList::new(root_stacking_context, display_list_entries)))
|
Some(Arc::new(DisplayList::new(root_stacking_context,
|
||||||
|
display_list_entries)))
|
||||||
|
}
|
||||||
|
(ReflowGoal::ForScriptQuery, false) => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if data.goal != ReflowGoal::ForDisplay {
|
if data.goal != ReflowGoal::ForDisplay {
|
||||||
|
@ -1038,6 +1058,12 @@ impl LayoutThread {
|
||||||
let document = unsafe { ServoLayoutNode::new(&data.document) };
|
let document = unsafe { ServoLayoutNode::new(&data.document) };
|
||||||
let document = document.as_document().unwrap();
|
let document = document.as_document().unwrap();
|
||||||
|
|
||||||
|
// FIXME(pcwalton): Combine `ReflowGoal` and `ReflowQueryType`. Then remove this assert.
|
||||||
|
debug_assert!((data.reflow_info.goal == ReflowGoal::ForDisplay &&
|
||||||
|
data.query_type == ReflowQueryType::NoQuery) ||
|
||||||
|
(data.reflow_info.goal == ReflowGoal::ForScriptQuery &&
|
||||||
|
data.query_type != ReflowQueryType::NoQuery));
|
||||||
|
|
||||||
debug!("layout: received layout request for: {}", self.url);
|
debug!("layout: received layout request for: {}", self.url);
|
||||||
|
|
||||||
let mut rw_data = possibly_locked_rw_data.lock();
|
let mut rw_data = possibly_locked_rw_data.lock();
|
||||||
|
@ -1217,13 +1243,26 @@ impl LayoutThread {
|
||||||
|
|
||||||
// Perform post-style recalculation layout passes.
|
// Perform post-style recalculation layout passes.
|
||||||
self.perform_post_style_recalc_layout_passes(&data.reflow_info,
|
self.perform_post_style_recalc_layout_passes(&data.reflow_info,
|
||||||
|
Some(&data.query_type),
|
||||||
Some(&document),
|
Some(&document),
|
||||||
&mut rw_data,
|
&mut rw_data,
|
||||||
&mut shared_layout_context);
|
&mut shared_layout_context);
|
||||||
|
|
||||||
if let Some(mut root_flow) = self.root_flow.clone() {
|
self.respond_to_query_if_necessary(&data.query_type,
|
||||||
|
&mut *rw_data,
|
||||||
|
&mut shared_layout_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn respond_to_query_if_necessary(&mut self,
|
||||||
|
query_type: &ReflowQueryType,
|
||||||
|
rw_data: &mut LayoutThreadData,
|
||||||
|
shared_layout_context: &mut SharedLayoutContext) {
|
||||||
|
let mut root_flow = match self.root_flow.clone() {
|
||||||
|
Some(root_flow) => root_flow,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
let root_flow = flow_ref::deref_mut(&mut root_flow);
|
let root_flow = flow_ref::deref_mut(&mut root_flow);
|
||||||
match data.query_type {
|
match *query_type {
|
||||||
ReflowQueryType::ContentBoxQuery(node) => {
|
ReflowQueryType::ContentBoxQuery(node) => {
|
||||||
let node = unsafe { ServoLayoutNode::new(&node) };
|
let node = unsafe { ServoLayoutNode::new(&node) };
|
||||||
rw_data.content_box_response = process_content_box_request(node, root_flow);
|
rw_data.content_box_response = process_content_box_request(node, root_flow);
|
||||||
|
@ -1233,12 +1272,10 @@ impl LayoutThread {
|
||||||
rw_data.content_boxes_response = process_content_boxes_request(node, root_flow);
|
rw_data.content_boxes_response = process_content_boxes_request(node, root_flow);
|
||||||
},
|
},
|
||||||
ReflowQueryType::HitTestQuery(translated_point, client_point, update_cursor) => {
|
ReflowQueryType::HitTestQuery(translated_point, client_point, update_cursor) => {
|
||||||
let translated_point =
|
let translated_point = Point2D::new(Au::from_f32_px(translated_point.x),
|
||||||
Point2D::new(Au::from_f32_px(translated_point.x),
|
|
||||||
Au::from_f32_px(translated_point.y));
|
Au::from_f32_px(translated_point.y));
|
||||||
|
|
||||||
let client_point =
|
let client_point = Point2D::new(Au::from_f32_px(client_point.x),
|
||||||
Point2D::new(Au::from_f32_px(client_point.x),
|
|
||||||
Au::from_f32_px(client_point.y));
|
Au::from_f32_px(client_point.y));
|
||||||
|
|
||||||
let result = rw_data.display_list
|
let result = rw_data.display_list
|
||||||
|
@ -1286,7 +1323,6 @@ impl LayoutThread {
|
||||||
ReflowQueryType::NoQuery => {}
|
ReflowQueryType::NoQuery => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn set_visible_rects<'a, 'b>(&mut self,
|
fn set_visible_rects<'a, 'b>(&mut self,
|
||||||
new_visible_rects: Vec<(LayerId, Rect<Au>)>,
|
new_visible_rects: Vec<(LayerId, Rect<Au>)>,
|
||||||
|
@ -1340,7 +1376,11 @@ impl LayoutThread {
|
||||||
false,
|
false,
|
||||||
reflow_info.goal);
|
reflow_info.goal);
|
||||||
|
|
||||||
self.perform_post_main_layout_passes(&reflow_info, None, &mut *rw_data, &mut layout_context);
|
self.perform_post_main_layout_passes(&reflow_info,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
&mut *rw_data,
|
||||||
|
&mut layout_context);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1398,6 +1438,7 @@ impl LayoutThread {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.perform_post_style_recalc_layout_passes(&reflow_info,
|
self.perform_post_style_recalc_layout_passes(&reflow_info,
|
||||||
|
None,
|
||||||
None,
|
None,
|
||||||
&mut *rw_data,
|
&mut *rw_data,
|
||||||
&mut layout_context);
|
&mut layout_context);
|
||||||
|
@ -1421,6 +1462,7 @@ impl LayoutThread {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.perform_post_style_recalc_layout_passes(&reflow_info,
|
self.perform_post_style_recalc_layout_passes(&reflow_info,
|
||||||
|
None,
|
||||||
None,
|
None,
|
||||||
&mut *rw_data,
|
&mut *rw_data,
|
||||||
&mut layout_context);
|
&mut layout_context);
|
||||||
|
@ -1428,6 +1470,7 @@ impl LayoutThread {
|
||||||
|
|
||||||
fn perform_post_style_recalc_layout_passes(&mut self,
|
fn perform_post_style_recalc_layout_passes(&mut self,
|
||||||
data: &Reflow,
|
data: &Reflow,
|
||||||
|
query_type: Option<&ReflowQueryType>,
|
||||||
document: Option<&ServoLayoutDocument>,
|
document: Option<&ServoLayoutDocument>,
|
||||||
rw_data: &mut LayoutThreadData,
|
rw_data: &mut LayoutThreadData,
|
||||||
layout_context: &mut SharedLayoutContext) {
|
layout_context: &mut SharedLayoutContext) {
|
||||||
|
@ -1503,18 +1546,24 @@ impl LayoutThread {
|
||||||
flow_ref::deref_mut(&mut root_flow) as &mut Flow);
|
flow_ref::deref_mut(&mut root_flow) as &mut Flow);
|
||||||
});
|
});
|
||||||
|
|
||||||
self.perform_post_main_layout_passes(data, document, rw_data, layout_context);
|
self.perform_post_main_layout_passes(data,
|
||||||
|
query_type,
|
||||||
|
document,
|
||||||
|
rw_data,
|
||||||
|
layout_context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn perform_post_main_layout_passes(&mut self,
|
fn perform_post_main_layout_passes(&mut self,
|
||||||
data: &Reflow,
|
data: &Reflow,
|
||||||
|
query_type: Option<&ReflowQueryType>,
|
||||||
document: Option<&ServoLayoutDocument>,
|
document: Option<&ServoLayoutDocument>,
|
||||||
rw_data: &mut LayoutThreadData,
|
rw_data: &mut LayoutThreadData,
|
||||||
layout_context: &mut SharedLayoutContext) {
|
layout_context: &mut SharedLayoutContext) {
|
||||||
// Build the display list if necessary, and send it to the painter.
|
// Build the display list if necessary, and send it to the painter.
|
||||||
if let Some(mut root_flow) = self.root_flow.clone() {
|
if let Some(mut root_flow) = self.root_flow.clone() {
|
||||||
self.compute_abs_pos_and_build_display_list(data,
|
self.compute_abs_pos_and_build_display_list(data,
|
||||||
|
query_type,
|
||||||
document,
|
document,
|
||||||
flow_ref::deref_mut(&mut root_flow),
|
flow_ref::deref_mut(&mut root_flow),
|
||||||
&mut *layout_context,
|
&mut *layout_context,
|
||||||
|
@ -1632,6 +1681,18 @@ fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the given reflow query type needs a full, up-to-date display list to be present
|
||||||
|
/// or false if it only needs stacking-relative positions.
|
||||||
|
fn reflow_query_type_needs_display_list(query_type: &ReflowQueryType) -> bool {
|
||||||
|
match *query_type {
|
||||||
|
ReflowQueryType::HitTestQuery(..) => true,
|
||||||
|
ReflowQueryType::ContentBoxQuery(_) | ReflowQueryType::ContentBoxesQuery(_) |
|
||||||
|
ReflowQueryType::NodeGeometryQuery(_) | ReflowQueryType::NodeScrollGeometryQuery(_) |
|
||||||
|
ReflowQueryType::NodeOverflowQuery(_) | ReflowQueryType::NodeLayerIdQuery(_) |
|
||||||
|
ReflowQueryType::ResolvedStyleQuery(..) | ReflowQueryType::OffsetParentQuery(_) |
|
||||||
|
ReflowQueryType::MarginStyleQuery(_) | ReflowQueryType::NoQuery => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref UA_STYLESHEETS: UserAgentStylesheets = {
|
static ref UA_STYLESHEETS: UserAgentStylesheets = {
|
||||||
|
|
|
@ -15,31 +15,36 @@ bitflags! {
|
||||||
#[doc = "Currently unused; need to decide how this propagates."]
|
#[doc = "Currently unused; need to decide how this propagates."]
|
||||||
const REPAINT = 0x01,
|
const REPAINT = 0x01,
|
||||||
|
|
||||||
|
#[doc = "The stacking-context-relative position of this node or its descendants has \
|
||||||
|
changed."]
|
||||||
|
#[doc = "Propagates both up and down the flow tree."]
|
||||||
|
const REPOSITION = 0x02,
|
||||||
|
|
||||||
#[doc = "Recompute the overflow regions (bounding box of object and all descendants)."]
|
#[doc = "Recompute the overflow regions (bounding box of object and all descendants)."]
|
||||||
#[doc = "Propagates down the flow tree because the computation is bottom-up."]
|
#[doc = "Propagates down the flow tree because the computation is bottom-up."]
|
||||||
const STORE_OVERFLOW = 0x02,
|
const STORE_OVERFLOW = 0x04,
|
||||||
|
|
||||||
#[doc = "Recompute intrinsic inline_sizes (minimum and preferred)."]
|
#[doc = "Recompute intrinsic inline_sizes (minimum and preferred)."]
|
||||||
#[doc = "Propagates down the flow tree because the computation is"]
|
#[doc = "Propagates down the flow tree because the computation is"]
|
||||||
#[doc = "bottom-up."]
|
#[doc = "bottom-up."]
|
||||||
const BUBBLE_ISIZES = 0x04,
|
const BUBBLE_ISIZES = 0x08,
|
||||||
|
|
||||||
#[doc = "Recompute actual inline-sizes and block-sizes, only taking out-of-flow children \
|
#[doc = "Recompute actual inline-sizes and block-sizes, only taking out-of-flow children \
|
||||||
into account. \
|
into account. \
|
||||||
Propagates up the flow tree because the computation is top-down."]
|
Propagates up the flow tree because the computation is top-down."]
|
||||||
const REFLOW_OUT_OF_FLOW = 0x08,
|
const REFLOW_OUT_OF_FLOW = 0x10,
|
||||||
|
|
||||||
#[doc = "Recompute actual inline_sizes and block_sizes."]
|
#[doc = "Recompute actual inline_sizes and block_sizes."]
|
||||||
#[doc = "Propagates up the flow tree because the computation is"]
|
#[doc = "Propagates up the flow tree because the computation is"]
|
||||||
#[doc = "top-down."]
|
#[doc = "top-down."]
|
||||||
const REFLOW = 0x10,
|
const REFLOW = 0x20,
|
||||||
|
|
||||||
#[doc = "Re-resolve generated content. \
|
#[doc = "Re-resolve generated content. \
|
||||||
Propagates up the flow tree because the computation is inorder."]
|
Propagates up the flow tree because the computation is inorder."]
|
||||||
const RESOLVE_GENERATED_CONTENT = 0x20,
|
const RESOLVE_GENERATED_CONTENT = 0x40,
|
||||||
|
|
||||||
#[doc = "The entire flow needs to be reconstructed."]
|
#[doc = "The entire flow needs to be reconstructed."]
|
||||||
const RECONSTRUCT_FLOW = 0x40
|
const RECONSTRUCT_FLOW = 0x80
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +68,8 @@ impl TRestyleDamage for RestyleDamage {
|
||||||
/// `RestyleDamage::all()` will result in unnecessary sequential resolution
|
/// `RestyleDamage::all()` will result in unnecessary sequential resolution
|
||||||
/// of generated content.
|
/// of generated content.
|
||||||
fn rebuild_and_reflow() -> RestyleDamage {
|
fn rebuild_and_reflow() -> RestyleDamage {
|
||||||
REPAINT | STORE_OVERFLOW | BUBBLE_ISIZES | REFLOW_OUT_OF_FLOW | REFLOW | RECONSTRUCT_FLOW
|
REPAINT | REPOSITION | STORE_OVERFLOW | BUBBLE_ISIZES | REFLOW_OUT_OF_FLOW | REFLOW |
|
||||||
|
RECONSTRUCT_FLOW
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,9 +78,10 @@ impl RestyleDamage {
|
||||||
/// returns the damage that we should add to the *parent* of this flow.
|
/// returns the damage that we should add to the *parent* of this flow.
|
||||||
pub fn damage_for_parent(self, child_is_absolutely_positioned: bool) -> RestyleDamage {
|
pub fn damage_for_parent(self, child_is_absolutely_positioned: bool) -> RestyleDamage {
|
||||||
if child_is_absolutely_positioned {
|
if child_is_absolutely_positioned {
|
||||||
self & (REPAINT | STORE_OVERFLOW | REFLOW_OUT_OF_FLOW | RESOLVE_GENERATED_CONTENT)
|
self & (REPAINT | REPOSITION | STORE_OVERFLOW | REFLOW_OUT_OF_FLOW |
|
||||||
|
RESOLVE_GENERATED_CONTENT)
|
||||||
} else {
|
} else {
|
||||||
self & (REPAINT | STORE_OVERFLOW | REFLOW | REFLOW_OUT_OF_FLOW |
|
self & (REPAINT | REPOSITION | STORE_OVERFLOW | REFLOW | REFLOW_OUT_OF_FLOW |
|
||||||
RESOLVE_GENERATED_CONTENT)
|
RESOLVE_GENERATED_CONTENT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +97,7 @@ impl RestyleDamage {
|
||||||
// Absolute children are out-of-flow and therefore insulated from changes.
|
// Absolute children are out-of-flow and therefore insulated from changes.
|
||||||
//
|
//
|
||||||
// FIXME(pcwalton): Au contraire, if the containing block dimensions change!
|
// FIXME(pcwalton): Au contraire, if the containing block dimensions change!
|
||||||
self & REPAINT
|
self & (REPAINT | REPOSITION)
|
||||||
}
|
}
|
||||||
(true, false) => {
|
(true, false) => {
|
||||||
// Changing the position of an absolutely-positioned block requires us to reflow
|
// Changing the position of an absolutely-positioned block requires us to reflow
|
||||||
|
@ -103,7 +110,7 @@ impl RestyleDamage {
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// TODO(pcwalton): Take floatedness into account.
|
// TODO(pcwalton): Take floatedness into account.
|
||||||
self & (REPAINT | REFLOW)
|
self & (REPAINT | REPOSITION | REFLOW)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,6 +122,7 @@ impl fmt::Display for RestyleDamage {
|
||||||
|
|
||||||
let to_iter =
|
let to_iter =
|
||||||
[ (REPAINT, "Repaint")
|
[ (REPAINT, "Repaint")
|
||||||
|
, (REPOSITION, "Reposition")
|
||||||
, (STORE_OVERFLOW, "StoreOverflow")
|
, (STORE_OVERFLOW, "StoreOverflow")
|
||||||
, (BUBBLE_ISIZES, "BubbleISizes")
|
, (BUBBLE_ISIZES, "BubbleISizes")
|
||||||
, (REFLOW_OUT_OF_FLOW, "ReflowOutOfFlow")
|
, (REFLOW_OUT_OF_FLOW, "ReflowOutOfFlow")
|
||||||
|
@ -163,14 +171,8 @@ fn compute_damage(old: &ServoComputedValues, new: &ServoComputedValues) -> Resty
|
||||||
// FIXME: Test somehow that every property is included.
|
// FIXME: Test somehow that every property is included.
|
||||||
|
|
||||||
add_if_not_equal!(old, new, damage,
|
add_if_not_equal!(old, new, damage,
|
||||||
[
|
[REPAINT, REPOSITION, STORE_OVERFLOW, BUBBLE_ISIZES, REFLOW_OUT_OF_FLOW,
|
||||||
REPAINT,
|
REFLOW, RECONSTRUCT_FLOW], [
|
||||||
STORE_OVERFLOW,
|
|
||||||
BUBBLE_ISIZES,
|
|
||||||
REFLOW_OUT_OF_FLOW,
|
|
||||||
REFLOW,
|
|
||||||
RECONSTRUCT_FLOW
|
|
||||||
], [
|
|
||||||
get_box.float, get_box.display, get_box.position, get_counters.content,
|
get_box.float, get_box.display, get_box.position, get_counters.content,
|
||||||
get_counters.counter_reset, get_counters.counter_increment,
|
get_counters.counter_reset, get_counters.counter_increment,
|
||||||
get_inheritedbox._servo_under_display_none,
|
get_inheritedbox._servo_under_display_none,
|
||||||
|
@ -191,8 +193,8 @@ fn compute_damage(old: &ServoComputedValues, new: &ServoComputedValues) -> Resty
|
||||||
get_column.column_width, get_column.column_count
|
get_column.column_width, get_column.column_count
|
||||||
]) || (new.get_box().display == display::T::inline &&
|
]) || (new.get_box().display == display::T::inline &&
|
||||||
add_if_not_equal!(old, new, damage,
|
add_if_not_equal!(old, new, damage,
|
||||||
[REPAINT, STORE_OVERFLOW, BUBBLE_ISIZES, REFLOW_OUT_OF_FLOW, REFLOW,
|
[REPAINT, REPOSITION, STORE_OVERFLOW, BUBBLE_ISIZES,
|
||||||
RECONSTRUCT_FLOW], [
|
REFLOW_OUT_OF_FLOW, REFLOW, RECONSTRUCT_FLOW], [
|
||||||
// For inline boxes only, border/padding styles are used in flow construction (to decide
|
// For inline boxes only, border/padding styles are used in flow construction (to decide
|
||||||
// whether to create fragments for empty flows).
|
// whether to create fragments for empty flows).
|
||||||
get_border.border_top_width, get_border.border_right_width,
|
get_border.border_top_width, get_border.border_right_width,
|
||||||
|
@ -200,7 +202,8 @@ fn compute_damage(old: &ServoComputedValues, new: &ServoComputedValues) -> Resty
|
||||||
get_padding.padding_top, get_padding.padding_right,
|
get_padding.padding_top, get_padding.padding_right,
|
||||||
get_padding.padding_bottom, get_padding.padding_left
|
get_padding.padding_bottom, get_padding.padding_left
|
||||||
])) || add_if_not_equal!(old, new, damage,
|
])) || add_if_not_equal!(old, new, damage,
|
||||||
[ REPAINT, STORE_OVERFLOW, BUBBLE_ISIZES, REFLOW_OUT_OF_FLOW, REFLOW ],
|
[REPAINT, REPOSITION, STORE_OVERFLOW, BUBBLE_ISIZES,
|
||||||
|
REFLOW_OUT_OF_FLOW, REFLOW],
|
||||||
[get_border.border_top_width, get_border.border_right_width,
|
[get_border.border_top_width, get_border.border_right_width,
|
||||||
get_border.border_bottom_width, get_border.border_left_width,
|
get_border.border_bottom_width, get_border.border_left_width,
|
||||||
get_margin.margin_top, get_margin.margin_right,
|
get_margin.margin_top, get_margin.margin_right,
|
||||||
|
@ -225,9 +228,12 @@ fn compute_damage(old: &ServoComputedValues, new: &ServoComputedValues) -> Resty
|
||||||
get_position.flex_shrink,
|
get_position.flex_shrink,
|
||||||
get_position.align_self
|
get_position.align_self
|
||||||
]) || add_if_not_equal!(old, new, damage,
|
]) || add_if_not_equal!(old, new, damage,
|
||||||
[ REPAINT, STORE_OVERFLOW, REFLOW_OUT_OF_FLOW ], [
|
[REPAINT, REPOSITION, STORE_OVERFLOW, REFLOW_OUT_OF_FLOW], [
|
||||||
get_position.top, get_position.left,
|
get_position.top, get_position.left,
|
||||||
get_position.right, get_position.bottom
|
get_position.right, get_position.bottom,
|
||||||
|
get_effects.opacity,
|
||||||
|
get_effects.transform, get_effects.transform_style, get_effects.transform_origin,
|
||||||
|
get_effects.perspective, get_effects.perspective_origin
|
||||||
]) || add_if_not_equal!(old, new, damage,
|
]) || add_if_not_equal!(old, new, damage,
|
||||||
[REPAINT], [
|
[REPAINT], [
|
||||||
get_color.color, get_background.background_color,
|
get_color.color, get_background.background_color,
|
||||||
|
@ -245,9 +251,7 @@ fn compute_damage(old: &ServoComputedValues, new: &ServoComputedValues) -> Resty
|
||||||
get_inheritedtext._servo_text_decorations_in_effect,
|
get_inheritedtext._servo_text_decorations_in_effect,
|
||||||
get_pointing.cursor, get_pointing.pointer_events,
|
get_pointing.cursor, get_pointing.pointer_events,
|
||||||
get_effects.box_shadow, get_effects.clip, get_inheritedtext.text_shadow, get_effects.filter,
|
get_effects.box_shadow, get_effects.clip, get_inheritedtext.text_shadow, get_effects.filter,
|
||||||
get_effects.transform, get_effects.backface_visibility, get_effects.transform_style,
|
get_effects.mix_blend_mode, get_inheritedbox.image_rendering,
|
||||||
get_effects.transform_origin, get_effects.perspective, get_effects.perspective_origin,
|
|
||||||
get_effects.mix_blend_mode, get_effects.opacity, get_inheritedbox.image_rendering,
|
|
||||||
|
|
||||||
// Note: May require REFLOW et al. if `visibility: collapse` is implemented.
|
// Note: May require REFLOW et al. if `visibility: collapse` is implemented.
|
||||||
get_inheritedbox.visibility
|
get_inheritedbox.visibility
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue