From cf7adcdca5b05dfbdd50cd8b5764bda6b156e952 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 18 Nov 2016 17:13:30 +0100 Subject: [PATCH] Make Stylesheet.dirty_on_viewport_size_change an AtomicBool --- components/layout_thread/lib.rs | 2 +- components/script/dom/htmlmetaelement.rs | 3 ++- components/style/stylesheets.rs | 25 +++++++++++++++++++++--- tests/unit/style/stylesheets.rs | 3 ++- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 52bcba2bc45..73a6e6c9865 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -1055,7 +1055,7 @@ impl LayoutThread { .send(ConstellationMsg::ViewportConstrained(self.id, constraints)) .unwrap(); } - if data.document_stylesheets.iter().any(|sheet| sheet.dirty_on_viewport_size_change) { + if data.document_stylesheets.iter().any(|sheet| sheet.dirty_on_viewport_size_change()) { let mut iter = node.traverse_preorder(); let mut next = iter.next(); diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs index c948dde4ab8..2a71965305d 100644 --- a/components/script/dom/htmlmetaelement.rs +++ b/components/script/dom/htmlmetaelement.rs @@ -21,6 +21,7 @@ use html5ever_atoms::LocalName; use parking_lot::RwLock; use std::ascii::AsciiExt; use std::sync::Arc; +use std::sync::atomic::AtomicBool; use style::attr::AttrValue; use style::str::HTML_SPACE_CHARACTERS; use style::stylesheets::{Stylesheet, CssRule, Origin}; @@ -101,7 +102,7 @@ impl HTMLMetaElement { media: Default::default(), // Viewport constraints are always recomputed on resize; they don't need to // force all styles to be recomputed. - dirty_on_viewport_size_change: false, + dirty_on_viewport_size_change: AtomicBool::new(false), })); let doc = document_from_node(self); doc.invalidate_stylesheets(); diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index 6b417231961..6fdf6eb63b9 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -22,6 +22,7 @@ use servo_url::ServoUrl; use std::cell::Cell; use std::fmt; use std::sync::Arc; +use std::sync::atomic::{AtomicBool, Ordering}; use style_traits::ToCss; use viewport::ViewportRule; @@ -59,7 +60,7 @@ pub struct Stylesheet { /// List of media associated with the Stylesheet. pub media: Arc>, pub origin: Origin, - pub dirty_on_viewport_size_change: bool, + pub dirty_on_viewport_size_change: AtomicBool, } @@ -215,11 +216,29 @@ impl Stylesheet { origin: origin, rules: rules.into(), media: Arc::new(RwLock::new(media)), - dirty_on_viewport_size_change: - input.seen_viewport_percentages(), + dirty_on_viewport_size_change: AtomicBool::new(input.seen_viewport_percentages()), } } + pub fn dirty_on_viewport_size_change(&self) -> bool { + self.dirty_on_viewport_size_change.load(Ordering::SeqCst) + } + + /// When CSSOM inserts a rule or declaration into this stylesheet, it needs to call this method + /// with the return value of `cssparser::Parser::seen_viewport_percentages`. + /// + /// FIXME: actually make these calls + /// + /// Note: when *removing* a rule or declaration that contains a viewport percentage, + /// to keep the flag accurate we’d need to iterator through the rest of the stylesheet to + /// check for *other* such values. + /// + /// Instead, we conservatively assume there might be some. + /// Restyling will some some more work than necessary, but give correct results. + pub fn inserted_has_viewport_percentages(&self, has_viewport_percentages: bool) { + self.dirty_on_viewport_size_change.fetch_or(has_viewport_percentages, Ordering::SeqCst); + } + /// Returns whether the style-sheet applies for the current device depending /// on the associated MediaList. /// diff --git a/tests/unit/style/stylesheets.rs b/tests/unit/style/stylesheets.rs index 7cfcc961895..b61c0a0f9a1 100644 --- a/tests/unit/style/stylesheets.rs +++ b/tests/unit/style/stylesheets.rs @@ -12,6 +12,7 @@ use servo_url::ServoUrl; use std::borrow::ToOwned; use std::sync::Arc; use std::sync::Mutex; +use std::sync::atomic::AtomicBool; use style::error_reporting::ParseErrorReporter; use style::keyframes::{Keyframe, KeyframeSelector, KeyframePercentage}; use style::parser::ParserContextExtraData; @@ -55,7 +56,7 @@ fn test_parse_stylesheet() { let expected = Stylesheet { origin: Origin::UserAgent, media: Default::default(), - dirty_on_viewport_size_change: false, + dirty_on_viewport_size_change: AtomicBool::new(false), rules: vec![ CssRule::Namespace(Arc::new(RwLock::new(NamespaceRule { prefix: None,