mirror of
https://github.com/servo/servo.git
synced 2025-09-01 02:28:21 +01:00
Auto merge of #11946 - emilio:animations-sender, r=bholley
style: Remove the Mutex from new_animations_sender by moving it to the local StyleContext. <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors <!-- Either: --> - [x] These changes do not require tests because refactoring. <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> 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. r? @SimonSapin/@mbrubeck for the style/layout, @bholley for the geckolib changes <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/11946) <!-- Reviewable:end -->
This commit is contained in:
commit
ec0d3e084d
15 changed files with 166 additions and 134 deletions
53
ports/geckolib/context.rs
Normal file
53
ports/geckolib/context.rs
Normal file
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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>,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>) {}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue