Skip to content

Commit

Permalink
style: Split style sheet invalidations per-origin.
Browse files Browse the repository at this point in the history
  • Loading branch information
heycam committed Aug 13, 2017
1 parent 321643a commit f9d1a0e
Showing 1 changed file with 53 additions and 40 deletions.
93 changes: 53 additions & 40 deletions components/style/stylesheet_set.rs
Expand Up @@ -8,7 +8,7 @@ use dom::TElement;
use invalidation::stylesheets::StylesheetInvalidationSet;
use shared_lock::SharedRwLockReadGuard;
use std::slice;
use stylesheets::StylesheetInDocument;
use stylesheets::{PerOrigin, StylesheetInDocument};
use stylist::Stylist;

/// Entry for a StylesheetSet. We don't bother creating a constructor, because
Expand Down Expand Up @@ -49,14 +49,11 @@ where
/// include recursive `@import` rules.
entries: Vec<StylesheetSetEntry<S>>,

/// Whether the entries list above has changed since the last restyle.
dirty: bool,
/// Per-origin stylesheet invalidation data.
invalidation_data: PerOrigin<InvalidationData>,

/// Has author style been disabled?
author_style_disabled: bool,

/// The style invalidations that we still haven't processed.
invalidations: StylesheetInvalidationSet,
}

impl<S> StylesheetSet<S>
Expand All @@ -67,9 +64,8 @@ where
pub fn new() -> Self {
StylesheetSet {
entries: vec![],
dirty: false,
invalidation_data: Default::default(),
author_style_disabled: false,
invalidations: StylesheetInvalidationSet::new(),
}
}

Expand All @@ -83,6 +79,18 @@ where
self.entries.retain(|entry| entry.sheet != *sheet);
}

fn collect_invalidations_for(
&mut self,
stylist: &Stylist,
sheet: &S,
guard: &SharedRwLockReadGuard,
) {
let origin = sheet.contents(guard).origin;
let data = self.invalidation_data.borrow_mut_for_origin(&origin);
data.invalidations.collect_invalidations_for(stylist, sheet, guard);
data.dirty = true;
}

/// Appends a new stylesheet to the current set.
pub fn append_stylesheet(
&mut self,
Expand All @@ -92,12 +100,7 @@ where
) {
debug!("StylesheetSet::append_stylesheet");
self.remove_stylesheet_if_present(&sheet);
self.invalidations.collect_invalidations_for(
stylist,
&sheet,
guard
);
self.dirty = true;
self.collect_invalidations_for(stylist, &sheet, guard);
self.entries.push(StylesheetSetEntry { sheet });
}

Expand All @@ -110,13 +113,8 @@ where
) {
debug!("StylesheetSet::prepend_stylesheet");
self.remove_stylesheet_if_present(&sheet);
self.invalidations.collect_invalidations_for(
stylist,
&sheet,
guard
);
self.collect_invalidations_for(stylist, &sheet, guard);
self.entries.insert(0, StylesheetSetEntry { sheet });
self.dirty = true;
}

/// Insert a given stylesheet before another stylesheet in the document.
Expand All @@ -132,13 +130,8 @@ where
let index = self.entries.iter().position(|entry| {
entry.sheet == before_sheet
}).expect("`before_sheet` stylesheet not found");
self.invalidations.collect_invalidations_for(
stylist,
&sheet,
guard
);
self.collect_invalidations_for(stylist, &sheet, guard);
self.entries.insert(index, StylesheetSetEntry { sheet });
self.dirty = true;
}

/// Remove a given stylesheet from the set.
Expand All @@ -150,12 +143,7 @@ where
) {
debug!("StylesheetSet::remove_stylesheet");
self.remove_stylesheet_if_present(&sheet);
self.dirty = true;
self.invalidations.collect_invalidations_for(
stylist,
&sheet,
guard
);
self.collect_invalidations_for(stylist, &sheet, guard);
}

/// Notes that the author style has been disabled for this document.
Expand All @@ -165,13 +153,15 @@ where
return;
}
self.author_style_disabled = disabled;
self.dirty = true;
self.invalidations.invalidate_fully();
self.invalidation_data.author.invalidations.invalidate_fully();
self.invalidation_data.author.dirty = true;
}

/// Returns whether the given set has changed from the last flush.
pub fn has_changed(&self) -> bool {
self.dirty
self.invalidation_data
.iter_origins()
.any(|(d, _)| d.dirty)
}

/// Flush the current set, unmarking it as dirty, and returns an iterator
Expand All @@ -184,10 +174,12 @@ where
E: TElement,
{
debug!("StylesheetSet::flush");
debug_assert!(self.dirty);
debug_assert!(self.has_changed());

self.dirty = false;
self.invalidations.flush(document_element);
for data in self.invalidation_data.iter_mut_origins() {
data.0.invalidations.flush(document_element);
data.0.dirty = false;
}

self.iter()
}
Expand All @@ -202,7 +194,28 @@ where
///
/// FIXME(emilio): Make this more granular.
pub fn force_dirty(&mut self) {
self.dirty = true;
self.invalidations.invalidate_fully();
for data in self.invalidation_data.iter_mut_origins() {
data.0.invalidations.invalidate_fully();
data.0.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
/// has changed since the last restyle.
dirty: bool,
}

impl Default for InvalidationData {
fn default() -> Self {
InvalidationData {
invalidations: StylesheetInvalidationSet::new(),
dirty: false,
}
}
}

0 comments on commit f9d1a0e

Please sign in to comment.