Skip to content

Commit 4fe9a9a

Browse files
committed
Associated damage type WIP
Signed-off-by: Nico Burns <[email protected]>
1 parent a58aed7 commit 4fe9a9a

File tree

10 files changed

+112
-228
lines changed

10 files changed

+112
-228
lines changed

style/context.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::animation::DocumentAnimationSet;
99
use crate::bloom::StyleBloom;
1010
use crate::computed_value_flags::ComputedValueFlags;
1111
use crate::data::{EagerPseudoStyles, ElementData};
12-
use crate::dom::{SendElement, TElement};
12+
use crate::dom::{SendElement, TElement, TRestyleDamage};
1313
#[cfg(feature = "gecko")]
1414
use crate::gecko_bindings::structs;
1515
use crate::parallel::{STACK_SAFETY_MARGIN_KB, STYLE_THREAD_STACK_SIZE_KB};
@@ -263,7 +263,7 @@ pub struct ElementCascadeInputs {
263263
impl ElementCascadeInputs {
264264
/// Construct inputs from previous cascade results, if any.
265265
#[inline]
266-
pub fn new_from_element_data(data: &ElementData) -> Self {
266+
pub fn new_from_element_data<D: TRestyleDamage>(data: &ElementData<D>) -> Self {
267267
debug_assert!(data.has_styles());
268268
ElementCascadeInputs {
269269
primary: CascadeInputs::new_from_style(data.styles.primary()),

style/data.rs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
77
use crate::computed_value_flags::ComputedValueFlags;
88
use crate::context::{SharedStyleContext, StackLimitChecker};
9-
use crate::dom::TElement;
9+
use crate::dom::{TElement, TRestyleDamage};
1010
use crate::invalidation::element::invalidator::InvalidationResult;
1111
use crate::invalidation::element::restyle_hints::RestyleHint;
1212
use crate::properties::ComputedValues;
13-
use crate::selector_parser::{PseudoElement, RestyleDamage, EAGER_PSEUDO_COUNT};
13+
use crate::selector_parser::{PseudoElement, EAGER_PSEUDO_COUNT};
1414
use crate::style_resolver::{PrimaryStyle, ResolvedElementStyles, ResolvedStyle};
1515
#[cfg(feature = "gecko")]
1616
use malloc_size_of::MallocSizeOfOps;
@@ -249,7 +249,7 @@ impl fmt::Debug for ElementStyles {
249249
/// inside of layout data, which itself hangs directly off the Element. In
250250
/// both cases, it is wrapped inside an AtomicRefCell to ensure thread safety.
251251
#[derive(Debug, Default)]
252-
pub struct ElementData {
252+
pub struct ElementData<RestyleDamage: TRestyleDamage> {
253253
/// The styles for the element and its pseudo-elements.
254254
pub styles: ElementStyles,
255255

@@ -266,7 +266,14 @@ pub struct ElementData {
266266
}
267267

268268
// There's one of these per rendered elements so it better be small.
269-
size_of_test!(ElementData, 24);
269+
// mod element_data_test {
270+
// use crate::dom::TRestyleDamage;
271+
// use super::ElementData;
272+
// #[derive(Debug, Copy, Clone, Default)]
273+
// struct SizeOfRestyleDamage(u32);
274+
// impl TRestyleDamage for SizeOfRestyleDamage {}
275+
// size_of_test!(ElementData<SizeOfRestyleDamage>, 24);
276+
// }
270277

271278
/// The kind of restyle that a single element should do.
272279
#[derive(Debug)]
@@ -282,11 +289,11 @@ pub enum RestyleKind {
282289
CascadeOnly,
283290
}
284291

285-
impl ElementData {
292+
impl<RestyleDamage: TRestyleDamage> ElementData<RestyleDamage> {
286293
/// Invalidates style for this element, its descendants, and later siblings,
287294
/// based on the snapshot of the element that we took when attributes or
288295
/// state changed.
289-
pub fn invalidate_style_if_needed<'a, E: TElement>(
296+
pub fn invalidate_style_if_needed<'a, E: TElement<RestyleDamage = RestyleDamage>>(
290297
&mut self,
291298
element: E,
292299
shared_context: &SharedStyleContext,
@@ -389,8 +396,8 @@ impl ElementData {
389396
return None;
390397
}
391398

392-
let needs_to_match_self = hint.intersects(RestyleHint::RESTYLE_SELF) ||
393-
(hint.intersects(RestyleHint::RESTYLE_SELF_IF_PSEUDO) && style.is_pseudo_style());
399+
let needs_to_match_self = hint.intersects(RestyleHint::RESTYLE_SELF)
400+
|| (hint.intersects(RestyleHint::RESTYLE_SELF_IF_PSEUDO) && style.is_pseudo_style());
394401
if needs_to_match_self {
395402
return Some(RestyleKind::MatchAndCascade);
396403
}
@@ -405,9 +412,9 @@ impl ElementData {
405412
));
406413
}
407414

408-
let needs_to_recascade_self = hint.intersects(RestyleHint::RECASCADE_SELF) ||
409-
(hint.intersects(RestyleHint::RECASCADE_SELF_IF_INHERIT_RESET_STYLE) &&
410-
style
415+
let needs_to_recascade_self = hint.intersects(RestyleHint::RECASCADE_SELF)
416+
|| (hint.intersects(RestyleHint::RECASCADE_SELF_IF_INHERIT_RESET_STYLE)
417+
&& style
411418
.flags
412419
.contains(ComputedValueFlags::INHERITS_RESET_STYLE));
413420
if needs_to_recascade_self {
@@ -447,9 +454,9 @@ impl ElementData {
447454
));
448455
}
449456

450-
let needs_to_recascade_self = hint.intersects(RestyleHint::RECASCADE_SELF) ||
451-
(hint.intersects(RestyleHint::RECASCADE_SELF_IF_INHERIT_RESET_STYLE) &&
452-
style
457+
let needs_to_recascade_self = hint.intersects(RestyleHint::RECASCADE_SELF)
458+
|| (hint.intersects(RestyleHint::RECASCADE_SELF_IF_INHERIT_RESET_STYLE)
459+
&& style
453460
.flags
454461
.contains(ComputedValueFlags::INHERITS_RESET_STYLE));
455462
if needs_to_recascade_self {
@@ -471,7 +478,7 @@ impl ElementData {
471478
/// Drops restyle flags and damage from the element.
472479
#[inline]
473480
pub fn clear_restyle_flags_and_damage(&mut self) {
474-
self.damage = RestyleDamage::empty();
481+
self.damage.clear();
475482
self.flags.remove(ElementDataFlags::WAS_RESTYLED);
476483
}
477484

@@ -521,8 +528,8 @@ impl ElementData {
521528
/// we need for style sharing, the latter does not.
522529
pub fn safe_for_cousin_sharing(&self) -> bool {
523530
if self.flags.intersects(
524-
ElementDataFlags::TRAVERSED_WITHOUT_STYLING |
525-
ElementDataFlags::PRIMARY_STYLE_REUSED_VIA_RULE_NODE,
531+
ElementDataFlags::TRAVERSED_WITHOUT_STYLING
532+
| ElementDataFlags::PRIMARY_STYLE_REUSED_VIA_RULE_NODE,
526533
) {
527534
return false;
528535
}

style/dom.rs

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::context::UpdateAnimationsTasks;
1414
use crate::data::ElementData;
1515
use crate::media_queries::Device;
1616
use crate::properties::{AnimationDeclarations, ComputedValues, PropertyDeclarationBlock};
17-
use crate::selector_parser::{AttrValue, Lang, PseudoElement, RestyleDamage, SelectorImpl};
17+
use crate::selector_parser::{AttrValue, Lang, PseudoElement, SelectorImpl};
1818
use crate::shared_lock::{Locked, SharedRwLock};
1919
use crate::stylesheets::scope_rule::ImplicitScopeRoot;
2020
use crate::stylist::CascadeData;
@@ -30,7 +30,7 @@ use servo_arc::{Arc, ArcBorrow};
3030
use std::fmt;
3131
use std::fmt::Debug;
3232
use std::hash::Hash;
33-
use std::ops::Deref;
33+
use std::ops::{BitOrAssign, Deref};
3434

3535
pub use style_traits::dom::OpaqueNode;
3636

@@ -383,13 +383,51 @@ pub trait TShadowRoot: Sized + Copy + Clone + Debug + PartialEq {
383383
}
384384
}
385385

386+
/// Represents restyle damage (whether to repaint, relayout, etc based on changed styles)
387+
///
388+
/// Stylo is mostly agnostic to this type which is used by the embedder. This trait represents the
389+
/// minimal interface that Stylo does need to the type.
390+
pub trait TRestyleDamage: Copy + Clone + Default + Debug + BitOrAssign {
391+
/// Clear/reset all damage flags
392+
fn clear(&mut self);
393+
/// Whether the damage is empty ("no styles changed")
394+
fn is_empty(&self) -> bool;
395+
/// Mark the element as needing it's (eager) pseudo-elements rebuilt
396+
fn set_rebuild_pseudos(&mut self);
397+
}
398+
399+
/// Represents the result of comparing an element's old and new style.
400+
#[derive(Debug)]
401+
pub struct StyleDifference<RestyleDamage: TRestyleDamage> {
402+
/// The resulting damage.
403+
pub damage: RestyleDamage,
404+
405+
/// Whether any styles changed.
406+
pub change: StyleChange,
407+
}
408+
409+
/// Represents whether or not the style of an element has changed.
410+
#[derive(Clone, Copy, Debug)]
411+
pub enum StyleChange {
412+
/// The style hasn't changed.
413+
Unchanged,
414+
/// The style has changed.
415+
Changed {
416+
/// Whether only reset structs changed.
417+
reset_only: bool,
418+
},
419+
}
420+
386421
/// The element trait, the main abstraction the style crate acts over.
387422
pub trait TElement:
388423
Eq + PartialEq + Debug + Hash + Sized + Copy + Clone + SelectorsElement<Impl = SelectorImpl>
389424
{
390425
/// The concrete node type.
391426
type ConcreteNode: TNode<ConcreteElement = Self>;
392427

428+
/// The type representing restyle damage flags
429+
type RestyleDamage: TRestyleDamage;
430+
393431
/// A concrete children iterator type in order to iterate over the `Node`s.
394432
///
395433
/// TODO(emilio): We should eventually replace this with the `impl Trait`
@@ -583,7 +621,7 @@ pub trait TElement:
583621

584622
/// Returns whether the element's styles are up-to-date after traversal
585623
/// (i.e. in post traversal).
586-
fn has_current_styles(&self, data: &ElementData) -> bool {
624+
fn has_current_styles(&self, data: &ElementData<Self::RestyleDamage>) -> bool {
587625
if self.has_snapshot() && !self.handled_snapshot() {
588626
return false;
589627
}
@@ -670,7 +708,7 @@ pub trait TElement:
670708
///
671709
/// Unsafe because it can race to allocate and leak if not used with
672710
/// exclusive access to the element.
673-
unsafe fn ensure_data(&self) -> AtomicRefMut<ElementData>;
711+
unsafe fn ensure_data(&self) -> AtomicRefMut<ElementData<Self::RestyleDamage>>;
674712

675713
/// Clears the element data reference, if any.
676714
///
@@ -681,10 +719,10 @@ pub trait TElement:
681719
fn has_data(&self) -> bool;
682720

683721
/// Immutably borrows the ElementData.
684-
fn borrow_data(&self) -> Option<AtomicRef<ElementData>>;
722+
fn borrow_data(&self) -> Option<AtomicRef<ElementData<Self::RestyleDamage>>>;
685723

686724
/// Mutably borrows the ElementData.
687-
fn mutate_data(&self) -> Option<AtomicRefMut<ElementData>>;
725+
fn mutate_data(&self) -> Option<AtomicRefMut<ElementData<Self::RestyleDamage>>>;
688726

689727
/// Whether we should skip any root- or item-based display property
690728
/// blockification on this element. (This function exists so that Gecko
@@ -909,9 +947,20 @@ pub trait TElement:
909947
None
910948
}
911949

912-
/// Compute the damage incurred by the change from the `_old` to `_new`.
913-
fn compute_layout_damage(_old: &ComputedValues, _new: &ComputedValues) -> RestyleDamage {
914-
Default::default()
950+
/// Given the old and new style of this element, and whether it's a
951+
/// pseudo-element, compute the restyle damage used to determine which
952+
/// kind of layout or painting operations we'll need.
953+
fn compute_style_difference(
954+
&self,
955+
_old: &ComputedValues,
956+
_new: &ComputedValues,
957+
pseudo: Option<&PseudoElement>,
958+
) -> StyleDifference<Self::RestyleDamage> {
959+
debug_assert!(pseudo.map_or(true, |p| p.is_eager()));
960+
StyleDifference {
961+
damage: Default::default(),
962+
change: StyleChange::Unchanged,
963+
}
915964
}
916965
}
917966

style/invalidation/element/relative_selector.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,7 @@ pub struct RelativeSelectorOuterInvalidationProcessor<'a, 'b, E: TElement> {
10201020
/// The current shadow host, if any.
10211021
pub host: Option<OpaqueElement>,
10221022
/// Data for the element being invalidated.
1023-
pub data: &'a mut ElementData,
1023+
pub data: &'a mut ElementData<E::RestyleDamage>,
10241024
/// Dependency to be processed.
10251025
pub dependency: &'b Dependency,
10261026
/// Matching context to use for invalidation.

style/invalidation/element/state_and_attributes.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
88
use crate::context::SharedStyleContext;
99
use crate::data::ElementData;
10-
use crate::dom::{TElement, TNode};
10+
use crate::dom::{TElement, TNode, TRestyleDamage};
1111
use crate::invalidation::element::element_wrapper::{ElementSnapshot, ElementWrapper};
1212
use crate::invalidation::element::invalidation_map::*;
1313
use crate::invalidation::element::invalidator::{
@@ -56,7 +56,7 @@ where
5656
pub struct StateAndAttrInvalidationProcessor<'a, 'b: 'a, E: TElement> {
5757
shared_context: &'a SharedStyleContext<'b>,
5858
element: E,
59-
data: &'a mut ElementData,
59+
data: &'a mut ElementData<E::RestyleDamage>,
6060
matching_context: MatchingContext<'a, E::Impl>,
6161
traversal_map: SiblingTraversalMap<E>,
6262
}
@@ -66,7 +66,7 @@ impl<'a, 'b: 'a, E: TElement + 'b> StateAndAttrInvalidationProcessor<'a, 'b, E>
6666
pub fn new(
6767
shared_context: &'a SharedStyleContext<'b>,
6868
element: E,
69-
data: &'a mut ElementData,
69+
data: &'a mut ElementData<E::RestyleDamage>,
7070
selector_caches: &'a mut SelectorCaches,
7171
) -> Self {
7272
let matching_context = MatchingContext::new_for_visited(
@@ -125,7 +125,7 @@ where
125125

126126
/// Whether we should process the descendants of a given element for style
127127
/// invalidation.
128-
pub fn should_process_descendants(data: &ElementData) -> bool {
128+
pub fn should_process_descendants<D: TRestyleDamage>(data: &ElementData<D>) -> bool {
129129
!data.styles.is_display_none() && !data.hint.contains(RestyleHint::RESTYLE_DESCENDANTS)
130130
}
131131

style/matching.rs

Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ use crate::context::CascadeInputs;
1313
use crate::context::{ElementCascadeInputs, QuirksMode};
1414
use crate::context::{SharedStyleContext, StyleContext};
1515
use crate::data::{ElementData, ElementStyles};
16-
use crate::dom::TElement;
16+
use crate::dom::{TElement, TRestyleDamage, StyleChange};
1717
#[cfg(feature = "servo")]
1818
use crate::dom::TNode;
1919
use crate::invalidation::element::restyle_hints::RestyleHint;
2020
use crate::properties::longhands::display::computed_value::T as Display;
2121
use crate::properties::ComputedValues;
2222
use crate::properties::PropertyDeclarationBlock;
2323
use crate::rule_tree::{CascadeLevel, StrongRuleNode};
24-
use crate::selector_parser::{PseudoElement, RestyleDamage};
24+
use crate::selector_parser::{PseudoElement};
2525
use crate::shared_lock::Locked;
2626
use crate::style_resolver::StyleResolverForElement;
2727
use crate::style_resolver::{PseudoElementResolution, ResolvedElementStyles};
@@ -30,28 +30,6 @@ use crate::stylist::RuleInclusion;
3030
use crate::traversal_flags::TraversalFlags;
3131
use servo_arc::{Arc, ArcBorrow};
3232

33-
/// Represents the result of comparing an element's old and new style.
34-
#[derive(Debug)]
35-
pub struct StyleDifference {
36-
/// The resulting damage.
37-
pub damage: RestyleDamage,
38-
39-
/// Whether any styles changed.
40-
pub change: StyleChange,
41-
}
42-
43-
/// Represents whether or not the style of an element has changed.
44-
#[derive(Clone, Copy, Debug)]
45-
pub enum StyleChange {
46-
/// The style hasn't changed.
47-
Unchanged,
48-
/// The style has changed.
49-
Changed {
50-
/// Whether only reset structs changed.
51-
reset_only: bool,
52-
},
53-
}
54-
5533
/// Whether or not newly computed values for an element need to be cascaded to
5634
/// children (or children might need to be re-matched, e.g., for container
5735
/// queries).
@@ -778,7 +756,7 @@ trait PrivateMatchMethods: TElement {
778756
fn accumulate_damage_for(
779757
&self,
780758
shared_context: &SharedStyleContext,
781-
damage: &mut RestyleDamage,
759+
damage: &mut Self::RestyleDamage,
782760
old_values: &ComputedValues,
783761
new_values: &ComputedValues,
784762
pseudo: Option<&PseudoElement>,
@@ -937,7 +915,7 @@ pub trait MatchMethods: TElement {
937915
fn finish_restyle(
938916
&self,
939917
context: &mut StyleContext<Self>,
940-
data: &mut ElementData,
918+
data: &mut ElementData<Self::RestyleDamage>,
941919
mut new_styles: ResolvedElementStyles,
942920
important_rules_changed: bool,
943921
) -> ChildRestyleRequirement {
@@ -1120,7 +1098,7 @@ pub trait MatchMethods: TElement {
11201098
let old_pseudo_should_exist =
11211099
old.as_ref().map_or(false, |s| pseudo.should_exist(s));
11221100
if new_pseudo_should_exist != old_pseudo_should_exist {
1123-
data.damage |= RestyleDamage::reconstruct();
1101+
data.damage.set_rebuild_pseudos();
11241102
return restyle_requirement;
11251103
}
11261104
},
@@ -1155,19 +1133,6 @@ pub trait MatchMethods: TElement {
11551133
);
11561134
result
11571135
}
1158-
1159-
/// Given the old and new style of this element, and whether it's a
1160-
/// pseudo-element, compute the restyle damage used to determine which
1161-
/// kind of layout or painting operations we'll need.
1162-
fn compute_style_difference(
1163-
&self,
1164-
old_values: &ComputedValues,
1165-
new_values: &ComputedValues,
1166-
pseudo: Option<&PseudoElement>,
1167-
) -> StyleDifference {
1168-
debug_assert!(pseudo.map_or(true, |p| p.is_eager()));
1169-
RestyleDamage::compute_style_difference::<Self>(old_values, new_values)
1170-
}
11711136
}
11721137

11731138
impl<E: TElement> MatchMethods for E {}

0 commit comments

Comments
 (0)