diff options
author | J. Ryan Stinnett <jryans@gmail.com> | 2017-05-11 16:30:26 -0500 |
---|---|---|
committer | J. Ryan Stinnett <jryans@gmail.com> | 2017-05-24 18:08:19 -0500 |
commit | f12af6c8d606f63fbba32e1dc3580f38604da24a (patch) | |
tree | 632578ef53c8be5fee4db5911a5e04d09684da11 | |
parent | 47c8574c54eb4616ff506acf085e560764f2c828 (diff) | |
download | servo-f12af6c8d606f63fbba32e1dc3580f38604da24a.tar.gz servo-f12af6c8d606f63fbba32e1dc3580f38604da24a.zip |
Filter visited cascade to only visited dependent properties
Speed up the visited cascade by only running it for the properties that are
actually visited dependent. (These are only the properties where the separate
set of visited styles is even read at all, so running the rest is wasted work.)
MozReview-Commit-ID: 5B7wYtuH974
-rw-r--r-- | components/style/matching.rs | 14 | ||||
-rw-r--r-- | components/style/properties/properties.mako.rs | 78 |
2 files changed, 74 insertions, 18 deletions
diff --git a/components/style/matching.rs b/components/style/matching.rs index aa992fc3ce3..5c68946abee 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -13,7 +13,8 @@ use data::{ComputedStyle, ElementData, RestyleData}; use dom::{TElement, TNode}; use font_metrics::FontMetricsProvider; use log::LogLevel::Trace; -use properties::{AnimationRules, CascadeFlags, ComputedValues, SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, cascade}; +use properties::{AnimationRules, CascadeFlags, ComputedValues}; +use properties::{SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, VISITED_DEPENDENT_ONLY, cascade}; use properties::longhands::display::computed_value as display; use restyle_hints::{RESTYLE_CSS_ANIMATIONS, RESTYLE_CSS_TRANSITIONS, RestyleReplacements}; use restyle_hints::{RESTYLE_STYLE_ATTRIBUTE, RESTYLE_SMIL}; @@ -188,7 +189,7 @@ impl CascadeVisitedMode { *self == CascadeVisitedMode::Unvisited } - /// Returns whether animations should be processed based on the cascade + /// Returns whether animations should be processed based on the cascade /// mode. At the moment, it appears we don't need to support animating /// visited styles. fn should_process_animations(&self) -> bool { @@ -202,6 +203,12 @@ impl CascadeVisitedMode { fn should_accumulate_damage(&self) -> bool { *self == CascadeVisitedMode::Unvisited } + + /// Returns whether the cascade should filter to only visited dependent + /// properties based on the cascade mode. + fn visited_dependent_only(&self) -> bool { + *self == CascadeVisitedMode::Visited + } } trait PrivateMatchMethods: TElement { @@ -246,6 +253,9 @@ trait PrivateMatchMethods: TElement { if self.skip_root_and_item_based_display_fixup() { cascade_flags.insert(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP) } + if cascade_visited.visited_dependent_only() { + cascade_flags.insert(VISITED_DEPENDENT_ONLY); + } // Grab the inherited values. let parent_el; diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 9e7e37f06ce..92429d554dd 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -576,6 +576,57 @@ impl LonghandId { % endfor } } + + /// Only a few properties are allowed to depend on the visited state of + /// links. When cascading visited styles, we can save time by only + /// processing these properties. + fn is_visited_dependent(&self) -> bool { + matches!(*self, + % if product == "gecko": + LonghandId::ColumnRuleColor | + LonghandId::TextEmphasisColor | + LonghandId::WebkitTextFillColor | + LonghandId::WebkitTextStrokeColor | + LonghandId::TextDecorationColor | + LonghandId::Fill | + LonghandId::Stroke | + LonghandId::CaretColor | + % endif + LonghandId::Color | + LonghandId::BackgroundColor | + LonghandId::BorderTopColor | + LonghandId::BorderRightColor | + LonghandId::BorderBottomColor | + LonghandId::BorderLeftColor | + LonghandId::OutlineColor + ) + } + + /// The computed value of some properties depends on the (sometimes + /// computed) value of *other* properties. + /// + /// So we classify properties into "early" and "other", such that the only + /// dependencies can be from "other" to "early". + /// + /// Unfortunately, it’s not easy to check that this classification is + /// correct. + fn is_early_property(&self) -> bool { + matches!(*self, + % if product == 'gecko': + LonghandId::TextOrientation | + LonghandId::AnimationName | + LonghandId::TransitionProperty | + LonghandId::XLang | + LonghandId::MozScriptLevel | + % endif + LonghandId::FontSize | + LonghandId::FontFamily | + LonghandId::Color | + LonghandId::TextDecorationLine | + LonghandId::WritingMode | + LonghandId::Direction + ) + } } /// An identifier for a given shorthand property. @@ -2403,6 +2454,8 @@ bitflags! { /// Whether to skip any root element and flex/grid item display style /// fixup. const SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP = 0x02, + /// Whether to only cascade properties that are visited dependent. + const VISITED_DEPENDENT_ONLY = 0x04, } } @@ -2582,6 +2635,14 @@ pub fn apply_declarations<'a, F, I>(device: &Device, PropertyDeclarationId::Custom(..) => continue, }; + // Only a few properties are allowed to depend on the visited state + // of links. When cascading visited styles, we can save time by + // only processing these properties. + if flags.contains(VISITED_DEPENDENT_ONLY) && + !longhand_id.is_visited_dependent() { + continue + } + // The computed value of some properties depends on the // (sometimes computed) value of *other* properties. // @@ -2593,26 +2654,11 @@ pub fn apply_declarations<'a, F, I>(device: &Device, // // Unfortunately, it’s not easy to check that this // classification is correct. - let is_early_property = matches!(longhand_id, - LonghandId::FontSize | - LonghandId::FontFamily | - LonghandId::Color | - LonghandId::TextDecorationLine | - LonghandId::WritingMode | - LonghandId::Direction - % if product == 'gecko': - | LonghandId::TextOrientation - | LonghandId::AnimationName - | LonghandId::TransitionProperty - | LonghandId::XLang - | LonghandId::MozScriptLevel - % endif - ); if % if category_to_cascade_now == "early": ! % endif - is_early_property + longhand_id.is_early_property() { continue } |