Bug 1309090 - Use AtomicRefCell for RawServoStyleSet.
MozReview-Commit-ID: 27JeRluDAo3
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -33,23 +33,23 @@ SERVO_BINDING_FUNC(Servo_StyleSheet_AddR
RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSheet_Release, void,
RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSheet_HasRules, bool,
RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSet_Init, RawServoStyleSetOwned)
SERVO_BINDING_FUNC(Servo_StyleSet_Drop, void, RawServoStyleSetOwned set)
SERVO_BINDING_FUNC(Servo_StyleSet_AppendStyleSheet, void,
- RawServoStyleSetBorrowedMut set, RawServoStyleSheetBorrowed sheet)
+ RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSet_PrependStyleSheet, void,
- RawServoStyleSetBorrowedMut set, RawServoStyleSheetBorrowed sheet)
+ RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSet_RemoveStyleSheet, void,
- RawServoStyleSetBorrowedMut set, RawServoStyleSheetBorrowed sheet)
+ RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSet_InsertStyleSheetBefore, void,
- RawServoStyleSetBorrowedMut set, RawServoStyleSheetBorrowed sheet,
+ RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet,
RawServoStyleSheetBorrowed reference)
// Animations API
SERVO_BINDING_FUNC(Servo_ParseProperty,
ServoDeclarationBlockStrong,
const uint8_t* property_bytes,
uint32_t property_length,
const uint8_t* value_bytes,
@@ -91,22 +91,22 @@ SERVO_BINDING_FUNC(Servo_CSSSupports, bo
const uint8_t* value, uint32_t value_length)
// Computed style data
SERVO_BINDING_FUNC(Servo_ComputedValues_Get, ServoComputedValuesStrong,
RawGeckoNodeBorrowed node)
SERVO_BINDING_FUNC(Servo_ComputedValues_GetForAnonymousBox,
ServoComputedValuesStrong,
ServoComputedValuesBorrowedOrNull parent_style_or_null,
- nsIAtom* pseudoTag, RawServoStyleSetBorrowedMut set)
+ nsIAtom* pseudoTag, RawServoStyleSetBorrowed set)
SERVO_BINDING_FUNC(Servo_ComputedValues_GetForPseudoElement,
ServoComputedValuesStrong,
ServoComputedValuesBorrowed parent_style,
RawGeckoElementBorrowed match_element, nsIAtom* pseudo_tag,
- RawServoStyleSetBorrowedMut set, bool is_probe)
+ RawServoStyleSetBorrowed set, bool is_probe)
SERVO_BINDING_FUNC(Servo_ComputedValues_Inherit, ServoComputedValuesStrong,
ServoComputedValuesBorrowedOrNull parent_style)
SERVO_BINDING_FUNC(Servo_ComputedValues_AddRef, void,
ServoComputedValuesBorrowed computed_values)
SERVO_BINDING_FUNC(Servo_ComputedValues_Release, void,
ServoComputedValuesBorrowed computed_values)
// Initialize Servo components. Should be called exactly once at startup.
@@ -116,17 +116,17 @@ SERVO_BINDING_FUNC(Servo_Shutdown, void)
// Restyle hints
SERVO_BINDING_FUNC(Servo_ComputeRestyleHint, nsRestyleHint,
RawGeckoElementBorrowed element, ServoElementSnapshot* snapshot,
RawServoStyleSetBorrowed set)
// Restyle the given subtree.
SERVO_BINDING_FUNC(Servo_RestyleSubtree, void,
- RawGeckoNodeBorrowed node, RawServoStyleSetBorrowedMut set)
+ RawGeckoNodeBorrowed node, RawServoStyleSetBorrowed set)
// Style-struct management.
#define STYLE_STRUCT(name, checkdata_cb) \
struct nsStyle##name; \
SERVO_BINDING_FUNC(Servo_GetStyle##name, const nsStyle##name*, \
ServoComputedValuesBorrowedOrNull computed_values)
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
--- a/servo/components/style/gecko/data.rs
+++ b/servo/components/style/gecko/data.rs
@@ -1,12 +1,13 @@
/* 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 atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
use animation::Animation;
use context::SharedStyleContext;
use dom::OpaqueNode;
use euclid::size::TypedSize2D;
use gecko_bindings::bindings::RawServoStyleSet;
use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI};
use media_queries::{Device, MediaType};
use num_cpus;
@@ -17,17 +18,17 @@ use std::collections::HashMap;
use std::env;
use std::sync::{Arc, RwLock};
use std::sync::mpsc::{Receiver, Sender, channel};
use style_traits::ViewportPx;
use stylesheets::Stylesheet;
use thread_state;
use workqueue::WorkQueue;
-pub struct PerDocumentStyleData {
+pub struct PerDocumentStyleDataImpl {
/// Rule processor.
pub stylist: Arc<Stylist>,
/// List of stylesheets, mirrored from Gecko.
pub stylesheets: Vec<Arc<Stylesheet>>,
/// Whether the stylesheets list above has changed since the last restyle.
pub stylesheets_changed: bool,
@@ -39,50 +40,62 @@ pub struct PerDocumentStyleData {
pub expired_animations: Arc<RwLock<HashMap<OpaqueNode, Vec<Animation>>>>,
// FIXME(bholley): This shouldn't be per-document.
pub work_queue: Option<WorkQueue<SharedStyleContext, WorkQueueData>>,
pub num_threads: usize,
}
+pub struct PerDocumentStyleData(AtomicRefCell<PerDocumentStyleDataImpl>);
+
lazy_static! {
pub static ref NUM_THREADS: usize = {
match env::var("STYLO_THREADS").map(|s| s.parse::<usize>().expect("invalid STYLO_THREADS")) {
Ok(num) => num,
_ => cmp::max(num_cpus::get() * 3 / 4, 1),
}
};
}
impl PerDocumentStyleData {
- pub fn new() -> PerDocumentStyleData {
+ pub fn new() -> Self {
// FIXME(bholley): Real window size.
let window_size: TypedSize2D<f32, ViewportPx> = TypedSize2D::new(800.0, 600.0);
let device = Device::new(MediaType::Screen, window_size);
let (new_anims_sender, new_anims_receiver) = channel();
- PerDocumentStyleData {
+ PerDocumentStyleData(AtomicRefCell::new(PerDocumentStyleDataImpl {
stylist: Arc::new(Stylist::new(device)),
stylesheets: vec![],
stylesheets_changed: true,
new_animations_sender: new_anims_sender,
new_animations_receiver: new_anims_receiver,
running_animations: Arc::new(RwLock::new(HashMap::new())),
expired_animations: Arc::new(RwLock::new(HashMap::new())),
work_queue: if *NUM_THREADS <= 1 {
None
} else {
WorkQueue::new("StyleWorker", thread_state::LAYOUT, *NUM_THREADS).ok()
},
num_threads: *NUM_THREADS,
- }
+ }))
+ }
+
+ pub fn borrow(&self) -> AtomicRef<PerDocumentStyleDataImpl> {
+ self.0.borrow()
}
+ pub fn borrow_mut(&self) -> AtomicRefMut<PerDocumentStyleDataImpl> {
+ self.0.borrow_mut()
+ }
+}
+
+impl PerDocumentStyleDataImpl {
pub fn flush_stylesheets(&mut self) {
// The stylist wants to be flushed if either the stylesheets change or the
// device dimensions change. When we add support for media queries, we'll
// need to detect the latter case and trigger a flush as well.
if self.stylesheets_changed {
let _ = Arc::get_mut(&mut self.stylist).unwrap()
.update(&self.stylesheets, None, true);
self.stylesheets_changed = false;
@@ -91,15 +104,15 @@ impl PerDocumentStyleData {
}
unsafe impl HasFFI for PerDocumentStyleData {
type FFIType = RawServoStyleSet;
}
unsafe impl HasSimpleFFI for PerDocumentStyleData {}
unsafe impl HasBoxFFI for PerDocumentStyleData {}
-impl Drop for PerDocumentStyleData {
+impl Drop for PerDocumentStyleDataImpl {
fn drop(&mut self) {
if let Some(ref mut queue) = self.work_queue {
queue.shutdown();
}
}
}
--- a/servo/components/style/gecko_bindings/bindings.rs
+++ b/servo/components/style/gecko_bindings/bindings.rs
@@ -827,31 +827,31 @@ extern "C" {
}
extern "C" {
pub fn Servo_StyleSet_Init() -> RawServoStyleSetOwned;
}
extern "C" {
pub fn Servo_StyleSet_Drop(set: RawServoStyleSetOwned);
}
extern "C" {
- pub fn Servo_StyleSet_AppendStyleSheet(set: RawServoStyleSetBorrowedMut,
+ pub fn Servo_StyleSet_AppendStyleSheet(set: RawServoStyleSetBorrowed,
sheet: RawServoStyleSheetBorrowed);
}
extern "C" {
- pub fn Servo_StyleSet_PrependStyleSheet(set: RawServoStyleSetBorrowedMut,
+ pub fn Servo_StyleSet_PrependStyleSheet(set: RawServoStyleSetBorrowed,
sheet:
RawServoStyleSheetBorrowed);
}
extern "C" {
- pub fn Servo_StyleSet_RemoveStyleSheet(set: RawServoStyleSetBorrowedMut,
+ pub fn Servo_StyleSet_RemoveStyleSheet(set: RawServoStyleSetBorrowed,
sheet: RawServoStyleSheetBorrowed);
}
extern "C" {
pub fn Servo_StyleSet_InsertStyleSheetBefore(set:
- RawServoStyleSetBorrowedMut,
+ RawServoStyleSetBorrowed,
sheet:
RawServoStyleSheetBorrowed,
reference:
RawServoStyleSheetBorrowed);
}
extern "C" {
pub fn Servo_ParseProperty(property_bytes: *const u8,
property_length: u32, value_bytes: *const u8,
@@ -913,27 +913,27 @@ extern "C" {
pub fn Servo_ComputedValues_Get(node: RawGeckoNodeBorrowed)
-> ServoComputedValuesStrong;
}
extern "C" {
pub fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null:
ServoComputedValuesBorrowedOrNull,
pseudoTag: *mut nsIAtom,
set:
- RawServoStyleSetBorrowedMut)
+ RawServoStyleSetBorrowed)
-> ServoComputedValuesStrong;
}
extern "C" {
pub fn Servo_ComputedValues_GetForPseudoElement(parent_style:
ServoComputedValuesBorrowed,
match_element:
RawGeckoElementBorrowed,
pseudo_tag: *mut nsIAtom,
set:
- RawServoStyleSetBorrowedMut,
+ RawServoStyleSetBorrowed,
is_probe: bool)
-> ServoComputedValuesStrong;
}
extern "C" {
pub fn Servo_ComputedValues_Inherit(parent_style:
ServoComputedValuesBorrowedOrNull)
-> ServoComputedValuesStrong;
}
@@ -954,17 +954,17 @@ extern "C" {
extern "C" {
pub fn Servo_ComputeRestyleHint(element: RawGeckoElementBorrowed,
snapshot: *mut ServoElementSnapshot,
set: RawServoStyleSetBorrowed)
-> nsRestyleHint;
}
extern "C" {
pub fn Servo_RestyleSubtree(node: RawGeckoNodeBorrowed,
- set: RawServoStyleSetBorrowedMut);
+ set: RawServoStyleSetBorrowed);
}
extern "C" {
pub fn Servo_GetStyleFont(computed_values:
ServoComputedValuesBorrowedOrNull)
-> *const nsStyleFont;
}
extern "C" {
pub fn Servo_GetStyleColor(computed_values:
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -10,17 +10,17 @@ use parking_lot::RwLock;
use std::mem::transmute;
use std::ptr;
use std::slice;
use std::str::from_utf8_unchecked;
use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
use style::arc_ptr_eq;
use style::context::{LocalStyleContextCreationInfo, ReflowGoal, SharedStyleContext};
-use style::dom::{NodeInfo, TDocument, TElement, TNode};
+use style::dom::{NodeInfo, TElement, TNode};
use style::error_reporting::StdoutErrorReporter;
use style::gecko::data::{NUM_THREADS, PerDocumentStyleData};
use style::gecko::selector_impl::{GeckoSelectorImpl, PseudoElement};
use style::gecko::snapshot::GeckoElementSnapshot;
use style::gecko::traversal::RecalcStyleOnly;
use style::gecko::wrapper::{DUMMY_BASE_URL, GeckoDeclarationBlock};
use style::gecko::wrapper::{GeckoElement, GeckoNode};
use style::gecko_bindings::bindings::{RawGeckoElementBorrowed, RawGeckoNodeBorrowed};
@@ -85,17 +85,17 @@ fn restyle_subtree(node: GeckoNode, raw_
//
// FIXME(bholley): this should move into Servo_Initialize as soon as we get
// rid of the HackilyFindSomeDeviceContext stuff that happens during
// initial_values computation, since that stuff needs to be called further
// along in startup than the sensible place to call Servo_Initialize.
ComputedValues::initial_values();
// The stylist consumes stylesheets lazily.
- let per_doc_data = PerDocumentStyleData::from_ffi_mut(raw_data);
+ let mut per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
per_doc_data.flush_stylesheets();
let local_context_data =
LocalStyleContextCreationInfo::new(per_doc_data.new_animations_sender.clone());
let shared_style_context = SharedStyleContext {
// FIXME (bug 1303229): Use the actual viewport size here
viewport_size: Size2D::new(Au(0), Au(0)),
@@ -197,50 +197,50 @@ pub extern "C" fn Servo_StyleSheet_FromU
unsafe {
transmute(sheet)
}
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_AppendStyleSheet(raw_data: RawServoStyleSetBorrowedMut,
raw_sheet: RawServoStyleSheetBorrowed) {
- let data = PerDocumentStyleData::from_ffi_mut(raw_data);
+ let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
let sheet = HasArcFFI::as_arc(&raw_sheet);
data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet));
data.stylesheets.push(sheet.clone());
data.stylesheets_changed = true;
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_PrependStyleSheet(raw_data: RawServoStyleSetBorrowedMut,
raw_sheet: RawServoStyleSheetBorrowed) {
- let data = PerDocumentStyleData::from_ffi_mut(raw_data);
+ let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
let sheet = HasArcFFI::as_arc(&raw_sheet);
data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet));
data.stylesheets.insert(0, sheet.clone());
data.stylesheets_changed = true;
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(raw_data: RawServoStyleSetBorrowedMut,
raw_sheet: RawServoStyleSheetBorrowed,
raw_reference: RawServoStyleSheetBorrowed) {
- let data = PerDocumentStyleData::from_ffi_mut(raw_data);
+ let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
let sheet = HasArcFFI::as_arc(&raw_sheet);
let reference = HasArcFFI::as_arc(&raw_reference);
data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet));
let index = data.stylesheets.iter().position(|x| arc_ptr_eq(x, reference)).unwrap();
data.stylesheets.insert(index, sheet.clone());
data.stylesheets_changed = true;
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_RemoveStyleSheet(raw_data: RawServoStyleSetBorrowedMut,
raw_sheet: RawServoStyleSheetBorrowed) {
- let data = PerDocumentStyleData::from_ffi_mut(raw_data);
+ let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
let sheet = HasArcFFI::as_arc(&raw_sheet);
data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet));
data.stylesheets_changed = true;
}
#[no_mangle]
pub extern "C" fn Servo_StyleSheet_HasRules(raw_sheet: RawServoStyleSheetBorrowed) -> bool {
!Stylesheet::as_arc(&raw_sheet).rules.is_empty()
@@ -275,17 +275,17 @@ pub extern "C" fn Servo_ComputedValues_G
}
#[no_mangle]
pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesBorrowedOrNull,
pseudo_tag: *mut nsIAtom,
raw_data: RawServoStyleSetBorrowedMut)
-> ServoComputedValuesStrong {
// The stylist consumes stylesheets lazily.
- let data = PerDocumentStyleData::from_ffi_mut(raw_data);
+ let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
data.flush_stylesheets();
let atom = Atom::from(pseudo_tag);
let pseudo = PseudoElement::from_atom_unchecked(atom, /* anon_box = */ true);
let maybe_parent = ComputedValues::arc_from_borrowed(&parent_style_or_null);
let new_computed = data.stylist.precomputed_values_for_pseudo(&pseudo, maybe_parent);
@@ -308,17 +308,17 @@ pub extern "C" fn Servo_ComputedValues_G
ComputedValues::as_arc(&parent_style).clone().into_strong()
}
};
let atom = Atom::from(pseudo_tag);
let pseudo = PseudoElement::from_atom_unchecked(atom, /* anon_box = */ false);
// The stylist consumes stylesheets lazily.
- let data = PerDocumentStyleData::from_ffi_mut(raw_data);
+ let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
data.flush_stylesheets();
let element = GeckoElement(match_element);
match GeckoSelectorImpl::pseudo_element_cascade_type(&pseudo) {
PseudoElementCascadeType::Eager => {
let node = element.as_node();
@@ -516,17 +516,17 @@ pub extern "C" fn Servo_CSSSupports(prop
Err(()) => false,
}
}
#[no_mangle]
pub extern "C" fn Servo_ComputeRestyleHint(element: RawGeckoElementBorrowed,
snapshot: *mut ServoElementSnapshot,
raw_data: RawServoStyleSetBorrowed) -> nsRestyleHint {
- let per_doc_data = PerDocumentStyleData::from_ffi(raw_data);
+ let per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
let snapshot = unsafe { GeckoElementSnapshot::from_raw(snapshot) };
let element = GeckoElement(element);
// NB: This involves an FFI call, we can get rid of it easily if needed.
let current_state = element.get_state();
let hint = per_doc_data.stylist
.compute_restyle_hint(&element, &snapshot,