aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <me@emiliocobos.me>2016-06-29 20:04:30 -0700
committerEmilio Cobos Álvarez <me@emiliocobos.me>2016-07-01 13:48:06 -0700
commit203d2a62c24ca3d8b07e4ec492fc53bb30bbeedc (patch)
tree979b0367ce41c744c270a54092c962b916f5a6e9
parent5478e605aef93cc384b709688cc68e3ed854a68b (diff)
downloadservo-203d2a62c24ca3d8b07e4ec492fc53bb30bbeedc.tar.gz
servo-203d2a62c24ca3d8b07e4ec492fc53bb30bbeedc.zip
style: Remove the Mutex from new_animations_sender by moving it to the local StyleContext.
As a follow-up, we could move all the data living under a mutex in the SharedLayoutContext only in order to create the local context to the same place. This should increase animation performance when there are multiple animations in one page that happen to be on different threads.
-rw-r--r--components/layout/context.rs14
-rw-r--r--components/layout_thread/lib.rs6
-rw-r--r--components/style/animation.rs31
-rw-r--r--components/style/context.rs42
-rw-r--r--components/style/matching.rs56
-rw-r--r--components/style/parallel.rs2
-rw-r--r--components/style/selector_impl.rs2
-rw-r--r--components/style/servo.rs1
-rw-r--r--components/style/traversal.rs3
-rw-r--r--ports/geckolib/context.rs53
-rw-r--r--ports/geckolib/data.rs4
-rw-r--r--ports/geckolib/glue.rs24
-rw-r--r--ports/geckolib/lib.rs1
-rw-r--r--ports/geckolib/selector_impl.rs1
-rw-r--r--ports/geckolib/traversal.rs60
15 files changed, 166 insertions, 134 deletions
diff --git a/components/layout/context.rs b/components/layout/context.rs
index 11cfed0d1b3..08237579626 100644
--- a/components/layout/context.rs
+++ b/components/layout/context.rs
@@ -25,15 +25,14 @@ use std::hash::BuildHasherDefault;
use std::rc::Rc;
use std::sync::{Arc, Mutex, RwLock};
use style::context::{LocalStyleContext, StyleContext};
-use style::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
-use style::properties::ServoComputedValues;
use style::selector_impl::ServoSelectorImpl;
use style::servo::SharedStyleContext;
use url::Url;
use util::opts;
struct LocalLayoutContext {
- style_context: LocalStyleContext<ServoComputedValues>,
+ style_context: LocalStyleContext<ServoSelectorImpl>,
+
font_context: RefCell<FontContext>,
}
@@ -64,11 +63,10 @@ fn create_or_get_local_context(shared_layout_context: &SharedLayoutContext)
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 {
- applicable_declarations_cache: RefCell::new(ApplicableDeclarationsCache::new()),
- style_sharing_candidate_cache: RefCell::new(StyleSharingCandidateCache::new()),
- },
+ style_context: LocalStyleContext::new(&local_style_data),
font_context: RefCell::new(FontContext::new(font_cache_thread)),
});
*r = Some(context.clone());
@@ -110,7 +108,7 @@ impl<'a> StyleContext<'a, ServoSelectorImpl> for LayoutContext<'a> {
&self.shared.style_context
}
- fn local_context(&self) -> &LocalStyleContext<ServoComputedValues> {
+ fn local_context(&self) -> &LocalStyleContext<ServoSelectorImpl> {
&self.cached_local_layout_context.style_context
}
}
diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs
index b33a5c56eb1..8b147955569 100644
--- a/components/layout_thread/lib.rs
+++ b/components/layout_thread/lib.rs
@@ -108,7 +108,7 @@ use style::parallel::WorkQueueData;
use style::properties::ComputedValues;
use style::refcell::RefCell;
use style::selector_matching::USER_OR_USER_AGENT_STYLESHEETS;
-use style::servo::{Animation, SharedStyleContext, Stylesheet, Stylist};
+use style::servo::{Animation, LocalStyleContextCreationInfo, SharedStyleContext, Stylesheet, Stylist};
use style::stylesheets::CSSRuleIteratorExt;
use url::Url;
use util::geometry::MAX_RECT;
@@ -488,6 +488,8 @@ impl LayoutThread {
screen_size_changed: bool,
goal: ReflowGoal)
-> SharedLayoutContext {
+ let local_style_context_creation_data = LocalStyleContextCreationInfo::new(self.new_animations_sender.clone());
+
SharedLayoutContext {
style_context: SharedStyleContext {
viewport_size: self.viewport_size.clone(),
@@ -495,10 +497,10 @@ impl LayoutThread {
stylist: rw_data.stylist.clone(),
generation: self.generation,
goal: goal,
- new_animations_sender: Mutex::new(self.new_animations_sender.clone()),
running_animations: self.running_animations.clone(),
expired_animations: self.expired_animations.clone(),
error_reporter: self.error_reporter.clone(),
+ local_context_creation_data: Mutex::new(local_style_context_creation_data),
},
image_cache_thread: self.image_cache_thread.clone(),
image_cache_sender: Mutex::new(self.image_cache_sender.clone()),
diff --git a/components/style/animation.rs b/components/style/animation.rs
index b2a64a5fa5e..29cd2bfa06d 100644
--- a/components/style/animation.rs
+++ b/components/style/animation.rs
@@ -19,8 +19,8 @@ use properties::style_struct_traits::Box;
use properties::{self, ComputedValues};
use selector_impl::SelectorImplExt;
use selectors::matching::DeclarationBlock;
+use std::sync::Arc;
use std::sync::mpsc::Sender;
-use std::sync::{Arc, Mutex};
use string_cache::Atom;
use time;
use values::computed::Time;
@@ -356,7 +356,7 @@ impl<T> GetMod for Vec<T> {
//
// TODO(emilio): Take rid of this mutex splitting SharedLayoutContex into a
// cloneable part and a non-cloneable part..
-pub fn start_transitions_if_applicable<Impl: SelectorImplExt>(new_animations_sender: &Mutex<Sender<Animation<Impl>>>,
+pub fn start_transitions_if_applicable<Impl: SelectorImplExt>(new_animations_sender: &Sender<Animation<Impl>>,
node: OpaqueNode,
old_style: &Impl::ComputedValues,
new_style: &mut Arc<Impl::ComputedValues>)
@@ -377,7 +377,6 @@ pub fn start_transitions_if_applicable<Impl: SelectorImplExt>(new_animations_sen
let start_time =
now + (box_style.transition_delay.0.get_mod(i).seconds() as f64);
new_animations_sender
- .lock().unwrap()
.send(Animation::Transition(node, start_time, AnimationFrame {
duration: box_style.transition_duration.0.get_mod(i).seconds() as f64,
property_animation: property_animation,
@@ -417,6 +416,7 @@ fn compute_style_for_animation_step<Impl: SelectorImplExt>(context: &SharedStyle
}
pub fn maybe_start_animations<Impl: SelectorImplExt>(context: &SharedStyleContext<Impl>,
+ new_animations_sender: &Sender<Animation<Impl>>,
node: OpaqueNode,
new_style: &Arc<Impl::ComputedValues>) -> bool
{
@@ -465,19 +465,18 @@ pub fn maybe_start_animations<Impl: SelectorImplExt>(context: &SharedStyleContex
};
- context.new_animations_sender
- .lock().unwrap()
- .send(Animation::Keyframes(node, name.clone(), KeyframesAnimationState {
- started_at: animation_start,
- duration: duration as f64,
- delay: delay as f64,
- iteration_state: iteration_state,
- running_state: running_state,
- direction: animation_direction,
- current_direction: initial_direction,
- expired: false,
- cascade_style: new_style.clone(),
- })).unwrap();
+ new_animations_sender
+ .send(Animation::Keyframes(node, name.clone(), KeyframesAnimationState {
+ started_at: animation_start,
+ duration: duration as f64,
+ delay: delay as f64,
+ iteration_state: iteration_state,
+ running_state: running_state,
+ direction: animation_direction,
+ current_direction: initial_direction,
+ expired: false,
+ cascade_style: new_style.clone(),
+ })).unwrap();
had_animations = true;
}
}
diff --git a/components/style/context.rs b/components/style/context.rs
index 041b52d2a17..bb8b179651c 100644
--- a/components/style/context.rs
+++ b/components/style/context.rs
@@ -10,7 +10,6 @@ use dom::OpaqueNode;
use error_reporting::ParseErrorReporter;
use euclid::Size2D;
use matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
-use properties::ComputedValues;
use selector_impl::SelectorImplExt;
use selector_matching::Stylist;
use std::cell::RefCell;
@@ -18,6 +17,19 @@ use std::collections::HashMap;
use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex, RwLock};
+/// This structure is used to create a local style context from a shared one.
+pub struct LocalStyleContextCreationInfo<Impl: SelectorImplExt> {
+ new_animations_sender: Sender<Animation<Impl>>,
+}
+
+impl<Impl: SelectorImplExt> LocalStyleContextCreationInfo<Impl> {
+ pub fn new(animations_sender: Sender<Animation<Impl>>) -> Self {
+ LocalStyleContextCreationInfo {
+ new_animations_sender: animations_sender,
+ }
+ }
+}
+
pub struct SharedStyleContext<Impl: SelectorImplExt> {
/// The current viewport size.
pub viewport_size: Size2D<Au>,
@@ -32,10 +44,6 @@ pub struct SharedStyleContext<Impl: SelectorImplExt> {
/// This can be used to easily check for invalid stale data.
pub generation: u32,
- /// A channel on which new animations that have been triggered by style recalculation can be
- /// sent.
- pub new_animations_sender: Mutex<Sender<Animation<Impl>>>,
-
/// Why is this reflow occurring
pub goal: ReflowGoal,
@@ -47,16 +55,32 @@ pub struct SharedStyleContext<Impl: SelectorImplExt> {
///The CSS error reporter for all CSS loaded in this layout thread
pub error_reporter: Box<ParseErrorReporter + Sync>,
+
+ /// Data needed to create the local style context from the shared one.
+ pub local_context_creation_data: Mutex<LocalStyleContextCreationInfo<Impl>>,
+}
+
+pub struct LocalStyleContext<Impl: SelectorImplExt> {
+ pub applicable_declarations_cache: RefCell<ApplicableDeclarationsCache<Impl::ComputedValues>>,
+ pub style_sharing_candidate_cache: RefCell<StyleSharingCandidateCache<Impl::ComputedValues>>,
+ /// A channel on which new animations that have been triggered by style
+ /// recalculation can be sent.
+ pub new_animations_sender: Sender<Animation<Impl>>,
}
-pub struct LocalStyleContext<C: ComputedValues> {
- pub applicable_declarations_cache: RefCell<ApplicableDeclarationsCache<C>>,
- pub style_sharing_candidate_cache: RefCell<StyleSharingCandidateCache<C>>,
+impl<Impl: SelectorImplExt> LocalStyleContext<Impl> {
+ pub fn new(local_context_creation_data: &LocalStyleContextCreationInfo<Impl>) -> Self {
+ LocalStyleContext {
+ applicable_declarations_cache: RefCell::new(ApplicableDeclarationsCache::new()),
+ style_sharing_candidate_cache: RefCell::new(StyleSharingCandidateCache::new()),
+ new_animations_sender: local_context_creation_data.new_animations_sender.clone(),
+ }
+ }
}
pub trait StyleContext<'a, Impl: SelectorImplExt> {
fn shared_context(&self) -> &'a SharedStyleContext<Impl>;
- fn local_context(&self) -> &LocalStyleContext<Impl::ComputedValues>;
+ fn local_context(&self) -> &LocalStyleContext<Impl>;
}
/// Why we're doing reflow.
diff --git a/components/style/matching.rs b/components/style/matching.rs
index 1f85effdb33..5e0009c379b 100644
--- a/components/style/matching.rs
+++ b/components/style/matching.rs
@@ -7,7 +7,7 @@
#![allow(unsafe_code)]
use animation::{self, Animation};
-use context::{SharedStyleContext, LocalStyleContext};
+use context::{StyleContext, SharedStyleContext};
use data::PrivateStyleData;
use dom::{TElement, TNode, TRestyleDamage};
use properties::{ComputedValues, PropertyDeclaration, cascade};
@@ -371,19 +371,22 @@ trait PrivateMatchMethods: TNode
///
/// Note that animations only apply to nodes or ::before or ::after
/// pseudo-elements.
- fn cascade_node_pseudo_element(&self,
- context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>,
- parent_style: Option<&Arc<Self::ConcreteComputedValues>>,
- applicable_declarations: &[DeclarationBlock],
- mut style: Option<&mut Arc<Self::ConcreteComputedValues>>,
- applicable_declarations_cache:
- &mut ApplicableDeclarationsCache<Self::ConcreteComputedValues>,
- shareable: bool,
- animate_properties: bool)
- -> (Self::ConcreteRestyleDamage, Arc<Self::ConcreteComputedValues>) {
+ fn cascade_node_pseudo_element<'a, Ctx>(&self,
+ context: &Ctx,
+ parent_style: Option<&Arc<Self::ConcreteComputedValues>>,
+ applicable_declarations: &[DeclarationBlock],
+ mut style: Option<&mut Arc<Self::ConcreteComputedValues>>,
+ applicable_declarations_cache:
+ &mut ApplicableDeclarationsCache<Self::ConcreteComputedValues>,
+ shareable: bool,
+ animate_properties: bool)
+ -> (Self::ConcreteRestyleDamage, Arc<Self::ConcreteComputedValues>)
+ where Ctx: StyleContext<'a, <Self::ConcreteElement as Element>::Impl> {
let mut cacheable = true;
+ let shared_context = context.shared_context();
if animate_properties {
- cacheable = !self.update_animations_for_cascade(context, &mut style) && cacheable;
+ cacheable = !self.update_animations_for_cascade(shared_context,
+ &mut style) && cacheable;
}
let this_style;
@@ -395,22 +398,22 @@ trait PrivateMatchMethods: TNode
None => None,
};
- let (the_style, is_cacheable) = cascade(context.viewport_size,
+ let (the_style, is_cacheable) = cascade(shared_context.viewport_size,
applicable_declarations,
shareable,
Some(&***parent_style),
cached_computed_values,
- context.error_reporter.clone());
+ shared_context.error_reporter.clone());
cacheable = cacheable && is_cacheable;
this_style = the_style
}
None => {
- let (the_style, is_cacheable) = cascade(context.viewport_size,
+ let (the_style, is_cacheable) = cascade(shared_context.viewport_size,
applicable_declarations,
shareable,
None,
None,
- context.error_reporter.clone());
+ shared_context.error_reporter.clone());
cacheable = cacheable && is_cacheable;
this_style = the_style
}
@@ -419,10 +422,12 @@ trait PrivateMatchMethods: TNode
let mut this_style = Arc::new(this_style);
if animate_properties {
+ let new_animations_sender = &context.local_context().new_animations_sender;
let this_opaque = self.opaque();
// Trigger any present animations if necessary.
let mut animations_started = animation::maybe_start_animations::<<Self::ConcreteElement as Element>::Impl>(
- &context,
+ &shared_context,
+ new_animations_sender,
this_opaque,
&this_style);
@@ -431,7 +436,7 @@ trait PrivateMatchMethods: TNode
if let Some(ref style) = style {
animations_started |=
animation::start_transitions_if_applicable::<<Self::ConcreteElement as Element>::Impl>(
- &context.new_animations_sender,
+ new_animations_sender,
this_opaque,
&**style,
&mut this_style);
@@ -658,12 +663,13 @@ pub trait MatchMethods : TNode {
}
}
- unsafe fn cascade_node(&self,
- context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>,
- local_context: &LocalStyleContext<Self::ConcreteComputedValues>,
- parent: Option<Self>,
- applicable_declarations: &ApplicableDeclarations<<Self::ConcreteElement as Element>::Impl>)
- where <Self::ConcreteElement as Element>::Impl: SelectorImplExt<ComputedValues = Self::ConcreteComputedValues>
+ unsafe fn cascade_node<'a, Ctx>(&self,
+ context: &Ctx,
+ parent: Option<Self>,
+ applicable_declarations:
+ &ApplicableDeclarations<<Self::ConcreteElement as Element>::Impl>)
+ where <Self::ConcreteElement as Element>::Impl: SelectorImplExt<ComputedValues = Self::ConcreteComputedValues>,
+ Ctx: StyleContext<'a, <Self::ConcreteElement as Element>::Impl>
{
// Get our parent's style. This must be unsafe so that we don't touch the parent's
// borrow flags.
@@ -679,7 +685,7 @@ pub trait MatchMethods : TNode {
};
let mut applicable_declarations_cache =
- local_context.applicable_declarations_cache.borrow_mut();
+ context.local_context().applicable_declarations_cache.borrow_mut();
let damage;
if self.is_text_node() {
diff --git a/components/style/parallel.rs b/components/style/parallel.rs
index 55f15f1d80f..d7cb95ecac2 100644
--- a/components/style/parallel.rs
+++ b/components/style/parallel.rs
@@ -45,7 +45,7 @@ pub fn traverse_dom<N, C>(root: N,
where N: TNode, C: DomTraversalContext<N> {
run_queue_with_custom_work_data_type(queue, |queue| {
queue.push(WorkUnit {
- fun: top_down_dom::<N, C>,
+ fun: top_down_dom::<N, C>,
data: (Box::new(vec![root.to_unsafe()]), root.opaque()),
});
}, queue_data);
diff --git a/components/style/selector_impl.rs b/components/style/selector_impl.rs
index 7f80cb2ea38..cf95f4a9048 100644
--- a/components/style/selector_impl.rs
+++ b/components/style/selector_impl.rs
@@ -65,7 +65,7 @@ pub trait ElementExt: Element {
// NB: The `Clone` trait is here for convenience due to:
// https://github.com/rust-lang/rust/issues/26925
-pub trait SelectorImplExt : SelectorImpl + Clone + Debug + Sized {
+pub trait SelectorImplExt : SelectorImpl + Clone + Debug + Sized + 'static {
type ComputedValues: properties::ComputedValues;
fn pseudo_element_cascade_type(pseudo: &Self::PseudoElement) -> PseudoElementCascadeType;
diff --git a/components/style/servo.rs b/components/style/servo.rs
index b592104832a..d5605a62832 100644
--- a/components/style/servo.rs
+++ b/components/style/servo.rs
@@ -15,4 +15,5 @@ pub type Stylesheet = stylesheets::Stylesheet<ServoSelectorImpl>;
pub type PrivateStyleData = data::PrivateStyleData<ServoSelectorImpl, ServoComputedValues>;
pub type Stylist = selector_matching::Stylist<ServoSelectorImpl>;
pub type SharedStyleContext = context::SharedStyleContext<ServoSelectorImpl>;
+pub type LocalStyleContextCreationInfo = context::LocalStyleContextCreationInfo<ServoSelectorImpl>;
pub type Animation = animation::Animation<ServoSelectorImpl>;
diff --git a/components/style/traversal.rs b/components/style/traversal.rs
index 5e5b7d31948..f76b0b3f5da 100644
--- a/components/style/traversal.rs
+++ b/components/style/traversal.rs
@@ -218,8 +218,7 @@ pub fn recalc_style_at<'a, N, C>(context: &'a C,
// Perform the CSS cascade.
unsafe {
- node.cascade_node(&context.shared_context(),
- &context.local_context(),
+ node.cascade_node(context,
parent_opt,
&applicable_declarations);
}
diff --git a/ports/geckolib/context.rs b/ports/geckolib/context.rs
new file mode 100644
index 00000000000..ea95b00b4b7
--- /dev/null
+++ b/ports/geckolib/context.rs
@@ -0,0 +1,53 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+use selector_impl::{GeckoSelectorImpl, SharedStyleContext};
+use std::cell::RefCell;
+use std::rc::Rc;
+use style::context::{LocalStyleContext, StyleContext};
+
+thread_local!(static LOCAL_CONTEXT_KEY:
+ RefCell<Option<Rc<LocalStyleContext<GeckoSelectorImpl>>>> = RefCell::new(None));
+
+// Keep this implementation in sync with the one in components/layout/context.rs.
+fn create_or_get_local_context(shared: &SharedStyleContext)
+ -> Rc<LocalStyleContext<GeckoSelectorImpl>> {
+ LOCAL_CONTEXT_KEY.with(|r| {
+ let mut r = r.borrow_mut();
+ if let Some(context) = r.clone() {
+ if shared.screen_size_changed {
+ context.applicable_declarations_cache.borrow_mut().evict_all();
+ }
+ context
+ } else {
+ let context = Rc::new(LocalStyleContext::new(&shared.local_context_creation_data.lock().unwrap()));
+ *r = Some(context.clone());
+ context
+ }
+ })
+}
+
+pub struct StandaloneStyleContext<'a> {
+ pub shared: &'a SharedStyleContext,
+ cached_local_context: Rc<LocalStyleContext<GeckoSelectorImpl>>,
+}
+
+impl<'a> StandaloneStyleContext<'a> {
+ pub fn new(shared: &'a SharedStyleContext) -> Self {
+ let local_context = create_or_get_local_context(shared);
+ StandaloneStyleContext {
+ shared: shared,
+ cached_local_context: local_context,
+ }
+ }
+}
+
+impl<'a> StyleContext<'a, GeckoSelectorImpl> for StandaloneStyleContext<'a> {
+ fn shared_context(&self) -> &'a SharedStyleContext {
+ &self.shared
+ }
+
+ fn local_context(&self) -> &LocalStyleContext<GeckoSelectorImpl> {
+ &self.cached_local_context
+ }
+}
diff --git a/ports/geckolib/data.rs b/ports/geckolib/data.rs
index 0f07ef83c57..9b2698409c9 100644
--- a/ports/geckolib/data.rs
+++ b/ports/geckolib/data.rs
@@ -6,7 +6,7 @@ use euclid::Size2D;
use euclid::size::TypedSize2D;
use gecko_bindings::bindings::RawServoStyleSet;
use num_cpus;
-use selector_impl::{GeckoSelectorImpl, Stylist, Stylesheet, SharedStyleContext};
+use selector_impl::{Animation, SharedStyleContext, Stylist, Stylesheet};
use std::cmp;
use std::collections::HashMap;
use std::sync::mpsc::{channel, Receiver, Sender};
@@ -18,8 +18,6 @@ use util::geometry::ViewportPx;
use util::thread_state;
use util::workqueue::WorkQueue;
-pub type Animation = ::style::animation::Animation<GeckoSelectorImpl>;
-
pub struct PerDocumentStyleData {
/// Rule processor.
pub stylist: Arc<Stylist>,
diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs
index 09503d76670..8f76407749c 100644
--- a/ports/geckolib/glue.rs
+++ b/ports/geckolib/glue.rs
@@ -22,7 +22,7 @@ use std::ptr;
use std::slice;
use std::str::from_utf8_unchecked;
use std::sync::{Arc, Mutex};
-use style::context::ReflowGoal;
+use style::context::{LocalStyleContextCreationInfo, ReflowGoal};
use style::dom::{TDocument, TElement, TNode};
use style::error_reporting::StdoutErrorReporter;
use style::parallel;
@@ -77,7 +77,7 @@ pub extern "C" fn Servo_Initialize() -> () {
fn restyle_subtree(node: GeckoNode, raw_data: *mut RawServoStyleSet) {
debug_assert!(node.is_element() || node.is_text_node());
- let data = unsafe { &mut *(raw_data as *mut PerDocumentStyleData) };
+ let per_doc_data = unsafe { &mut *(raw_data as *mut PerDocumentStyleData) };
// Force the creation of our lazily-constructed initial computed values on
// the main thread, since it's not safe to call elsewhere.
@@ -88,24 +88,28 @@ fn restyle_subtree(node: GeckoNode, raw_data: *mut RawServoStyleSet) {
// along in startup than the sensible place to call Servo_Initialize.
GeckoComputedValues::initial_values();
- let _needs_dirtying = Arc::get_mut(&mut data.stylist).unwrap()
- .update(&data.stylesheets, data.stylesheets_changed);
- data.stylesheets_changed = false;
+ let _needs_dirtying = Arc::get_mut(&mut per_doc_data.stylist).unwrap()
+ .update(&per_doc_data.stylesheets,
+ per_doc_data.stylesheets_changed);
+ per_doc_data.stylesheets_changed = false;
+
+ let local_context_data =
+ LocalStyleContextCreationInfo::new(per_doc_data.new_animations_sender.clone());
let shared_style_context = SharedStyleContext {
viewport_size: Size2D::new(Au(0), Au(0)),
screen_size_changed: false,
generation: 0,
goal: ReflowGoal::ForScriptQuery,
- stylist: data.stylist.clone(),
- new_animations_sender: Mutex::new(data.new_animations_sender.clone()),
- running_animations: data.running_animations.clone(),
- expired_animations: data.expired_animations.clone(),
+ stylist: per_doc_data.stylist.clone(),
+ running_animations: per_doc_data.running_animations.clone(),
+ expired_animations: per_doc_data.expired_animations.clone(),
error_reporter: Box::new(StdoutErrorReporter),
+ local_context_creation_data: Mutex::new(local_context_data),
};
if node.is_dirty() || node.has_dirty_descendants() {
- parallel::traverse_dom::<GeckoNode, RecalcStyleOnly>(node, &shared_style_context, &mut data.work_queue);
+ parallel::traverse_dom::<GeckoNode, RecalcStyleOnly>(node, &shared_style_context, &mut per_doc_data.work_queue);
}
}
diff --git a/ports/geckolib/lib.rs b/ports/geckolib/lib.rs
index cedf344568f..c3c90da9cb3 100644
--- a/ports/geckolib/lib.rs
+++ b/ports/geckolib/lib.rs
@@ -24,6 +24,7 @@ extern crate style_traits;
extern crate url;
extern crate util;
+mod context;
mod data;
#[allow(non_snake_case)]
pub mod glue;
diff --git a/ports/geckolib/selector_impl.rs b/ports/geckolib/selector_impl.rs
index 5c5e1731b3b..c1284015414 100644
--- a/ports/geckolib/selector_impl.rs
+++ b/ports/geckolib/selector_impl.rs
@@ -12,6 +12,7 @@ pub type Stylist = style::selector_matching::Stylist<GeckoSelectorImpl>;
pub type Stylesheet = style::stylesheets::Stylesheet<GeckoSelectorImpl>;
pub type SharedStyleContext = style::context::SharedStyleContext<GeckoSelectorImpl>;
pub type PrivateStyleData = style::data::PrivateStyleData<GeckoSelectorImpl, GeckoComputedValues>;
+pub type Animation = style::animation::Animation<GeckoSelectorImpl>;
#[cfg(feature = "servo_features")]
known_heap_size!(0, GeckoSelectorImpl, PseudoElement, NonTSPseudoClass);
diff --git a/ports/geckolib/traversal.rs b/ports/geckolib/traversal.rs
index f400377aeca..fc85963ba08 100644
--- a/ports/geckolib/traversal.rs
+++ b/ports/geckolib/traversal.rs
@@ -2,66 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use properties::GeckoComputedValues;
-use selector_impl::{GeckoSelectorImpl, SharedStyleContext};
-use std::cell::RefCell;
+use context::StandaloneStyleContext;
+use selector_impl::SharedStyleContext;
use std::mem;
-use std::rc::Rc;
-use style::context::{LocalStyleContext, StyleContext};
use style::dom::OpaqueNode;
-use style::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
use style::traversal::{DomTraversalContext, recalc_style_at};
use wrapper::GeckoNode;
-thread_local!(static LOCAL_CONTEXT_KEY:
- RefCell<Option<Rc<LocalStyleContext<GeckoComputedValues>>>> = RefCell::new(None));
-
-// Keep this implementation in sync with the one in components/layout/context.rs.
-fn create_or_get_local_context(shared: &SharedStyleContext)
- -> Rc<LocalStyleContext<GeckoComputedValues>> {
- LOCAL_CONTEXT_KEY.with(|r| {
- let mut r = r.borrow_mut();
- if let Some(context) = r.clone() {
- if shared.screen_size_changed {
- context.applicable_declarations_cache.borrow_mut().evict_all();
- }
- context
- } else {
- let context = Rc::new(LocalStyleContext {
- applicable_declarations_cache: RefCell::new(ApplicableDeclarationsCache::new()),
- style_sharing_candidate_cache: RefCell::new(StyleSharingCandidateCache::new()),
- });
- *r = Some(context.clone());
- context
- }
- })
-}
-
-pub struct StandaloneStyleContext<'a> {
- pub shared: &'a SharedStyleContext,
- cached_local_context: Rc<LocalStyleContext<GeckoComputedValues>>,
-}
-
-impl<'a> StandaloneStyleContext<'a> {
- pub fn new(shared: &'a SharedStyleContext) -> Self {
- let local_context = create_or_get_local_context(shared);
- StandaloneStyleContext {
- shared: shared,
- cached_local_context: local_context,
- }
- }
-}
-
-impl<'a> StyleContext<'a, GeckoSelectorImpl> for StandaloneStyleContext<'a> {
- fn shared_context(&self) -> &'a SharedStyleContext {
- &self.shared
- }
-
- fn local_context(&self) -> &LocalStyleContext<GeckoComputedValues> {
- &self.cached_local_context
- }
-}
-
pub struct RecalcStyleOnly<'lc> {
context: StandaloneStyleContext<'lc>,
root: OpaqueNode,
@@ -73,7 +20,7 @@ impl<'lc, 'ln> DomTraversalContext<GeckoNode<'ln>> for RecalcStyleOnly<'lc> {
fn new<'a>(shared: &'a Self::SharedContext, root: OpaqueNode) -> Self {
// See the comment in RecalcStyleAndConstructFlows::new for an explanation of why this is
// necessary.
- let shared_lc: &'lc SharedStyleContext = unsafe { mem::transmute(shared) };
+ let shared_lc: &'lc Self::SharedContext = unsafe { mem::transmute(shared) };
RecalcStyleOnly {
context: StandaloneStyleContext::new(shared_lc),
root: root,
@@ -90,4 +37,3 @@ impl<'lc, 'ln> DomTraversalContext<GeckoNode<'ln>> for RecalcStyleOnly<'lc> {
fn process_postorder(&self, _: GeckoNode<'ln>) {}
}
-