Bug 1728754 - Plumb layer order through ApplicableDeclarationBlock, and make it have an effect. r=boris
authorEmilio Cobos Álvarez <emilio@crisal.io>
Mon, 06 Sep 2021 10:02:07 +0000
changeset 591086 84c423dca87e1ec8af1611003cccc83f4f43263e
parent 591085 a6a1582d09cb88ba50315cd5a74de05471b422f1
child 591087 377d8e27a15545a70f2427f13710d85886cd3de7
push id38767
push userccozmuta@mozilla.com
push dateMon, 06 Sep 2021 21:42:43 +0000
treeherdermozilla-central@aca153106940 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersboris
bugs1728754, 1728722, 1727276
milestone93.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1728754 - Plumb layer order through ApplicableDeclarationBlock, and make it have an effect. r=boris Same, I want to land this separately to see if it affects micro-benchmarks. If so, we might want to pack the layer order _somewhere_ (though in this case I'm not sure where, tbh). With this, layer rules should have an effect on the page. There are a few things missing before being able to enable them: * Fix nested layer order in some cases (when parent layers are declared out of order, see the previous commit mentioning this). * Some kind of OM representation, perhaps. * Tests of course, which are coming in bug 1728722 and bug 1727276. But this should be enough to allow playing with them. Depends on D124337 Differential Revision: https://phabricator.services.mozilla.com/D124338
servo/components/style/applicable_declarations.rs
servo/components/style/rule_collector.rs
servo/components/style/stylist.rs
servo/ports/geckolib/tests/size_of.rs
--- a/servo/components/style/applicable_declarations.rs
+++ b/servo/components/style/applicable_declarations.rs
@@ -64,42 +64,46 @@ impl ApplicableDeclarationBits {
 #[derive(Clone, Debug, MallocSizeOf, PartialEq)]
 pub struct ApplicableDeclarationBlock {
     /// The style source, either a style rule, or a property declaration block.
     #[ignore_malloc_size_of = "Arc"]
     pub source: StyleSource,
     /// The bits containing the source order, cascade level, and shadow cascade
     /// order.
     bits: ApplicableDeclarationBits,
-    /// The specificity of the selector this block is represented by.
+    /// The specificity of the selector.
     pub specificity: u32,
+    /// The layer order of the selector.
+    pub layer_order: u32,
 }
 
 impl ApplicableDeclarationBlock {
     /// Constructs an applicable declaration block from a given property
     /// declaration block and importance.
     #[inline]
     pub fn from_declarations(
         declarations: Arc<Locked<PropertyDeclarationBlock>>,
         level: CascadeLevel,
     ) -> Self {
         ApplicableDeclarationBlock {
             source: StyleSource::from_declarations(declarations),
             bits: ApplicableDeclarationBits::new(0, level),
             specificity: 0,
+            layer_order: 0,
         }
     }
 
     /// Constructs an applicable declaration block from the given components
     #[inline]
-    pub fn new(source: StyleSource, order: u32, level: CascadeLevel, specificity: u32) -> Self {
+    pub fn new(source: StyleSource, source_order: u32, level: CascadeLevel, specificity: u32, layer_order: u32) -> Self {
         ApplicableDeclarationBlock {
             source,
-            bits: ApplicableDeclarationBits::new(order, level),
+            bits: ApplicableDeclarationBits::new(source_order, level),
             specificity,
+            layer_order,
         }
     }
 
     /// Returns the source order of the block.
     #[inline]
     pub fn source_order(&self) -> u32 {
         self.bits.source_order()
     }
--- a/servo/components/style/rule_collector.rs
+++ b/servo/components/style/rule_collector.rs
@@ -143,17 +143,17 @@ where
         debug_assert!(!self.in_sort_scope, "Nested sorting makes no sense");
         let start = self.rules.len();
         self.in_sort_scope = true;
         let old_host = self.context.current_host.take();
         self.context.current_host = host.map(|e| e.opaque());
         f(self);
         if start != self.rules.len() {
             self.rules[start..]
-                .sort_unstable_by_key(|block| (block.specificity, block.source_order()));
+                .sort_unstable_by_key(|block| (block.layer_order, block.specificity, block.source_order()));
         }
         self.context.current_host = old_host;
         self.in_sort_scope = false;
     }
 
     #[inline]
     fn in_shadow_tree(&mut self, host: E, f: impl FnOnce(&mut Self)) {
         self.in_tree(Some(host), f);
--- a/servo/components/style/stylist.rs
+++ b/servo/components/style/stylist.rs
@@ -2196,16 +2196,17 @@ impl CascadeData {
                                     .as_mut()
                                     .expect("Expected precomputed declarations for the UA level")
                                     .get_or_insert_with(pseudo, Vec::new)
                                     .push(ApplicableDeclarationBlock::new(
                                         StyleSource::from_rule(locked.clone()),
                                         self.rules_source_order,
                                         CascadeLevel::UANormal,
                                         selector.specificity(),
+                                        current_layer_order,
                                     ));
                                 continue;
                             }
                             if pseudo.is_unknown_webkit_pseudo_element() {
                                 continue;
                             }
                         }
 
@@ -2698,17 +2699,17 @@ impl Rule {
 
     /// Turns this rule into an `ApplicableDeclarationBlock` for the given
     /// cascade level.
     pub fn to_applicable_declaration_block(
         &self,
         level: CascadeLevel,
     ) -> ApplicableDeclarationBlock {
         let source = StyleSource::from_rule(self.style_rule.clone());
-        ApplicableDeclarationBlock::new(source, self.source_order, level, self.specificity())
+        ApplicableDeclarationBlock::new(source, self.source_order, level, self.specificity(), self.layer_order)
     }
 
     /// Creates a new Rule.
     pub fn new(
         selector: Selector<SelectorImpl>,
         hashes: AncestorHashes,
         style_rule: Arc<Locked<StyleRule>>,
         source_order: u32,
--- a/servo/ports/geckolib/tests/size_of.rs
+++ b/servo/ports/geckolib/tests/size_of.rs
@@ -45,17 +45,17 @@ size_of_test!(
     test_size_of_property_declaration,
     style::properties::PropertyDeclaration,
     32
 );
 
 size_of_test!(
     test_size_of_application_declaration_block,
     ApplicableDeclarationBlock,
-    16
+    24
 );
 
 #[test]
 fn test_size_of_rule_node() {
     assert_eq!(RULE_NODE_SIZE, 80, "RuleNode size changed");
 }
 
 // This is huge, but we allocate it on the stack and then never move it,