Skip to content

Commit 092e34b

Browse files
authored
Simply restyle damage macros (and convert them to be plain functions) (#222)
* Simplify restyle damage macros Signed-off-by: Nico Burns <[email protected]> * Don't diff custom properties if we've already set damage anyway Signed-off-by: Nico Burns <[email protected]> --------- Signed-off-by: Nico Burns <[email protected]>
1 parent 0d8dd54 commit 092e34b

File tree

2 files changed

+71
-78
lines changed

2 files changed

+71
-78
lines changed

style/properties/properties.mako.rs

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2964,28 +2964,15 @@ const_assert!(std::mem::size_of::<longhands::${longhand.ident}::SpecifiedValue>(
29642964

29652965
% if engine == "servo":
29662966
% for effect_name in ["repaint", "recalculate_overflow", "rebuild_stacking_context", "rebuild_box"]:
2967-
macro_rules! restyle_damage_${effect_name} {
2968-
($old: ident, $new: ident, $damage: ident, [ $($effect:expr),* ]) => ({
2969-
restyle_damage_${effect_name}!($old, $new, $damage, [$($effect),*], false)
2970-
});
2971-
($old: ident, $new: ident, $damage: ident, [ $($effect:expr),* ], $extra:expr) => ({
2972-
if
2973-
% for style_struct in data.active_style_structs():
2974-
% for longhand in style_struct.longhands:
2975-
% if effect_name in longhand.servo_restyle_damage.split() and not longhand.logical:
2976-
$old.get_${style_struct.name_lower}().${longhand.ident} !=
2977-
$new.get_${style_struct.name_lower}().${longhand.ident} ||
2978-
% endif
2979-
% endfor
2980-
% endfor
2981-
2982-
$extra || false {
2983-
$damage.insert($($effect)|*);
2984-
true
2985-
} else {
2986-
false
2987-
}
2988-
});
2989-
}
2967+
pub(crate) fn restyle_damage_${effect_name} (old: &ComputedValues, new: &ComputedValues) -> bool {
2968+
% for style_struct in data.active_style_structs():
2969+
% for longhand in style_struct.longhands:
2970+
% if effect_name in longhand.servo_restyle_damage.split() and not longhand.logical:
2971+
old.get_${style_struct.name_lower}().${longhand.ident} != new.get_${style_struct.name_lower}().${longhand.ident} ||
2972+
% endif
2973+
% endfor
2974+
% endfor
2975+
false
2976+
}
29902977
% endfor
29912978
% endif

style/servo/restyle_damage.rs

Lines changed: 61 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ use crate::computed_values::mix_blend_mode::T as MixBlendMode;
1212
use crate::computed_values::transform_style::T as TransformStyle;
1313
use crate::dom::TElement;
1414
use crate::matching::{StyleChange, StyleDifference};
15-
use crate::properties::{style_structs, ComputedValues};
15+
use crate::properties::{
16+
restyle_damage_rebuild_box, restyle_damage_rebuild_stacking_context,
17+
restyle_damage_recalculate_overflow, restyle_damage_repaint, style_structs, ComputedValues,
18+
};
1619
use crate::values::computed::basic_shape::ClipPath;
1720
use crate::values::computed::Perspective;
1821
use crate::values::generics::transform::{GenericRotate, GenericScale, GenericTranslate};
@@ -125,64 +128,67 @@ impl fmt::Display for ServoRestyleDamage {
125128
}
126129
}
127130

131+
fn augmented_restyle_damage_rebuild_box(old: &ComputedValues, new: &ComputedValues) -> bool {
132+
let old_box = old.get_box();
133+
let new_box = new.get_box();
134+
restyle_damage_rebuild_box(old, new)
135+
|| old_box.original_display != new_box.original_display
136+
|| old_box.has_transform_or_perspective() != new_box.has_transform_or_perspective()
137+
|| old.get_effects().filter.0.is_empty() != new.get_effects().filter.0.is_empty()
138+
}
139+
140+
fn augmented_restyle_damage_rebuild_stacking_context(
141+
old: &ComputedValues,
142+
new: &ComputedValues,
143+
) -> bool {
144+
restyle_damage_rebuild_stacking_context(old, new)
145+
|| old.guarantees_stacking_context() != new.guarantees_stacking_context()
146+
}
128147
fn compute_damage(old: &ComputedValues, new: &ComputedValues) -> ServoRestyleDamage {
129148
let mut damage = ServoRestyleDamage::empty();
130149

131-
let has_transform_or_perspective_style = |style_box: &style_structs::Box| {
132-
!style_box.transform.0.is_empty() ||
133-
style_box.scale != GenericScale::None ||
134-
style_box.rotate != GenericRotate::None ||
135-
style_box.translate != GenericTranslate::None ||
136-
style_box.perspective != Perspective::None ||
137-
style_box.transform_style == TransformStyle::Preserve3d
138-
};
139-
140-
let rebuild_box_extra = || {
141-
let old_box = old.get_box();
142-
let new_box = new.get_box();
143-
old_box.original_display != new_box.original_display ||
144-
has_transform_or_perspective_style(old_box) !=
145-
has_transform_or_perspective_style(new_box) ||
146-
old.get_effects().filter.0.is_empty() != new.get_effects().filter.0.is_empty()
147-
};
148-
149-
// Some properties establish a stacking context when they are set to a non-initial value.
150-
// In that case, the damage is only set to `ServoRestyleDamage::REPAINT` because we don't
151-
// need to rebuild stacking contexts when the style changes between different non-initial
152-
// values. This function checks whether any of these properties is set to a value that
153-
// guarantees a stacking context, so that we only do the work when this changes.
154-
// Note that it's still possible to establish a stacking context when this returns false.
155-
let guarantees_stacking_context = |style: &ComputedValues| {
156-
style.get_effects().opacity != 1.0 ||
157-
old.get_effects().mix_blend_mode != MixBlendMode::Normal ||
158-
old.get_svg().clip_path != ClipPath::None ||
159-
style.get_box().isolation == Isolation::Isolate
160-
};
161-
162-
// This uses short-circuiting boolean OR for its side effects and ignores the result.
163-
let _ = restyle_damage_rebuild_box!(
164-
old,
165-
new,
166-
damage,
167-
[ServoRestyleDamage::RELAYOUT],
168-
rebuild_box_extra()
169-
) || restyle_damage_recalculate_overflow!(
170-
old,
171-
new,
172-
damage,
173-
[ServoRestyleDamage::RECALCULATE_OVERFLOW]
174-
) || restyle_damage_rebuild_stacking_context!(
175-
old,
176-
new,
177-
damage,
178-
[ServoRestyleDamage::REBUILD_STACKING_CONTEXT],
179-
guarantees_stacking_context(old) != guarantees_stacking_context(new)
180-
) || restyle_damage_repaint!(old, new, damage, [ServoRestyleDamage::REPAINT]);
181-
182-
// Paint worklets may depend on custom properties,
183-
// so if they have changed we should repaint.
184-
if !old.custom_properties_equal(new) {
150+
// Damage flags higher up the if-else chain imply damage flags lower down the if-else chain,
151+
// so we can skip the diffing process for later flags if an earlier flag is true
152+
if augmented_restyle_damage_rebuild_box(old, new) {
153+
damage.insert(ServoRestyleDamage::RELAYOUT)
154+
} else if restyle_damage_recalculate_overflow(old, new) {
155+
damage.insert(ServoRestyleDamage::RECALCULATE_OVERFLOW)
156+
} else if augmented_restyle_damage_rebuild_stacking_context(old, new) {
157+
damage.insert(ServoRestyleDamage::REBUILD_STACKING_CONTEXT);
158+
} else if restyle_damage_repaint(old, new) {
185159
damage.insert(ServoRestyleDamage::REPAINT);
186160
}
161+
// Paint worklets may depend on custom properties, so if they have changed we should repaint.
162+
else if !old.custom_properties_equal(new) {
163+
damage.insert(ServoRestyleDamage::REPAINT);
164+
}
165+
187166
damage
188167
}
168+
169+
impl ComputedValues {
170+
/// Some properties establish a stacking context when they are set to a non-initial value.
171+
/// In that case, the damage is only set to `ServoRestyleDamage::REPAINT` because we don't
172+
/// need to rebuild stacking contexts when the style changes between different non-initial
173+
/// values. This function checks whether any of these properties is set to a value that
174+
/// guarantees a stacking context, so that we only do the work when this changes.
175+
/// Note that it's still possible to establish a stacking context when this returns false.
176+
pub fn guarantees_stacking_context(&self) -> bool {
177+
self.get_effects().opacity != 1.0
178+
|| self.get_effects().mix_blend_mode != MixBlendMode::Normal
179+
|| self.get_svg().clip_path != ClipPath::None
180+
|| self.get_box().isolation == Isolation::Isolate
181+
}
182+
}
183+
184+
impl style_structs::Box {
185+
/// Whether there is a non-default transform or perspective style set
186+
pub fn has_transform_or_perspective(&self) -> bool {
187+
!self.transform.0.is_empty()
188+
|| self.scale != GenericScale::None
189+
|| self.rotate != GenericRotate::None
190+
|| self.translate != GenericTranslate::None
191+
|| self.perspective != Perspective::None
192+
|| self.transform_style == TransformStyle::Preserve3d
193+
}
194+
}

0 commit comments

Comments
 (0)