aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/context.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout/context.rs')
-rw-r--r--components/layout/context.rs96
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()
}
}