From 1cc44bd06536f0b9eaa0ae05a30448040155ec65 Mon Sep 17 00:00:00 2001 From: Oriol Brufau Date: Wed, 17 May 2023 00:44:00 +0200 Subject: [PATCH] style: Will-change should only create stacking contexts / containing blocks / etc if the property it'd change would apply As per https://drafts.csswg.org/css-will-change/#will-change. > If any non-initial value of a property would cause the element to > generate a containing block for absolutely positioned elements, > specifying that property in will-change must cause the element to > generate a containing block for absolutely positioned elements. But in this case the transform property wouldn't apply to the element so there's no reason to create a stacking-context. Differential Revision: https://phabricator.services.mozilla.com/D114121 --- .../style/properties/longhands/box.mako.rs | 15 ++--- .../properties/longhands/effects.mako.rs | 5 +- .../properties/longhands/position.mako.rs | 1 - .../style/properties/longhands/svg.mako.rs | 2 - .../style/properties/properties.mako.rs | 20 ++---- components/style/values/specified/box.rs | 64 +++++++++++-------- 6 files changed, 49 insertions(+), 58 deletions(-) diff --git a/components/style/properties/longhands/box.mako.rs b/components/style/properties/longhands/box.mako.rs index 73a2ec87065..f2d0234a918 100644 --- a/components/style/properties/longhands/box.mako.rs +++ b/components/style/properties/longhands/box.mako.rs @@ -48,7 +48,6 @@ ${helpers.single_keyword( engines="gecko servo-2013 servo-2020" animation_value_type="discrete" gecko_enum_prefix="StylePositionProperty" - flags="CREATES_STACKING_CONTEXT ABSPOS_CB" spec="https://drafts.csswg.org/css-position/#position-property" servo_restyle_damage="rebuild_and_reflow" > @@ -330,7 +329,7 @@ ${helpers.predefined_type( engines="gecko servo-2013 servo-2020", extra_prefixes=transform_extra_prefixes, animation_value_type="ComputedValue", - flags="CREATES_STACKING_CONTEXT FIXPOS_CB CAN_ANIMATE_ON_COMPOSITOR", + flags="CAN_ANIMATE_ON_COMPOSITOR", spec="https://drafts.csswg.org/css-transforms/#propdef-transform", servo_restyle_damage="reflow_out_of_flow", )} @@ -342,7 +341,7 @@ ${helpers.predefined_type( engines="gecko servo-2013", animation_value_type="ComputedValue", boxed=True, - flags="CREATES_STACKING_CONTEXT FIXPOS_CB CAN_ANIMATE_ON_COMPOSITOR", + flags="CAN_ANIMATE_ON_COMPOSITOR", gecko_pref="layout.css.individual-transform.enabled", spec="https://drafts.csswg.org/css-transforms-2/#individual-transforms", servo_restyle_damage = "reflow_out_of_flow", @@ -355,7 +354,7 @@ ${helpers.predefined_type( engines="gecko servo-2013", animation_value_type="ComputedValue", boxed=True, - flags="CREATES_STACKING_CONTEXT FIXPOS_CB CAN_ANIMATE_ON_COMPOSITOR", + flags="CAN_ANIMATE_ON_COMPOSITOR", gecko_pref="layout.css.individual-transform.enabled", spec="https://drafts.csswg.org/css-transforms-2/#individual-transforms", servo_restyle_damage = "reflow_out_of_flow", @@ -368,7 +367,7 @@ ${helpers.predefined_type( engines="gecko servo-2013", animation_value_type="ComputedValue", boxed=True, - flags="CREATES_STACKING_CONTEXT FIXPOS_CB CAN_ANIMATE_ON_COMPOSITOR", + flags="CAN_ANIMATE_ON_COMPOSITOR", gecko_pref="layout.css.individual-transform.enabled", spec="https://drafts.csswg.org/css-transforms-2/#individual-transforms", servo_restyle_damage="reflow_out_of_flow", @@ -382,7 +381,7 @@ ${helpers.predefined_type( engines="gecko", animation_value_type="ComputedValue", gecko_pref="layout.css.motion-path.enabled", - flags="CREATES_STACKING_CONTEXT FIXPOS_CB CAN_ANIMATE_ON_COMPOSITOR", + flags="CAN_ANIMATE_ON_COMPOSITOR", spec="https://drafts.fxtf.org/motion-1/#offset-path-property", servo_restyle_damage="reflow_out_of_flow" )} @@ -477,7 +476,6 @@ ${helpers.single_keyword( "auto isolate", engines="gecko", spec="https://drafts.fxtf.org/compositing/#isolation", - flags="CREATES_STACKING_CONTEXT", gecko_enum_prefix="StyleIsolation", animation_value_type="discrete", )} @@ -530,7 +528,6 @@ ${helpers.predefined_type( gecko_ffi_name="mChildPerspective", spec="https://drafts.csswg.org/css-transforms/#perspective", extra_prefixes=transform_extra_prefixes, - flags="CREATES_STACKING_CONTEXT FIXPOS_CB", animation_value_type="AnimatedPerspective", servo_restyle_damage = "reflow_out_of_flow", )} @@ -574,7 +571,6 @@ ${helpers.predefined_type( engines="gecko servo-2013 servo-2020", spec="https://drafts.csswg.org/css-transforms-2/#transform-style-property", extra_prefixes=transform_extra_prefixes, - flags="CREATES_STACKING_CONTEXT FIXPOS_CB", animation_value_type="discrete", servo_restyle_damage = "reflow_out_of_flow", )} @@ -598,7 +594,6 @@ ${helpers.predefined_type( "specified::Contain::empty()", engines="gecko", animation_value_type="none", - flags="CREATES_STACKING_CONTEXT FIXPOS_CB", spec="https://drafts.csswg.org/css-contain/#contain-property", )} diff --git a/components/style/properties/longhands/effects.mako.rs b/components/style/properties/longhands/effects.mako.rs index 00ede146cd4..5470c74d47c 100644 --- a/components/style/properties/longhands/effects.mako.rs +++ b/components/style/properties/longhands/effects.mako.rs @@ -13,7 +13,7 @@ ${helpers.predefined_type( "1.0", engines="gecko servo-2013 servo-2020", animation_value_type="ComputedValue", - flags="CREATES_STACKING_CONTEXT CAN_ANIMATE_ON_COMPOSITOR", + flags="CAN_ANIMATE_ON_COMPOSITOR", spec="https://drafts.csswg.org/css-color/#transparency", servo_restyle_damage = "reflow_out_of_flow", )} @@ -56,7 +56,6 @@ ${helpers.predefined_type( animation_value_type="AnimatedFilterList", vector_animation_type="with_zero", extra_prefixes="webkit", - flags="CREATES_STACKING_CONTEXT FIXPOS_CB", spec="https://drafts.fxtf.org/filters/#propdef-filter", )} @@ -71,7 +70,6 @@ ${helpers.predefined_type( separator="Space", animation_value_type="AnimatedFilterList", vector_animation_type="with_zero", - flags="CREATES_STACKING_CONTEXT FIXPOS_CB", gecko_pref="layout.css.backdrop-filter.enabled", spec="https://drafts.fxtf.org/filter-effects-2/#propdef-backdrop-filter", )} @@ -84,6 +82,5 @@ ${helpers.single_keyword( engines="gecko servo-2013 servo-2020", gecko_enum_prefix="StyleBlend", animation_value_type="discrete", - flags="CREATES_STACKING_CONTEXT", spec="https://drafts.fxtf.org/compositing/#propdef-mix-blend-mode", )} diff --git a/components/style/properties/longhands/position.mako.rs b/components/style/properties/longhands/position.mako.rs index df118faed1a..1795bde7e5f 100644 --- a/components/style/properties/longhands/position.mako.rs +++ b/components/style/properties/longhands/position.mako.rs @@ -60,7 +60,6 @@ ${helpers.predefined_type( "computed::ZIndex::auto()", engines="gecko servo-2013 servo-2020", spec="https://www.w3.org/TR/CSS2/visuren.html#z-index", - flags="CREATES_STACKING_CONTEXT", animation_value_type="ComputedValue", )} diff --git a/components/style/properties/longhands/svg.mako.rs b/components/style/properties/longhands/svg.mako.rs index a09f3e7b656..f6128693582 100644 --- a/components/style/properties/longhands/svg.mako.rs +++ b/components/style/properties/longhands/svg.mako.rs @@ -81,7 +81,6 @@ ${helpers.predefined_type( "generics::basic_shape::ClipPath::None", engines="gecko", animation_value_type="basic_shape::ClipPath", - flags="CREATES_STACKING_CONTEXT", spec="https://drafts.fxtf.org/css-masking/#propdef-clip-path", )} @@ -183,7 +182,6 @@ ${helpers.predefined_type( vector=True, extra_prefixes="webkit", animation_value_type="discrete", - flags="CREATES_STACKING_CONTEXT", )} ${helpers.predefined_type( diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index ea3e043ea49..99d283da46c 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -1068,28 +1068,20 @@ impl CSSWideKeyword { bitflags! { /// A set of flags for properties. pub struct PropertyFlags: u16 { - /// This property requires a stacking context. - const CREATES_STACKING_CONTEXT = 1 << 0; - /// This property has values that can establish a containing block for - /// fixed positioned and absolutely positioned elements. - const FIXPOS_CB = 1 << 1; - /// This property has values that can establish a containing block for - /// absolutely positioned elements. - const ABSPOS_CB = 1 << 2; /// This longhand property applies to ::first-letter. - const APPLIES_TO_FIRST_LETTER = 1 << 3; + const APPLIES_TO_FIRST_LETTER = 1 << 1; /// This longhand property applies to ::first-line. - const APPLIES_TO_FIRST_LINE = 1 << 4; + const APPLIES_TO_FIRST_LINE = 1 << 2; /// This longhand property applies to ::placeholder. - const APPLIES_TO_PLACEHOLDER = 1 << 5; + const APPLIES_TO_PLACEHOLDER = 1 << 3; /// This longhand property applies to ::cue. - const APPLIES_TO_CUE = 1 << 6; + const APPLIES_TO_CUE = 1 << 4; /// This longhand property applies to ::marker. - const APPLIES_TO_MARKER = 1 << 7; + const APPLIES_TO_MARKER = 1 << 5; /// This property is a legacy shorthand. /// /// https://drafts.csswg.org/css-cascade/#legacy-shorthand - const IS_LEGACY_SHORTHAND = 1 << 8; + const IS_LEGACY_SHORTHAND = 1 << 6; /* The following flags are currently not used in Rust code, they * only need to be listed in corresponding properties so that diff --git a/components/style/values/specified/box.rs b/components/style/values/specified/box.rs index 3039a990ff9..06a4e1ea869 100644 --- a/components/style/values/specified/box.rs +++ b/components/style/values/specified/box.rs @@ -6,7 +6,7 @@ use crate::custom_properties::Name as CustomPropertyName; use crate::parser::{Parse, ParserContext}; -use crate::properties::{LonghandId, PropertyDeclarationId, PropertyFlags}; +use crate::properties::{LonghandId, PropertyDeclarationId}; use crate::properties::{PropertyId, ShorthandId}; use crate::values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount; use crate::values::generics::box_::Perspective as GenericPerspective; @@ -1086,44 +1086,54 @@ bitflags! { /// The change bits that we care about. #[derive(Default, MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)] #[repr(C)] - pub struct WillChangeBits: u8 { - /// Whether the stacking context will change. - const STACKING_CONTEXT = 1 << 0; - /// Whether `transform` will change. + pub struct WillChangeBits: u16 { + /// Whether a property which can create a stacking context **on any + /// box** will change. + const STACKING_CONTEXT_UNCONDITIONAL = 1 << 0; + /// Whether `transform` or related properties will change. const TRANSFORM = 1 << 1; /// Whether `scroll-position` will change. const SCROLL = 1 << 2; + /// Whether `contain` will change. + const CONTAIN = 1 << 3; /// Whether `opacity` will change. - const OPACITY = 1 << 3; - /// Fixed pos containing block. - const FIXPOS_CB = 1 << 4; - /// Abs pos containing block. - const ABSPOS_CB = 1 << 5; + const OPACITY = 1 << 4; + /// Whether `perspective` will change. + const PERSPECTIVE = 1 << 5; + /// Whether `z-index` will change. + const Z_INDEX = 1 << 6; + /// Whether any property which creates a containing block for non-svg + /// text frames will change. + const FIXPOS_CB_NON_SVG = 1 << 7; + /// Whether the position property will change. + const POSITION = 1 << 8; } } fn change_bits_for_longhand(longhand: LonghandId) -> WillChangeBits { - let mut flags = match longhand { + match longhand { LonghandId::Opacity => WillChangeBits::OPACITY, - LonghandId::Transform => WillChangeBits::TRANSFORM, - #[cfg(feature = "gecko")] - LonghandId::Translate | LonghandId::Rotate | LonghandId::Scale | LonghandId::OffsetPath => { - WillChangeBits::TRANSFORM + LonghandId::Contain => WillChangeBits::CONTAIN, + LonghandId::Perspective => WillChangeBits::PERSPECTIVE, + LonghandId::Position => { + WillChangeBits::STACKING_CONTEXT_UNCONDITIONAL | WillChangeBits::POSITION }, + LonghandId::ZIndex => WillChangeBits::Z_INDEX, + LonghandId::Transform | + LonghandId::TransformStyle | + LonghandId::Translate | + LonghandId::Rotate | + LonghandId::Scale | + LonghandId::OffsetPath => WillChangeBits::TRANSFORM, + LonghandId::BackdropFilter | LonghandId::Filter => { + WillChangeBits::STACKING_CONTEXT_UNCONDITIONAL | WillChangeBits::FIXPOS_CB_NON_SVG + }, + LonghandId::MixBlendMode | + LonghandId::Isolation | + LonghandId::MaskImage | + LonghandId::ClipPath => WillChangeBits::STACKING_CONTEXT_UNCONDITIONAL, _ => WillChangeBits::empty(), - }; - - let property_flags = longhand.flags(); - if property_flags.contains(PropertyFlags::CREATES_STACKING_CONTEXT) { - flags |= WillChangeBits::STACKING_CONTEXT; } - if property_flags.contains(PropertyFlags::FIXPOS_CB) { - flags |= WillChangeBits::FIXPOS_CB; - } - if property_flags.contains(PropertyFlags::ABSPOS_CB) { - flags |= WillChangeBits::ABSPOS_CB; - } - flags } fn change_bits_for_maybe_property(ident: &str, context: &ParserContext) -> WillChangeBits {