style: Only flush stylesheet invalidations for origins that have changed. draft
authorCameron McCormack <cam@mcc.id.au>
Sat, 12 Aug 2017 17:23:56 +0800
changeset 645507 93cbf10578e9ac3a436604ae4f7bc82a5b3adc9f
parent 645506 cb1ed81739efa1579cd80e82ff0676abe227c7e6
child 645508 5d96bbf58c53e389b93bbe90e4ccdc87db55b8e7
push id73769
push userbmo:cam@mcc.id.au
push dateSun, 13 Aug 2017 04:04:30 +0000
milestone57.0a1
style: Only flush stylesheet invalidations for origins that have changed. MozReview-Commit-ID: Fqh9IQgdfG0
servo/components/style/gecko/data.rs
servo/components/style/stylesheet_set.rs
--- a/servo/components/style/gecko/data.rs
+++ b/servo/components/style/gecko/data.rs
@@ -158,17 +158,17 @@ impl PerDocumentStyleDataImpl {
                                 document_element: Option<E>)
         where E: TElement,
     {
         if !self.stylesheets.has_changed() {
             return;
         }
 
         let author_style_disabled = self.stylesheets.author_style_disabled();
-        self.stylist.clear();
+
         let iter = self.stylesheets.flush(document_element);
         self.stylist.rebuild(
             iter,
             &StylesheetGuards::same(guard),
             /* ua_sheets = */ None,
             /* stylesheets_changed = */ true,
             author_style_disabled,
             &mut self.extra_style_data,
--- a/servo/components/style/stylesheet_set.rs
+++ b/servo/components/style/stylesheet_set.rs
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! A centralized set of stylesheets for a document.
 
 use dom::TElement;
 use invalidation::stylesheets::StylesheetInvalidationSet;
 use shared_lock::SharedRwLockReadGuard;
 use std::slice;
-use stylesheets::{PerOrigin, StylesheetInDocument};
+use stylesheets::{Origin, PerOrigin, StylesheetInDocument};
 use stylist::Stylist;
 
 /// Entry for a StylesheetSet. We don't bother creating a constructor, because
 /// there's no sensible defaults for the member variables.
 pub struct StylesheetSetEntry<S>
 where
     S: StylesheetInDocument + PartialEq + 'static,
 {
@@ -163,47 +163,57 @@ where
             .iter_origins()
             .any(|(d, _)| d.dirty)
     }
 
     /// Flush the current set, unmarking it as dirty, and returns an iterator
     /// over the new stylesheet list.
     pub fn flush<E>(
         &mut self,
-        document_element: Option<E>
+        document_element: Option<E>,
     ) -> StylesheetIterator<S>
     where
         E: TElement,
     {
         debug!("StylesheetSet::flush");
         debug_assert!(self.has_changed());
 
-        for data in self.invalidation_data.iter_mut_origins() {
-            data.0.invalidations.flush(document_element);
-            data.0.dirty = false;
+        for (data, _) in self.invalidation_data.iter_mut_origins() {
+            if data.dirty {
+                data.invalidations.flush(document_element);
+                data.dirty = false;
+            }
         }
 
         self.iter()
     }
 
     /// Returns an iterator over the current list of stylesheets.
     pub fn iter(&self) -> StylesheetIterator<S> {
         StylesheetIterator(self.entries.iter())
     }
 
     /// Mark the stylesheets as dirty, because something external may have
     /// invalidated it.
     ///
     /// FIXME(emilio): Make this more granular.
     pub fn force_dirty(&mut self) {
-        for data in self.invalidation_data.iter_mut_origins() {
-            data.0.invalidations.invalidate_fully();
-            data.0.dirty = true;
+        for (data, _) in self.invalidation_data.iter_mut_origins() {
+            data.invalidations.invalidate_fully();
+            data.dirty = true;
         }
     }
+
+    /// Mark the stylesheets for the specified origin as dirty, because
+    /// something external may have invalidated it.
+    pub fn force_dirty_origin(&mut self, origin: &Origin) {
+        let data = self.invalidation_data.borrow_mut_for_origin(origin);
+        data.invalidations.invalidate_fully();
+        data.dirty = true;
+    }
 }
 
 struct InvalidationData {
     /// The stylesheet invalidations for this origin that we still haven't
     /// processed.
     invalidations: StylesheetInvalidationSet,
 
     /// Whether the sheets for this origin in the `StylesheetSet`'s entry list