diff options
Diffstat (limited to 'components/layout/context.rs')
-rw-r--r-- | components/layout/context.rs | 96 |
1 files changed, 56 insertions, 40 deletions
diff --git a/components/layout/context.rs b/components/layout/context.rs index cb5b9efb0ef..e2d1fa7831c 100644 --- a/components/layout/context.rs +++ b/components/layout/context.rs @@ -17,57 +17,74 @@ use net_traits::image::base::Image; use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread, ImageResponse, ImageState}; use net_traits::image_cache_thread::{ImageOrMetadataAvailable, UsePlaceholder}; use parking_lot::RwLock; +use servo_config::opts; use servo_url::ServoUrl; use std::cell::{RefCell, RefMut}; use std::collections::HashMap; use std::hash::BuildHasherDefault; use std::rc::Rc; use std::sync::{Arc, Mutex}; -use style::context::{LocalStyleContext, StyleContext, SharedStyleContext}; -use util::opts; +use style::context::{SharedStyleContext, ThreadLocalStyleContext}; +use style::dom::TElement; -struct LocalLayoutContext { - style_context: LocalStyleContext, +/// TLS data scoped to the traversal. +pub struct ScopedThreadLocalLayoutContext<E: TElement> { + pub style_context: ThreadLocalStyleContext<E>, +} + +impl<E: TElement> ScopedThreadLocalLayoutContext<E> { + pub fn new(shared: &SharedLayoutContext) -> Self { + ScopedThreadLocalLayoutContext { + style_context: ThreadLocalStyleContext::new(&shared.style_context), + } + } +} + +/// TLS data that persists across traversals. +pub struct PersistentThreadLocalLayoutContext { + // FontContext uses Rc all over the place and so isn't Send, which means we + // can't use ScopedTLS for it. There's also no reason to scope it to the + // traversal, and performance is probably better if we don't. + pub font_context: RefCell<FontContext>, +} - font_context: RefCell<FontContext>, +impl PersistentThreadLocalLayoutContext { + pub fn new(shared: &SharedLayoutContext) -> Rc<Self> { + let font_cache_thread = shared.font_cache_thread.lock().unwrap().clone(); + Rc::new(PersistentThreadLocalLayoutContext { + font_context: RefCell::new(FontContext::new(font_cache_thread)), + }) + } } -impl HeapSizeOf for LocalLayoutContext { - // FIXME(njn): measure other fields eventually. +impl HeapSizeOf for PersistentThreadLocalLayoutContext { fn heap_size_of_children(&self) -> usize { self.font_context.heap_size_of_children() } } -thread_local!(static LOCAL_CONTEXT_KEY: RefCell<Option<Rc<LocalLayoutContext>>> = RefCell::new(None)); +thread_local!(static LOCAL_CONTEXT_KEY: RefCell<Option<Rc<PersistentThreadLocalLayoutContext>>> = RefCell::new(None)); -pub fn heap_size_of_local_context() -> usize { - LOCAL_CONTEXT_KEY.with(|r| { - r.borrow().clone().map_or(0, |context| context.heap_size_of_children()) - }) -} - -// Keep this implementation in sync with the one in ports/geckolib/traversal.rs. -fn create_or_get_local_context(shared_layout_context: &SharedLayoutContext) - -> Rc<LocalLayoutContext> { +fn create_or_get_persistent_context(shared: &SharedLayoutContext) + -> Rc<PersistentThreadLocalLayoutContext> { LOCAL_CONTEXT_KEY.with(|r| { let mut r = r.borrow_mut(); if let Some(context) = r.clone() { context } else { - let font_cache_thread = shared_layout_context.font_cache_thread.lock().unwrap().clone(); - let local_style_data = shared_layout_context.style_context.local_context_creation_data.lock().unwrap(); - - let context = Rc::new(LocalLayoutContext { - style_context: LocalStyleContext::new(&local_style_data), - font_context: RefCell::new(FontContext::new(font_cache_thread)), - }); + let context = PersistentThreadLocalLayoutContext::new(shared); *r = Some(context.clone()); context } }) } +pub fn heap_size_of_persistent_local_context() -> usize { + LOCAL_CONTEXT_KEY.with(|r| { + r.borrow().clone().map_or(0, |context| context.heap_size_of_children()) + }) +} + /// Layout information shared among all workers. This must be thread-safe. pub struct SharedLayoutContext { /// Bits shared by the layout and style system. @@ -90,27 +107,26 @@ pub struct SharedLayoutContext { pub struct LayoutContext<'a> { pub shared: &'a SharedLayoutContext, - cached_local_layout_context: Rc<LocalLayoutContext>, + pub persistent: Rc<PersistentThreadLocalLayoutContext>, } -impl<'a> StyleContext<'a> for LayoutContext<'a> { - fn shared_context(&self) -> &'a SharedStyleContext { - &self.shared.style_context - } - - fn local_context(&self) -> &LocalStyleContext { - &self.cached_local_layout_context.style_context +impl<'a> LayoutContext<'a> { + pub fn new(shared: &'a SharedLayoutContext) -> Self + { + LayoutContext { + shared: shared, + persistent: create_or_get_persistent_context(shared), + } } } impl<'a> LayoutContext<'a> { - pub fn new(shared_layout_context: &'a SharedLayoutContext) -> LayoutContext<'a> { - let local_context = create_or_get_local_context(shared_layout_context); - - LayoutContext { - shared: shared_layout_context, - cached_local_layout_context: local_context, - } + // FIXME(bholley): The following two methods are identical and should be merged. + // shared_context() is the appropriate name, but it involves renaming a lot of + // calls. + #[inline(always)] + pub fn shared_context(&self) -> &SharedStyleContext { + &self.shared.style_context } #[inline(always)] @@ -120,7 +136,7 @@ impl<'a> LayoutContext<'a> { #[inline(always)] pub fn font_context(&self) -> RefMut<FontContext> { - self.cached_local_layout_context.font_context.borrow_mut() + self.persistent.font_context.borrow_mut() } } |