mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Introduce a concept of restyle damage to the style system.
We can't hoist RestyleDamage itself, because it's very layout-dependent. But this should be enough to let us hoist the things we need.
This commit is contained in:
parent
947134949a
commit
27987c3bb4
7 changed files with 61 additions and 31 deletions
|
@ -35,7 +35,7 @@ use flow_ref::{self, FlowRef, WeakFlowRef};
|
|||
use fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
|
||||
use gfx::display_list::{ClippingRegion, DisplayList};
|
||||
use gfx_traits::LayerId;
|
||||
use incremental::{self, RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, RestyleDamage};
|
||||
use incremental::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, RestyleDamage};
|
||||
use inline::InlineFlow;
|
||||
use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo};
|
||||
use msg::compositor_msg::LayerType;
|
||||
|
@ -48,6 +48,7 @@ use std::sync::Arc;
|
|||
use std::sync::atomic::Ordering;
|
||||
use std::{fmt, mem, raw};
|
||||
use style::computed_values::{clear, display, empty_cells, float, position, text_align};
|
||||
use style::dom::TRestyleDamage;
|
||||
use style::properties::{self, ComputedValues};
|
||||
use style::values::computed::LengthOrPercentageOrAuto;
|
||||
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, TableFlow};
|
||||
|
@ -1046,7 +1047,7 @@ impl BaseFlow {
|
|||
}
|
||||
|
||||
// New flows start out as fully damaged.
|
||||
let mut damage = incremental::rebuild_and_reflow();
|
||||
let mut damage = RestyleDamage::rebuild_and_reflow();
|
||||
damage.remove(RECONSTRUCT_FLOW);
|
||||
|
||||
BaseFlow {
|
||||
|
|
|
@ -18,7 +18,7 @@ use gfx::display_list::{BLUR_INFLATION_FACTOR, OpaqueNode};
|
|||
use gfx::text::glyph::CharIndex;
|
||||
use gfx::text::text_run::{TextRun, TextRunSlice};
|
||||
use gfx_traits::LayerId;
|
||||
use incremental::{self, RECONSTRUCT_FLOW, RestyleDamage};
|
||||
use incremental::{RECONSTRUCT_FLOW, RestyleDamage};
|
||||
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFragmentContext, InlineFragmentNodeInfo};
|
||||
use inline::{InlineMetrics, LAST_FRAGMENT_OF_ELEMENT};
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
|
@ -40,6 +40,7 @@ use style::computed_values::content::ContentItem;
|
|||
use style::computed_values::{border_collapse, clear, display, mix_blend_mode, overflow_wrap};
|
||||
use style::computed_values::{overflow_x, position, text_decoration, transform_style};
|
||||
use style::computed_values::{white_space, word_break, z_index};
|
||||
use style::dom::TRestyleDamage;
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
|
||||
use style::values::computed::{LengthOrPercentageOrNone};
|
||||
|
@ -833,7 +834,7 @@ impl Fragment {
|
|||
self.border_box.start,
|
||||
size);
|
||||
|
||||
let mut restyle_damage = incremental::rebuild_and_reflow();
|
||||
let mut restyle_damage = RestyleDamage::rebuild_and_reflow();
|
||||
restyle_damage.remove(RECONSTRUCT_FLOW);
|
||||
|
||||
Fragment {
|
||||
|
|
|
@ -13,12 +13,13 @@ use flow::{InorderFlowTraversal};
|
|||
use flow::{self, AFFECTS_COUNTERS, Flow, HAS_COUNTER_AFFECTING_CHILDREN, ImmutableFlowUtils};
|
||||
use fragment::{Fragment, GeneratedContentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
|
||||
use gfx::display_list::OpaqueNode;
|
||||
use incremental::{self, RESOLVE_GENERATED_CONTENT};
|
||||
use incremental::{RESOLVE_GENERATED_CONTENT, RestyleDamage};
|
||||
use smallvec::SmallVec;
|
||||
use std::collections::{HashMap, LinkedList};
|
||||
use std::sync::Arc;
|
||||
use style::computed_values::content::ContentItem;
|
||||
use style::computed_values::{display, list_style_type};
|
||||
use style::dom::TRestyleDamage;
|
||||
use style::properties::ComputedValues;
|
||||
use text::TextRunScanner;
|
||||
use wrapper::PseudoElementType;
|
||||
|
@ -431,7 +432,7 @@ fn render_text(layout_context: &LayoutContext,
|
|||
fragments.push_back(Fragment::from_opaque_node_and_style(node,
|
||||
pseudo,
|
||||
style,
|
||||
incremental::rebuild_and_reflow(),
|
||||
RestyleDamage::rebuild_and_reflow(),
|
||||
info));
|
||||
// FIXME(pcwalton): This should properly handle multiple marker fragments. This could happen
|
||||
// due to text run splitting.
|
||||
|
|
|
@ -6,6 +6,7 @@ use flow::{self, AFFECTS_COUNTERS, Flow, HAS_COUNTER_AFFECTING_CHILDREN, IS_ABSO
|
|||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
use style::computed_values::float;
|
||||
use style::dom::TRestyleDamage;
|
||||
use style::properties::ComputedValues;
|
||||
|
||||
bitflags! {
|
||||
|
@ -47,6 +48,18 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
impl TRestyleDamage for RestyleDamage {
|
||||
fn compute(old: &Option<Arc<ComputedValues>>, new: &ComputedValues) -> RestyleDamage { compute_damage(old, new) }
|
||||
|
||||
/// Returns a bitmask that represents a flow that needs to be rebuilt and reflowed.
|
||||
///
|
||||
/// Use this instead of `RestyleDamage::all()` because `RestyleDamage::all()` will result in
|
||||
/// unnecessary sequential resolution of generated content.
|
||||
fn rebuild_and_reflow() -> RestyleDamage {
|
||||
REPAINT | BUBBLE_ISIZES | REFLOW_OUT_OF_FLOW | REFLOW | RECONSTRUCT_FLOW
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl RestyleDamage {
|
||||
/// Supposing a flow has the given `position` property and this damage, returns the damage that
|
||||
|
@ -130,18 +143,10 @@ macro_rules! add_if_not_equal(
|
|||
})
|
||||
);
|
||||
|
||||
/// Returns a bitmask that represents a flow that needs to be rebuilt and reflowed.
|
||||
///
|
||||
/// Use this instead of `RestyleDamage::all()` because `RestyleDamage::all()` will result in
|
||||
/// unnecessary sequential resolution of generated content.
|
||||
pub fn rebuild_and_reflow() -> RestyleDamage {
|
||||
REPAINT | BUBBLE_ISIZES | REFLOW_OUT_OF_FLOW | REFLOW | RECONSTRUCT_FLOW
|
||||
}
|
||||
|
||||
pub fn compute_damage(old: &Option<Arc<ComputedValues>>, new: &ComputedValues) -> RestyleDamage {
|
||||
let old: &ComputedValues =
|
||||
match old.as_ref() {
|
||||
None => return rebuild_and_reflow(),
|
||||
None => return RestyleDamage::rebuild_and_reflow(),
|
||||
Some(cv) => &**cv,
|
||||
};
|
||||
|
||||
|
@ -195,7 +200,7 @@ pub fn compute_damage(old: &Option<Arc<ComputedValues>>, new: &ComputedValues) -
|
|||
// If the layer requirements of this flow have changed due to the value
|
||||
// of the transform, then reflow is required to rebuild the layers.
|
||||
if old.transform_requires_layer() != new.transform_requires_layer() {
|
||||
damage.insert(rebuild_and_reflow());
|
||||
damage.insert(RestyleDamage::rebuild_and_reflow());
|
||||
}
|
||||
|
||||
// FIXME: test somehow that we checked every CSS property
|
||||
|
@ -256,7 +261,7 @@ impl<'a> LayoutDamageComputation for &'a mut Flow {
|
|||
|
||||
fn reflow_entire_document(self) {
|
||||
let self_base = flow::mut_base(self);
|
||||
self_base.restyle_damage.insert(rebuild_and_reflow());
|
||||
self_base.restyle_damage.insert(RestyleDamage::rebuild_and_reflow());
|
||||
self_base.restyle_damage.remove(RECONSTRUCT_FLOW);
|
||||
for kid in self_base.children.iter_mut() {
|
||||
kid.reflow_entire_document();
|
||||
|
|
|
@ -10,13 +10,13 @@ use css::matching::{ElementMatchMethods, MatchMethods, StyleSharingResult};
|
|||
use flow::{PostorderFlowTraversal, PreorderFlowTraversal};
|
||||
use flow::{self, Flow};
|
||||
use gfx::display_list::OpaqueNode;
|
||||
use incremental::{self, BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RestyleDamage};
|
||||
use incremental::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RestyleDamage};
|
||||
use script::layout_interface::ReflowGoal;
|
||||
use selectors::bloom::BloomFilter;
|
||||
use std::cell::RefCell;
|
||||
use std::mem;
|
||||
use style::context::StyleContext;
|
||||
use style::dom::UnsafeNode;
|
||||
use style::dom::{TRestyleDamage, UnsafeNode};
|
||||
use style::matching::ApplicableDeclarations;
|
||||
use util::opts;
|
||||
use util::tid::tid;
|
||||
|
@ -209,8 +209,7 @@ fn recalc_style_at<'a, 'ln, N: LayoutNode<'ln>> (context: &'a DomTraversalContex
|
|||
},
|
||||
None => {
|
||||
if node.has_changed() {
|
||||
node.to_threadsafe().set_restyle_damage(
|
||||
incremental::rebuild_and_reflow())
|
||||
node.set_restyle_damage(N::ConcreteRestyleDamage::rebuild_and_reflow())
|
||||
}
|
||||
None
|
||||
},
|
||||
|
|
|
@ -132,6 +132,7 @@ impl<'ln> ServoLayoutNode<'ln> {
|
|||
impl<'ln> TNode<'ln> for ServoLayoutNode<'ln> {
|
||||
type ConcreteElement = ServoLayoutElement<'ln>;
|
||||
type ConcreteDocument = ServoLayoutDocument<'ln>;
|
||||
type ConcreteRestyleDamage = RestyleDamage;
|
||||
|
||||
fn to_unsafe(&self) -> UnsafeNode {
|
||||
unsafe {
|
||||
|
@ -237,6 +238,14 @@ impl<'ln> TNode<'ln> for ServoLayoutNode<'ln> {
|
|||
unsafe { self.mutate_layout_data().map(|d| transmute(d)) }
|
||||
}
|
||||
|
||||
fn restyle_damage(self) -> RestyleDamage {
|
||||
self.borrow_layout_data().unwrap().restyle_damage
|
||||
}
|
||||
|
||||
fn set_restyle_damage(self, damage: RestyleDamage) {
|
||||
self.mutate_layout_data().unwrap().restyle_damage = damage;
|
||||
}
|
||||
|
||||
fn parent_node(&self) -> Option<ServoLayoutNode<'ln>> {
|
||||
unsafe {
|
||||
self.node.parent_node_ref().map(|node| self.new_with_this_lifetime(&node))
|
||||
|
@ -714,16 +723,9 @@ pub trait ThreadSafeLayoutNode<'ln> : Clone + Copy + Sized {
|
|||
|
||||
fn is_ignorable_whitespace(&self) -> bool;
|
||||
|
||||
/// Get the description of how to account for recent style changes.
|
||||
/// This is a simple bitfield and fine to copy by value.
|
||||
fn restyle_damage(self) -> RestyleDamage {
|
||||
self.borrow_layout_data().unwrap().restyle_damage
|
||||
}
|
||||
fn restyle_damage(self) -> RestyleDamage;
|
||||
|
||||
/// Set the restyle damage field.
|
||||
fn set_restyle_damage(self, damage: RestyleDamage) {
|
||||
self.mutate_layout_data().unwrap().restyle_damage = damage;
|
||||
}
|
||||
fn set_restyle_damage(self, damage: RestyleDamage);
|
||||
|
||||
/// Returns the layout data flags for this node.
|
||||
fn flags(self) -> LayoutDataFlags;
|
||||
|
@ -909,6 +911,14 @@ impl<'ln> ThreadSafeLayoutNode<'ln> for ServoThreadSafeLayoutNode<'ln> {
|
|||
}
|
||||
}
|
||||
|
||||
fn restyle_damage(self) -> RestyleDamage {
|
||||
self.node.restyle_damage()
|
||||
}
|
||||
|
||||
fn set_restyle_damage(self, damage: RestyleDamage) {
|
||||
self.node.set_restyle_damage(damage)
|
||||
}
|
||||
|
||||
fn flags(self) -> LayoutDataFlags {
|
||||
unsafe {
|
||||
(*self.node.borrow_layout_data_unchecked().unwrap()).flags
|
||||
|
|
|
@ -5,13 +5,15 @@
|
|||
#![allow(unsafe_code)]
|
||||
|
||||
use data::PrivateStyleData;
|
||||
use properties::{PropertyDeclaration, PropertyDeclarationBlock};
|
||||
use properties::{ComputedValues, PropertyDeclaration, PropertyDeclarationBlock};
|
||||
use restyle_hints::{ElementSnapshot, RESTYLE_DESCENDANTS, RESTYLE_LATER_SIBLINGS, RESTYLE_SELF, RestyleHint};
|
||||
use selectors::matching::DeclarationBlock;
|
||||
use selectors::states::ElementState;
|
||||
use smallvec::VecLike;
|
||||
use std::cell::{Ref, RefMut};
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::BitOr;
|
||||
use std::sync::Arc;
|
||||
use string_cache::{Atom, Namespace};
|
||||
|
||||
/// Opaque type stored in type-unsafe work queues for parallel layout.
|
||||
|
@ -39,10 +41,15 @@ impl OpaqueNode {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait TRestyleDamage : BitOr<Output=Self> + Copy {
|
||||
fn compute(old: &Option<Arc<ComputedValues>>, new: &ComputedValues) -> Self;
|
||||
fn rebuild_and_reflow() -> Self;
|
||||
}
|
||||
|
||||
pub trait TNode<'ln> : Sized + Copy + Clone {
|
||||
type ConcreteElement: TElement<'ln, ConcreteNode = Self, ConcreteDocument = Self::ConcreteDocument>;
|
||||
type ConcreteDocument: TDocument<'ln, ConcreteNode = Self, ConcreteElement = Self::ConcreteElement>;
|
||||
type ConcreteRestyleDamage: TRestyleDamage;
|
||||
|
||||
fn to_unsafe(&self) -> UnsafeNode;
|
||||
unsafe fn from_unsafe(n: &UnsafeNode) -> Self;
|
||||
|
@ -134,6 +141,12 @@ pub trait TNode<'ln> : Sized + Copy + Clone {
|
|||
#[inline(always)]
|
||||
fn mutate_data(&self) -> Option<RefMut<PrivateStyleData>>;
|
||||
|
||||
/// Get the description of how to account for recent style changes.
|
||||
fn restyle_damage(self) -> Self::ConcreteRestyleDamage;
|
||||
|
||||
/// Set the restyle damage field.
|
||||
fn set_restyle_damage(self, damage: Self::ConcreteRestyleDamage);
|
||||
|
||||
fn parent_node(&self) -> Option<Self>;
|
||||
|
||||
fn first_child(&self) -> Option<Self>;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue