aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/layout/context.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/layout/context.rs')
-rw-r--r--src/components/layout/context.rs182
1 files changed, 46 insertions, 136 deletions
diff --git a/src/components/layout/context.rs b/src/components/layout/context.rs
index 0a58e3a761a..936314dcb63 100644
--- a/src/components/layout/context.rs
+++ b/src/components/layout/context.rs
@@ -10,8 +10,6 @@ use geom::{Rect, Size2D};
use gfx::display_list::OpaqueNode;
use gfx::font_context::FontContext;
use gfx::font_cache_task::FontCacheTask;
-#[cfg(not(target_os="android"))]
-use green::task::GreenTask;
use script::layout_interface::LayoutChan;
use servo_msg::constellation_msg::ConstellationChan;
use servo_net::local_image_cache::LocalImageCache;
@@ -19,42 +17,37 @@ use servo_util::geometry::Au;
use servo_util::opts::Opts;
use sync::{Arc, Mutex};
use std::mem;
-#[cfg(not(target_os="android"))]
-use std::ptr;
-#[cfg(not(target_os="android"))]
-use std::rt::local::Local;
-#[cfg(not(target_os="android"))]
-use std::rt::task::Task;
use style::Stylist;
use url::Url;
-#[cfg(not(target_os="android"))]
-#[thread_local]
-static mut FONT_CONTEXT: *mut FontContext = 0 as *mut FontContext;
-
-#[cfg(target_os="android")]
-local_data_key!(font_context: *mut FontContext)
-
-#[cfg(not(target_os="android"))]
-#[thread_local]
-static mut APPLICABLE_DECLARATIONS_CACHE: *mut ApplicableDeclarationsCache =
- 0 as *mut ApplicableDeclarationsCache;
-
-#[cfg(target_os="android")]
-local_data_key!(applicable_declarations_cache: *mut ApplicableDeclarationsCache)
-
-#[cfg(not(target_os="android"))]
-#[thread_local]
-static mut STYLE_SHARING_CANDIDATE_CACHE: *mut StyleSharingCandidateCache =
- 0 as *mut StyleSharingCandidateCache;
+struct LocalLayoutContext {
+ font_context: FontContext,
+ applicable_declarations_cache: ApplicableDeclarationsCache,
+ style_sharing_candidate_cache: StyleSharingCandidateCache,
+}
-#[cfg(target_os="android")]
-local_data_key!(style_sharing_candidate_cache: *mut StyleSharingCandidateCache)
+local_data_key!(local_context_key: *mut LocalLayoutContext)
+
+fn create_or_get_local_context(shared_layout_context: &SharedLayoutContext) -> *mut LocalLayoutContext {
+ let maybe_context = local_context_key.get();
+
+ let context = match maybe_context {
+ None => {
+ let context = box LocalLayoutContext {
+ font_context: FontContext::new(shared_layout_context.font_cache_task.clone()),
+ applicable_declarations_cache: ApplicableDeclarationsCache::new(),
+ style_sharing_candidate_cache: StyleSharingCandidateCache::new(),
+ };
+ local_context_key.replace(Some(unsafe { mem::transmute(context) }));
+ local_context_key.get().unwrap()
+ },
+ Some(context) => context
+ };
+
+ *context
+}
-/// Data shared by all layout workers.
-#[allow(raw_pointer_deriving)]
-#[deriving(Clone)]
-pub struct LayoutContext {
+pub struct SharedLayoutContext {
/// The local image cache.
pub image_cache: Arc<Mutex<LocalImageCache>>,
@@ -88,126 +81,43 @@ pub struct LayoutContext {
pub dirty: Rect<Au>,
}
-#[cfg(not(target_os="android"))]
-impl LayoutContext {
- pub fn font_context<'a>(&'a mut self) -> &'a mut FontContext {
- // Sanity check.
- {
- let mut task = Local::borrow(None::<Task>);
- match task.maybe_take_runtime::<GreenTask>() {
- Some(green) => {
- task.put_runtime(green);
- fail!("can't call this on a green task!")
- }
- None => {}
- }
- }
-
- unsafe {
- if FONT_CONTEXT == ptr::mut_null() {
- let context = box FontContext::new(self.font_cache_task.clone());
- FONT_CONTEXT = mem::transmute(context)
- }
- mem::transmute(FONT_CONTEXT)
- }
- }
-
- pub fn applicable_declarations_cache<'a>(&'a self) -> &'a mut ApplicableDeclarationsCache {
- // Sanity check.
- {
- let mut task = Local::borrow(None::<Task>);
- match task.maybe_take_runtime::<GreenTask>() {
- Some(green) => {
- task.put_runtime(green);
- fail!("can't call this on a green task!")
- }
- None => {}
- }
- }
+pub struct LayoutContext<'a> {
+ pub shared: &'a SharedLayoutContext,
+ cached_local_layout_context: *mut LocalLayoutContext,
+}
- unsafe {
- if APPLICABLE_DECLARATIONS_CACHE == ptr::mut_null() {
- let cache = box ApplicableDeclarationsCache::new();
- APPLICABLE_DECLARATIONS_CACHE = mem::transmute(cache)
- }
- mem::transmute(APPLICABLE_DECLARATIONS_CACHE)
- }
- }
+impl<'a> LayoutContext<'a> {
+ pub fn new(shared_layout_context: &'a SharedLayoutContext) -> LayoutContext<'a> {
- pub fn style_sharing_candidate_cache<'a>(&'a self) -> &'a mut StyleSharingCandidateCache {
- // Sanity check.
- {
- let mut task = Local::borrow(None::<Task>);
- match task.maybe_take_runtime::<GreenTask>() {
- Some(green) => {
- task.put_runtime(green);
- fail!("can't call this on a green task!")
- }
- None => {}
- }
- }
+ let local_context = create_or_get_local_context(shared_layout_context);
- unsafe {
- if STYLE_SHARING_CANDIDATE_CACHE == ptr::mut_null() {
- let cache = box StyleSharingCandidateCache::new();
- STYLE_SHARING_CANDIDATE_CACHE = mem::transmute(cache)
- }
- mem::transmute(STYLE_SHARING_CANDIDATE_CACHE)
+ LayoutContext {
+ shared: shared_layout_context,
+ cached_local_layout_context: local_context,
}
}
-}
-
-// On Android, we don't have the __tls_* functions emitted by rustc, so we
-// need to use the slower local_data functions.
-// Making matters worse, the local_data functions are very particular about
-// enforcing the lifetimes associated with objects that they hold onto,
-// which causes us some trouble we work around as below.
-#[cfg(target_os="android")]
-impl LayoutContext {
- pub fn font_context<'a>(&'a mut self) -> &'a mut FontContext {
+ #[inline(always)]
+ pub fn font_context<'a>(&'a self) -> &'a mut FontContext {
unsafe {
- let opt = font_context.replace(None);
- let mut context;
- match opt {
- Some(c) => context = mem::transmute(c),
- None => {
- context = mem::transmute(box FontContext::new(self.font_cache_task.clone()))
- }
- }
- font_context.replace(Some(context));
- mem::transmute(context)
+ let cached_context = &*self.cached_local_layout_context;
+ mem::transmute(&cached_context.font_context)
}
}
+ #[inline(always)]
pub fn applicable_declarations_cache<'a>(&'a self) -> &'a mut ApplicableDeclarationsCache {
unsafe {
- let opt = applicable_declarations_cache.replace(None);
- let mut cache;
- match opt {
- Some(c) => cache = mem::transmute(c),
- None => {
- cache = mem::transmute(box ApplicableDeclarationsCache::new());
- }
- }
- applicable_declarations_cache.replace(Some(cache));
- mem::transmute(cache)
+ let cached_context = &*self.cached_local_layout_context;
+ mem::transmute(&cached_context.applicable_declarations_cache)
}
}
+ #[inline(always)]
pub fn style_sharing_candidate_cache<'a>(&'a self) -> &'a mut StyleSharingCandidateCache {
unsafe {
- let opt = style_sharing_candidate_cache.replace(None);
- let mut cache;
- match opt {
- Some(c) => cache = mem::transmute(c),
- None => {
- cache = mem::transmute(box StyleSharingCandidateCache::new());
- }
- }
- style_sharing_candidate_cache.replace(Some(cache));
- mem::transmute(cache)
+ let cached_context = &*self.cached_local_layout_context;
+ mem::transmute(&cached_context.style_sharing_candidate_cache)
}
}
}
-