diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 1bfa0e6161e..d8a78f685fe 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -107,7 +107,8 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::mpsc::{Receiver, Sender, channel}; use std::thread; use style::animation::Animation; -use style::context::{QuirksMode, ReflowGoal, SharedStyleContext, ThreadLocalStyleContextCreationInfo}; +use style::context::{QuirksMode, ReflowGoal, SharedStyleContext}; +use style::context::{StyleSystemOptions, ThreadLocalStyleContextCreationInfo}; use style::data::StoredRestyleHint; use style::dom::{ShowSubtree, ShowSubtreeDataAndPrimaryValues, TElement, TNode}; use style::error_reporting::StdoutErrorReporter; @@ -516,6 +517,7 @@ impl LayoutThread { LayoutContext { style_context: SharedStyleContext { stylist: rw_data.stylist.clone(), + options: StyleSystemOptions::default(), guards: guards, running_animations: self.running_animations.clone(), expired_animations: self.expired_animations.clone(), diff --git a/components/style/context.rs b/components/style/context.rs index 17a49ad6040..1eadf4cb845 100644 --- a/components/style/context.rs +++ b/components/style/context.rs @@ -61,6 +61,42 @@ pub enum QuirksMode { NoQuirks, } +/// A global options structure for the style system. We use this instead of +/// opts to abstract across Gecko and Servo. +#[derive(Clone)] +pub struct StyleSystemOptions { + /// Whether the style sharing cache is disabled. + pub disable_style_sharing_cache: bool, + /// Whether we should dump statistics about the style system. + pub dump_style_statistics: bool, +} + +#[cfg(feature = "gecko")] +fn get_env(name: &str) -> bool { + match env::var(name) { + Ok(s) => !s.is_empty(), + Err(_) => false, + } +} + +impl Default for StyleSystemOptions { + #[cfg(feature = "servo")] + fn default() -> Self { + StyleSystemOptions { + disable_style_sharing_cache: opts::get().disable_share_style_cache, + dump_style_statistics: opts::get().style_sharing_stats, + } + } + + #[cfg(feature = "gecko")] + fn default() -> Self { + StyleSystemOptions { + disable_style_sharing_cache: get_env("DISABLE_STYLE_SHARING_CACHE"), + dump_style_statistics: get_env("DUMP_STYLE_STATISTICS"), + } + } +} + /// A shared style context. /// /// There's exactly one of these during a given restyle traversal, and it's @@ -69,6 +105,9 @@ pub struct SharedStyleContext<'a> { /// The CSS selector stylist. pub stylist: Arc, + /// Configuration options. + pub options: StyleSystemOptions, + /// Guards for pre-acquired locks pub guards: StylesheetGuards<'a>, @@ -175,35 +214,7 @@ impl fmt::Display for TraversalStatistics { } } -#[cfg(not(feature = "servo"))] -lazy_static! { - /// Whether to dump style statistics, computed statically. We use an environmental - /// variable so that this is easy to set for Gecko builds, and matches the - /// mechanism we use to dump statistics on the Gecko style system. - static ref DUMP_STYLE_STATISTICS: bool = { - match env::var("DUMP_STYLE_STATISTICS") { - Ok(s) => !s.is_empty(), - Err(_) => false, - } - }; -} - -#[cfg(feature = "servo")] -fn shall_stat_style_sharing() -> bool { - opts::get().style_sharing_stats -} - -#[cfg(not(feature = "servo"))] -fn shall_stat_style_sharing() -> bool { - *DUMP_STYLE_STATISTICS -} - impl TraversalStatistics { - /// Returns whether statistics dumping is enabled. - pub fn should_dump() -> bool { - shall_stat_style_sharing() - } - /// Computes the traversal time given the start time in seconds. pub fn finish(&mut self, traversal: &D, start: f64) where E: TElement, diff --git a/components/style/gecko/global_style_data.rs b/components/style/gecko/global_style_data.rs index 2653ad16b1f..857ff63d82a 100644 --- a/components/style/gecko/global_style_data.rs +++ b/components/style/gecko/global_style_data.rs @@ -4,6 +4,7 @@ //! Global style data +use context::StyleSystemOptions; use num_cpus; use rayon; use shared_lock::SharedRwLock; @@ -20,6 +21,9 @@ pub struct GlobalStyleData { /// Shared RWLock for CSSOM objects pub shared_lock: SharedRwLock, + + /// Global style system options determined by env vars. + pub options: StyleSystemOptions, } lazy_static! { @@ -45,6 +49,7 @@ lazy_static! { num_threads: num_threads, style_thread_pool: pool, shared_lock: SharedRwLock::new(), + options: StyleSystemOptions::default(), } }; } diff --git a/components/style/matching.rs b/components/style/matching.rs index 0e03d1e2ea5..b9f55588aab 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -25,7 +25,6 @@ use selector_parser::{PseudoElement, RestyleDamage, SelectorImpl}; use selectors::bloom::BloomFilter; use selectors::matching::{ElementSelectorFlags, StyleRelations}; use selectors::matching::AFFECTED_BY_PSEUDO_ELEMENTS; -#[cfg(feature = "servo")] use servo_config::opts; use sink::ForgetfulSink; use std::sync::Arc; use stylist::ApplicableDeclarationBlock; @@ -727,16 +726,6 @@ pub enum StyleSharingBehavior { Disallow, } -#[cfg(feature = "servo")] -fn is_share_style_cache_disabled() -> bool { - opts::get().disable_share_style_cache -} - -#[cfg(not(feature = "servo"))] -fn is_share_style_cache_disabled() -> bool { - false -} - /// The public API that elements expose for selector matching. pub trait MatchMethods : TElement { /// Performs selector matching and property cascading on an element and its eager pseudos. @@ -1033,7 +1022,7 @@ pub trait MatchMethods : TElement { context: &mut StyleContext, data: &mut AtomicRefMut) -> StyleSharingResult { - if is_share_style_cache_disabled() { + if context.shared.options.disable_style_sharing_cache { debug!("{:?} Cannot share style: style sharing cache disabled", self); return StyleSharingResult::CannotShare } diff --git a/components/style/parallel.rs b/components/style/parallel.rs index 2b39eb461d0..18b15e12a3a 100644 --- a/components/style/parallel.rs +++ b/components/style/parallel.rs @@ -44,7 +44,7 @@ pub fn traverse_dom(traversal: &D, where E: TElement, D: DomTraversal, { - let dump_stats = TraversalStatistics::should_dump(); + let dump_stats = traversal.shared_context().options.dump_style_statistics; let start_time = if dump_stats { Some(time::precise_time_s()) } else { None }; debug_assert!(traversal.is_parallel()); diff --git a/components/style/sequential.rs b/components/style/sequential.rs index 38ea519e474..f0b10d34d2a 100644 --- a/components/style/sequential.rs +++ b/components/style/sequential.rs @@ -6,7 +6,6 @@ #![deny(missing_docs)] -use context::TraversalStatistics; use dom::{TElement, TNode}; use std::borrow::BorrowMut; use std::collections::VecDeque; @@ -22,7 +21,7 @@ pub fn traverse_dom(traversal: &D, where E: TElement, D: DomTraversal, { - let dump_stats = TraversalStatistics::should_dump(); + let dump_stats = traversal.shared_context().options.dump_style_statistics; let start_time = if dump_stats { Some(time::precise_time_s()) } else { None }; debug_assert!(!traversal.is_parallel()); diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 9999dbff74d..ed24e8e68b6 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -22,7 +22,7 @@ use style::dom::{ShowSubtreeData, TElement, TNode}; use style::error_reporting::StdoutErrorReporter; use style::font_metrics::get_metrics_provider_for_product; use style::gecko::data::{PerDocumentStyleData, PerDocumentStyleDataImpl}; -use style::gecko::global_style_data::GLOBAL_STYLE_DATA; +use style::gecko::global_style_data::{GLOBAL_STYLE_DATA, GlobalStyleData}; use style::gecko::restyle_damage::GeckoRestyleDamage; use style::gecko::selector_parser::{SelectorImpl, PseudoElement}; use style::gecko::traversal::RecalcStyleOnly; @@ -143,7 +143,8 @@ unsafe fn dummy_url_data() -> &'static RefPtr { RefPtr::from_ptr_ref(&DUMMY_URL_DATA) } -fn create_shared_context<'a>(guard: &'a SharedRwLockReadGuard, +fn create_shared_context<'a>(global_style_data: &GlobalStyleData, + guard: &'a SharedRwLockReadGuard, per_doc_data: &PerDocumentStyleDataImpl, traversal_flags: TraversalFlags) -> SharedStyleContext<'a> { let local_context_data = @@ -151,6 +152,7 @@ fn create_shared_context<'a>(guard: &'a SharedRwLockReadGuard, SharedStyleContext { stylist: per_doc_data.stylist.clone(), + options: global_style_data.options.clone(), guards: StylesheetGuards::same(guard), running_animations: per_doc_data.running_animations.clone(), expired_animations: per_doc_data.expired_animations.clone(), @@ -187,7 +189,10 @@ fn traverse_subtree(element: GeckoElement, raw_data: RawServoStyleSetBorrowed, let global_style_data = &*GLOBAL_STYLE_DATA; let guard = global_style_data.shared_lock.read(); - let shared_style_context = create_shared_context(&guard, &per_doc_data, traversal_flags); + let shared_style_context = create_shared_context(&global_style_data, + &guard, + &per_doc_data, + traversal_flags); let traversal_driver = if global_style_data.style_thread_pool.is_none() { TraversalDriver::Sequential @@ -407,8 +412,10 @@ pub extern "C" fn Servo_StyleSet_GetBaseComputedValuesForElement(raw_data: RawSe let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow(); let global_style_data = &*GLOBAL_STYLE_DATA; let guard = global_style_data.shared_lock.read(); - let shared_context = &create_shared_context(&guard, &doc_data, TraversalFlags::empty()); - + let shared_context = &create_shared_context(&global_style_data, + &guard, + &doc_data, + TraversalFlags::empty()); let element = GeckoElement(element); let element_data = element.borrow_data().unwrap(); let styles = element_data.styles(); @@ -1691,7 +1698,10 @@ pub extern "C" fn Servo_ResolveStyleLazily(element: RawGeckoElementBorrowed, } // We don't have the style ready. Go ahead and compute it as necessary. - let shared = create_shared_context(&guard, &mut doc_data.borrow_mut(), TraversalFlags::empty()); + let shared = create_shared_context(&global_style_data, + &guard, + &mut doc_data.borrow_mut(), + TraversalFlags::empty()); let mut tlc = ThreadLocalStyleContext::new(&shared); let mut context = StyleContext { shared: &shared,