mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Move all PropertyDeclarationBlock from RwLock<_> to Locked<_>
This commit is contained in:
parent
aeffca2a59
commit
1bacd0eb15
28 changed files with 321 additions and 208 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -928,9 +928,7 @@ dependencies = [
|
||||||
"lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"selectors 0.18.0",
|
"selectors 0.18.0",
|
||||||
"servo_url 0.0.1",
|
"servo_url 0.0.1",
|
||||||
"style 0.0.1",
|
"style 0.0.1",
|
||||||
|
@ -2756,6 +2754,7 @@ dependencies = [
|
||||||
"nsstring_vendor 0.1.0",
|
"nsstring_vendor 0.1.0",
|
||||||
"num-integer 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-integer 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pdqsort 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pdqsort 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -562,7 +562,7 @@ unsafe impl JSTraceable for StyleLocked<ViewportRule> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl JSTraceable for RwLock<PropertyDeclarationBlock> {
|
unsafe impl JSTraceable for StyleLocked<PropertyDeclarationBlock> {
|
||||||
unsafe fn trace(&self, _trc: *mut JSTracer) {
|
unsafe fn trace(&self, _trc: *mut JSTracer) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,7 @@ use dom::window::Window;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use style::keyframes::Keyframe;
|
use style::keyframes::Keyframe;
|
||||||
use style::shared_lock::Locked;
|
use style::shared_lock::{Locked, ToCssWithGuard};
|
||||||
use style_traits::ToCss;
|
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct CSSKeyframeRule {
|
pub struct CSSKeyframeRule {
|
||||||
|
@ -70,6 +69,6 @@ impl SpecificCSSRule for CSSKeyframeRule {
|
||||||
|
|
||||||
fn get_css(&self) -> DOMString {
|
fn get_css(&self) -> DOMString {
|
||||||
let guard = self.cssrule.shared_lock().read();
|
let guard = self.cssrule.shared_lock().read();
|
||||||
self.keyframerule.read_with(&guard).to_css_string().into()
|
self.keyframerule.read_with(&guard).to_css_string(&guard).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,9 @@ use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object};
|
||||||
use dom::bindings::str::DOMString;
|
use dom::bindings::str::DOMString;
|
||||||
use dom::cssrule::CSSRule;
|
use dom::cssrule::CSSRule;
|
||||||
use dom::element::Element;
|
use dom::element::Element;
|
||||||
use dom::node::{Node, window_from_node};
|
use dom::node::{Node, window_from_node, document_from_node};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use parking_lot::RwLock;
|
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -23,6 +22,7 @@ use style::parser::ParserContextExtraData;
|
||||||
use style::properties::{Importance, PropertyDeclarationBlock, PropertyId, LonghandId, ShorthandId};
|
use style::properties::{Importance, PropertyDeclarationBlock, PropertyId, LonghandId, ShorthandId};
|
||||||
use style::properties::{parse_one_declaration, parse_style_attribute};
|
use style::properties::{parse_one_declaration, parse_style_attribute};
|
||||||
use style::selector_parser::PseudoElement;
|
use style::selector_parser::PseudoElement;
|
||||||
|
use style::shared_lock::Locked;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
|
|
||||||
// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
|
// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
|
||||||
|
@ -40,7 +40,7 @@ pub enum CSSStyleOwner {
|
||||||
Element(JS<Element>),
|
Element(JS<Element>),
|
||||||
CSSRule(JS<CSSRule>,
|
CSSRule(JS<CSSRule>,
|
||||||
#[ignore_heap_size_of = "Arc"]
|
#[ignore_heap_size_of = "Arc"]
|
||||||
Arc<RwLock<PropertyDeclarationBlock>>),
|
Arc<Locked<PropertyDeclarationBlock>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CSSStyleOwner {
|
impl CSSStyleOwner {
|
||||||
|
@ -55,10 +55,13 @@ impl CSSStyleOwner {
|
||||||
let mut changed = true;
|
let mut changed = true;
|
||||||
match *self {
|
match *self {
|
||||||
CSSStyleOwner::Element(ref el) => {
|
CSSStyleOwner::Element(ref el) => {
|
||||||
|
let document = document_from_node(&**el);
|
||||||
|
let shared_lock = document.style_shared_lock();
|
||||||
let mut attr = el.style_attribute().borrow_mut().take();
|
let mut attr = el.style_attribute().borrow_mut().take();
|
||||||
let result = if attr.is_some() {
|
let result = if attr.is_some() {
|
||||||
let lock = attr.as_ref().unwrap();
|
let lock = attr.as_ref().unwrap();
|
||||||
let mut pdb = lock.write();
|
let mut guard = shared_lock.write();
|
||||||
|
let mut pdb = lock.write_with(&mut guard);
|
||||||
let result = f(&mut pdb, &mut changed);
|
let result = f(&mut pdb, &mut changed);
|
||||||
result
|
result
|
||||||
} else {
|
} else {
|
||||||
|
@ -69,7 +72,7 @@ impl CSSStyleOwner {
|
||||||
// exact conditions under it changes.
|
// exact conditions under it changes.
|
||||||
changed = !pdb.declarations().is_empty();
|
changed = !pdb.declarations().is_empty();
|
||||||
if changed {
|
if changed {
|
||||||
attr = Some(Arc::new(RwLock::new(pdb)));
|
attr = Some(Arc::new(shared_lock.wrap(pdb)));
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
|
@ -83,7 +86,8 @@ impl CSSStyleOwner {
|
||||||
//
|
//
|
||||||
// [1]: https://github.com/whatwg/html/issues/2306
|
// [1]: https://github.com/whatwg/html/issues/2306
|
||||||
if let Some(pdb) = attr {
|
if let Some(pdb) = attr {
|
||||||
let serialization = pdb.read().to_css_string();
|
let guard = shared_lock.read();
|
||||||
|
let serialization = pdb.read_with(&guard).to_css_string();
|
||||||
el.set_attribute(&local_name!("style"),
|
el.set_attribute(&local_name!("style"),
|
||||||
AttrValue::Declaration(serialization,
|
AttrValue::Declaration(serialization,
|
||||||
pdb));
|
pdb));
|
||||||
|
@ -96,7 +100,10 @@ impl CSSStyleOwner {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
CSSStyleOwner::CSSRule(ref rule, ref pdb) => {
|
CSSStyleOwner::CSSRule(ref rule, ref pdb) => {
|
||||||
let result = f(&mut *pdb.write(), &mut changed);
|
let result = {
|
||||||
|
let mut guard = rule.shared_lock().write();
|
||||||
|
f(&mut *pdb.write_with(&mut guard), &mut changed)
|
||||||
|
};
|
||||||
if changed {
|
if changed {
|
||||||
rule.global().as_window().Document().invalidate_stylesheets();
|
rule.global().as_window().Document().invalidate_stylesheets();
|
||||||
}
|
}
|
||||||
|
@ -111,15 +118,20 @@ impl CSSStyleOwner {
|
||||||
match *self {
|
match *self {
|
||||||
CSSStyleOwner::Element(ref el) => {
|
CSSStyleOwner::Element(ref el) => {
|
||||||
match *el.style_attribute().borrow() {
|
match *el.style_attribute().borrow() {
|
||||||
Some(ref pdb) => f(&pdb.read()),
|
Some(ref pdb) => {
|
||||||
|
let document = document_from_node(&**el);
|
||||||
|
let guard = document.style_shared_lock().read();
|
||||||
|
f(pdb.read_with(&guard))
|
||||||
|
}
|
||||||
None => {
|
None => {
|
||||||
let pdb = PropertyDeclarationBlock::new();
|
let pdb = PropertyDeclarationBlock::new();
|
||||||
f(&pdb)
|
f(&pdb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CSSStyleOwner::CSSRule(_, ref pdb) => {
|
CSSStyleOwner::CSSRule(ref rule, ref pdb) => {
|
||||||
f(&pdb.read())
|
let guard = rule.shared_lock().read();
|
||||||
|
f(pdb.read_with(&guard))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,6 @@ use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode};
|
||||||
use html5ever_atoms::{Prefix, LocalName, Namespace, QualName};
|
use html5ever_atoms::{Prefix, LocalName, Namespace, QualName};
|
||||||
use js::jsapi::{HandleValue, JSAutoCompartment};
|
use js::jsapi::{HandleValue, JSAutoCompartment};
|
||||||
use net_traits::request::CorsSettings;
|
use net_traits::request::CorsSettings;
|
||||||
use parking_lot::RwLock;
|
|
||||||
use ref_filter_map::ref_filter_map;
|
use ref_filter_map::ref_filter_map;
|
||||||
use script_layout_interface::message::ReflowQueryType;
|
use script_layout_interface::message::ReflowQueryType;
|
||||||
use script_thread::Runnable;
|
use script_thread::Runnable;
|
||||||
|
@ -108,6 +107,7 @@ use style::properties::longhands::{self, background_image, border_spacing, font_
|
||||||
use style::restyle_hints::RESTYLE_SELF;
|
use style::restyle_hints::RESTYLE_SELF;
|
||||||
use style::rule_tree::CascadeLevel;
|
use style::rule_tree::CascadeLevel;
|
||||||
use style::selector_parser::{NonTSPseudoClass, RestyleDamage, SelectorImpl, SelectorParser};
|
use style::selector_parser::{NonTSPseudoClass, RestyleDamage, SelectorImpl, SelectorParser};
|
||||||
|
use style::shared_lock::{SharedRwLock, Locked};
|
||||||
use style::sink::Push;
|
use style::sink::Push;
|
||||||
use style::stylist::ApplicableDeclarationBlock;
|
use style::stylist::ApplicableDeclarationBlock;
|
||||||
use style::thread_state;
|
use style::thread_state;
|
||||||
|
@ -129,7 +129,7 @@ pub struct Element {
|
||||||
attrs: DOMRefCell<Vec<JS<Attr>>>,
|
attrs: DOMRefCell<Vec<JS<Attr>>>,
|
||||||
id_attribute: DOMRefCell<Option<Atom>>,
|
id_attribute: DOMRefCell<Option<Atom>>,
|
||||||
#[ignore_heap_size_of = "Arc"]
|
#[ignore_heap_size_of = "Arc"]
|
||||||
style_attribute: DOMRefCell<Option<Arc<RwLock<PropertyDeclarationBlock>>>>,
|
style_attribute: DOMRefCell<Option<Arc<Locked<PropertyDeclarationBlock>>>>,
|
||||||
attr_list: MutNullableJS<NamedNodeMap>,
|
attr_list: MutNullableJS<NamedNodeMap>,
|
||||||
class_list: MutNullableJS<DOMTokenList>,
|
class_list: MutNullableJS<DOMTokenList>,
|
||||||
state: Cell<ElementState>,
|
state: Cell<ElementState>,
|
||||||
|
@ -352,7 +352,7 @@ pub trait LayoutElementHelpers {
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe fn html_element_in_html_document_for_layout(&self) -> bool;
|
unsafe fn html_element_in_html_document_for_layout(&self) -> bool;
|
||||||
fn id_attribute(&self) -> *const Option<Atom>;
|
fn id_attribute(&self) -> *const Option<Atom>;
|
||||||
fn style_attribute(&self) -> *const Option<Arc<RwLock<PropertyDeclarationBlock>>>;
|
fn style_attribute(&self) -> *const Option<Arc<Locked<PropertyDeclarationBlock>>>;
|
||||||
fn local_name(&self) -> &LocalName;
|
fn local_name(&self) -> &LocalName;
|
||||||
fn namespace(&self) -> &Namespace;
|
fn namespace(&self) -> &Namespace;
|
||||||
fn get_lang_for_layout(&self) -> String;
|
fn get_lang_for_layout(&self) -> String;
|
||||||
|
@ -384,14 +384,18 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
where V: Push<ApplicableDeclarationBlock>
|
where V: Push<ApplicableDeclarationBlock>
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_declaration(declaration: PropertyDeclaration) -> ApplicableDeclarationBlock {
|
fn from_declaration(shared_lock: &SharedRwLock, declaration: PropertyDeclaration)
|
||||||
|
-> ApplicableDeclarationBlock {
|
||||||
ApplicableDeclarationBlock::from_declarations(
|
ApplicableDeclarationBlock::from_declarations(
|
||||||
Arc::new(RwLock::new(PropertyDeclarationBlock::with_one(
|
Arc::new(shared_lock.wrap(PropertyDeclarationBlock::with_one(
|
||||||
declaration, Importance::Normal
|
declaration, Importance::Normal
|
||||||
))),
|
))),
|
||||||
CascadeLevel::PresHints)
|
CascadeLevel::PresHints)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let document = self.upcast::<Node>().owner_doc_for_layout();
|
||||||
|
let shared_lock = document.style_shared_lock();
|
||||||
|
|
||||||
let bgcolor = if let Some(this) = self.downcast::<HTMLBodyElement>() {
|
let bgcolor = if let Some(this) = self.downcast::<HTMLBodyElement>() {
|
||||||
this.get_background_color()
|
this.get_background_color()
|
||||||
} else if let Some(this) = self.downcast::<HTMLTableElement>() {
|
} else if let Some(this) = self.downcast::<HTMLTableElement>() {
|
||||||
|
@ -408,6 +412,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
|
|
||||||
if let Some(color) = bgcolor {
|
if let Some(color) = bgcolor {
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
|
shared_lock,
|
||||||
PropertyDeclaration::BackgroundColor(
|
PropertyDeclaration::BackgroundColor(
|
||||||
CSSColor { parsed: Color::RGBA(color), authored: None })));
|
CSSColor { parsed: Color::RGBA(color), authored: None })));
|
||||||
}
|
}
|
||||||
|
@ -420,6 +425,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
|
|
||||||
if let Some(url) = background {
|
if let Some(url) = background {
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
|
shared_lock,
|
||||||
PropertyDeclaration::BackgroundImage(
|
PropertyDeclaration::BackgroundImage(
|
||||||
background_image::SpecifiedValue(vec![
|
background_image::SpecifiedValue(vec![
|
||||||
background_image::single_value::SpecifiedValue(Some(
|
background_image::single_value::SpecifiedValue(Some(
|
||||||
|
@ -442,6 +448,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
|
|
||||||
if let Some(color) = color {
|
if let Some(color) = color {
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
|
shared_lock,
|
||||||
PropertyDeclaration::Color(
|
PropertyDeclaration::Color(
|
||||||
longhands::color::SpecifiedValue(CSSColor {
|
longhands::color::SpecifiedValue(CSSColor {
|
||||||
parsed: Color::RGBA(color),
|
parsed: Color::RGBA(color),
|
||||||
|
@ -459,6 +466,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
|
|
||||||
if let Some(font_family) = font_family {
|
if let Some(font_family) = font_family {
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
|
shared_lock,
|
||||||
PropertyDeclaration::FontFamily(
|
PropertyDeclaration::FontFamily(
|
||||||
font_family::computed_value::T(vec![
|
font_family::computed_value::T(vec![
|
||||||
font_family::computed_value::FontFamily::from_atom(
|
font_family::computed_value::FontFamily::from_atom(
|
||||||
|
@ -469,6 +477,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
|
|
||||||
if let Some(font_size) = font_size {
|
if let Some(font_size) = font_size {
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
|
shared_lock,
|
||||||
PropertyDeclaration::FontSize(font_size::SpecifiedValue(font_size.into()))))
|
PropertyDeclaration::FontSize(font_size::SpecifiedValue(font_size.into()))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,6 +490,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
if let Some(cellspacing) = cellspacing {
|
if let Some(cellspacing) = cellspacing {
|
||||||
let width_value = specified::Length::from_px(cellspacing as f32);
|
let width_value = specified::Length::from_px(cellspacing as f32);
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
|
shared_lock,
|
||||||
PropertyDeclaration::BorderSpacing(
|
PropertyDeclaration::BorderSpacing(
|
||||||
Box::new(border_spacing::SpecifiedValue {
|
Box::new(border_spacing::SpecifiedValue {
|
||||||
horizontal: width_value.clone(),
|
horizontal: width_value.clone(),
|
||||||
|
@ -514,6 +524,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
if let Some(size) = size {
|
if let Some(size) = size {
|
||||||
let value = specified::NoCalcLength::ServoCharacterWidth(specified::CharacterWidth(size));
|
let value = specified::NoCalcLength::ServoCharacterWidth(specified::CharacterWidth(size));
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
|
shared_lock,
|
||||||
PropertyDeclaration::Width(
|
PropertyDeclaration::Width(
|
||||||
specified::LengthOrPercentageOrAuto::Length(value))));
|
specified::LengthOrPercentageOrAuto::Length(value))));
|
||||||
}
|
}
|
||||||
|
@ -539,12 +550,14 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
let width_value =
|
let width_value =
|
||||||
specified::LengthOrPercentageOrAuto::Percentage(specified::Percentage(percentage));
|
specified::LengthOrPercentageOrAuto::Percentage(specified::Percentage(percentage));
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
|
shared_lock,
|
||||||
PropertyDeclaration::Width(width_value)));
|
PropertyDeclaration::Width(width_value)));
|
||||||
}
|
}
|
||||||
LengthOrPercentageOrAuto::Length(length) => {
|
LengthOrPercentageOrAuto::Length(length) => {
|
||||||
let width_value = specified::LengthOrPercentageOrAuto::Length(
|
let width_value = specified::LengthOrPercentageOrAuto::Length(
|
||||||
specified::NoCalcLength::Absolute(length));
|
specified::NoCalcLength::Absolute(length));
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
|
shared_lock,
|
||||||
PropertyDeclaration::Width(width_value)));
|
PropertyDeclaration::Width(width_value)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -564,12 +577,14 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
let height_value =
|
let height_value =
|
||||||
specified::LengthOrPercentageOrAuto::Percentage(specified::Percentage(percentage));
|
specified::LengthOrPercentageOrAuto::Percentage(specified::Percentage(percentage));
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
|
shared_lock,
|
||||||
PropertyDeclaration::Height(height_value)));
|
PropertyDeclaration::Height(height_value)));
|
||||||
}
|
}
|
||||||
LengthOrPercentageOrAuto::Length(length) => {
|
LengthOrPercentageOrAuto::Length(length) => {
|
||||||
let height_value = specified::LengthOrPercentageOrAuto::Length(
|
let height_value = specified::LengthOrPercentageOrAuto::Length(
|
||||||
specified::NoCalcLength::Absolute(length));
|
specified::NoCalcLength::Absolute(length));
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
|
shared_lock,
|
||||||
PropertyDeclaration::Height(height_value)));
|
PropertyDeclaration::Height(height_value)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -592,6 +607,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
// https://html.spec.whatwg.org/multipage/#textarea-effective-width
|
// https://html.spec.whatwg.org/multipage/#textarea-effective-width
|
||||||
let value = specified::NoCalcLength::ServoCharacterWidth(specified::CharacterWidth(cols));
|
let value = specified::NoCalcLength::ServoCharacterWidth(specified::CharacterWidth(cols));
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
|
shared_lock,
|
||||||
PropertyDeclaration::Width(specified::LengthOrPercentageOrAuto::Length(value))));
|
PropertyDeclaration::Width(specified::LengthOrPercentageOrAuto::Length(value))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -610,6 +626,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
// https://html.spec.whatwg.org/multipage/#textarea-effective-height
|
// https://html.spec.whatwg.org/multipage/#textarea-effective-height
|
||||||
let value = specified::NoCalcLength::FontRelative(specified::FontRelativeLength::Em(rows as CSSFloat));
|
let value = specified::NoCalcLength::FontRelative(specified::FontRelativeLength::Em(rows as CSSFloat));
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
|
shared_lock,
|
||||||
PropertyDeclaration::Height(specified::LengthOrPercentageOrAuto::Length(value))));
|
PropertyDeclaration::Height(specified::LengthOrPercentageOrAuto::Length(value))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,12 +640,16 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
if let Some(border) = border {
|
if let Some(border) = border {
|
||||||
let width_value = specified::BorderWidth::from_length(specified::Length::from_px(border as f32));
|
let width_value = specified::BorderWidth::from_length(specified::Length::from_px(border as f32));
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
|
shared_lock,
|
||||||
PropertyDeclaration::BorderTopWidth(Box::new(width_value.clone()))));
|
PropertyDeclaration::BorderTopWidth(Box::new(width_value.clone()))));
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
|
shared_lock,
|
||||||
PropertyDeclaration::BorderLeftWidth(Box::new(width_value.clone()))));
|
PropertyDeclaration::BorderLeftWidth(Box::new(width_value.clone()))));
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
|
shared_lock,
|
||||||
PropertyDeclaration::BorderBottomWidth(Box::new(width_value.clone()))));
|
PropertyDeclaration::BorderBottomWidth(Box::new(width_value.clone()))));
|
||||||
hints.push(from_declaration(
|
hints.push(from_declaration(
|
||||||
|
shared_lock,
|
||||||
PropertyDeclaration::BorderRightWidth(Box::new(width_value))));
|
PropertyDeclaration::BorderRightWidth(Box::new(width_value))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -672,7 +693,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn style_attribute(&self) -> *const Option<Arc<RwLock<PropertyDeclarationBlock>>> {
|
fn style_attribute(&self) -> *const Option<Arc<Locked<PropertyDeclarationBlock>>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
(*self.unsafe_get()).style_attribute.borrow_for_layout()
|
(*self.unsafe_get()).style_attribute.borrow_for_layout()
|
||||||
}
|
}
|
||||||
|
@ -835,7 +856,7 @@ impl Element {
|
||||||
ns!()
|
ns!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn style_attribute(&self) -> &DOMRefCell<Option<Arc<RwLock<PropertyDeclarationBlock>>>> {
|
pub fn style_attribute(&self) -> &DOMRefCell<Option<Arc<Locked<PropertyDeclarationBlock>>>> {
|
||||||
&self.style_attribute
|
&self.style_attribute
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2170,7 +2191,7 @@ impl VirtualMethods for Element {
|
||||||
block
|
block
|
||||||
} else {
|
} else {
|
||||||
let win = window_from_node(self);
|
let win = window_from_node(self);
|
||||||
Arc::new(RwLock::new(parse_style_attribute(
|
Arc::new(doc.style_shared_lock().wrap(parse_style_attribute(
|
||||||
&attr.value(),
|
&attr.value(),
|
||||||
&doc.base_url(),
|
&doc.base_url(),
|
||||||
win.css_error_reporter(),
|
win.css_error_reporter(),
|
||||||
|
|
|
@ -44,7 +44,6 @@ use dom::text::Text;
|
||||||
use gfx_traits::ByteIndex;
|
use gfx_traits::ByteIndex;
|
||||||
use html5ever_atoms::{LocalName, Namespace};
|
use html5ever_atoms::{LocalName, Namespace};
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use parking_lot::RwLock;
|
|
||||||
use range::Range;
|
use range::Range;
|
||||||
use script_layout_interface::{HTMLCanvasData, LayoutNodeType, SVGSVGData, TrustedNodeAddress};
|
use script_layout_interface::{HTMLCanvasData, LayoutNodeType, SVGSVGData, TrustedNodeAddress};
|
||||||
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialPersistentLayoutData};
|
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialPersistentLayoutData};
|
||||||
|
@ -69,7 +68,7 @@ use style::dom::UnsafeNode;
|
||||||
use style::element_state::*;
|
use style::element_state::*;
|
||||||
use style::properties::{ComputedValues, PropertyDeclarationBlock};
|
use style::properties::{ComputedValues, PropertyDeclarationBlock};
|
||||||
use style::selector_parser::{NonTSPseudoClass, PseudoElement, SelectorImpl};
|
use style::selector_parser::{NonTSPseudoClass, PseudoElement, SelectorImpl};
|
||||||
use style::shared_lock::SharedRwLock as StyleSharedRwLock;
|
use style::shared_lock::{SharedRwLock as StyleSharedRwLock, Locked as StyleLocked};
|
||||||
use style::sink::Push;
|
use style::sink::Push;
|
||||||
use style::str::is_whitespace;
|
use style::str::is_whitespace;
|
||||||
use style::stylist::ApplicableDeclarationBlock;
|
use style::stylist::ApplicableDeclarationBlock;
|
||||||
|
@ -377,7 +376,7 @@ impl<'le> TElement for ServoLayoutElement<'le> {
|
||||||
ServoLayoutNode::from_layout_js(self.element.upcast())
|
ServoLayoutNode::from_layout_js(self.element.upcast())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn style_attribute(&self) -> Option<&Arc<RwLock<PropertyDeclarationBlock>>> {
|
fn style_attribute(&self) -> Option<&Arc<StyleLocked<PropertyDeclarationBlock>>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
(*self.element.style_attribute()).as_ref()
|
(*self.element.style_attribute()).as_ref()
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ path = "lib.rs"
|
||||||
doctest = false
|
doctest = false
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
gecko = ["nsstring_vendor", "rayon/unstable"]
|
gecko = ["nsstring_vendor", "rayon/unstable", "num_cpus"]
|
||||||
use_bindgen = ["bindgen", "regex"]
|
use_bindgen = ["bindgen", "regex"]
|
||||||
servo = ["serde/unstable", "serde", "serde_derive", "heapsize_derive",
|
servo = ["serde/unstable", "serde", "serde_derive", "heapsize_derive",
|
||||||
"style_traits/servo", "servo_atoms", "html5ever-atoms",
|
"style_traits/servo", "servo_atoms", "html5ever-atoms",
|
||||||
|
@ -37,6 +37,7 @@ lazy_static = "0.2"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
matches = "0.1"
|
matches = "0.1"
|
||||||
nsstring_vendor = {path = "gecko_bindings/nsstring_vendor", optional = true}
|
nsstring_vendor = {path = "gecko_bindings/nsstring_vendor", optional = true}
|
||||||
|
num_cpus = {version = "1.1.0", optional = true}
|
||||||
num-integer = "0.1.32"
|
num-integer = "0.1.32"
|
||||||
num-traits = "0.1.32"
|
num-traits = "0.1.32"
|
||||||
ordered-float = "0.4"
|
ordered-float = "0.4"
|
||||||
|
|
|
@ -415,7 +415,7 @@ fn compute_style_for_animation_step(context: &SharedStyleContext,
|
||||||
match step.value {
|
match step.value {
|
||||||
KeyframesStepValue::ComputedValues => style_from_cascade.clone(),
|
KeyframesStepValue::ComputedValues => style_from_cascade.clone(),
|
||||||
KeyframesStepValue::Declarations { block: ref declarations } => {
|
KeyframesStepValue::Declarations { block: ref declarations } => {
|
||||||
let guard = declarations.read();
|
let guard = declarations.read_with(context.guards.author);
|
||||||
|
|
||||||
// No !important in keyframes.
|
// No !important in keyframes.
|
||||||
debug_assert!(guard.declarations().iter()
|
debug_assert!(guard.declarations().iter()
|
||||||
|
|
|
@ -11,9 +11,9 @@ use app_units::Au;
|
||||||
use cssparser::{self, Color, RGBA};
|
use cssparser::{self, Color, RGBA};
|
||||||
use euclid::num::Zero;
|
use euclid::num::Zero;
|
||||||
use num_traits::ToPrimitive;
|
use num_traits::ToPrimitive;
|
||||||
use parking_lot::RwLock;
|
|
||||||
use properties::PropertyDeclarationBlock;
|
use properties::PropertyDeclarationBlock;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
|
use shared_lock::Locked;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -61,7 +61,7 @@ pub enum AttrValue {
|
||||||
/// declarationblock for longer than needed.
|
/// declarationblock for longer than needed.
|
||||||
Declaration(String,
|
Declaration(String,
|
||||||
#[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")]
|
#[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")]
|
||||||
Arc<RwLock<PropertyDeclarationBlock>>)
|
Arc<Locked<PropertyDeclarationBlock>>)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shared implementation to parse an integer according to
|
/// Shared implementation to parse an integer according to
|
||||||
|
|
|
@ -11,10 +11,10 @@ use {Atom, Namespace, LocalName};
|
||||||
use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
|
use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
|
||||||
use data::ElementData;
|
use data::ElementData;
|
||||||
use element_state::ElementState;
|
use element_state::ElementState;
|
||||||
use parking_lot::RwLock;
|
|
||||||
use properties::{ComputedValues, PropertyDeclarationBlock};
|
use properties::{ComputedValues, PropertyDeclarationBlock};
|
||||||
use selector_parser::{ElementExt, PreExistingComputedValues, PseudoElement};
|
use selector_parser::{ElementExt, PreExistingComputedValues, PseudoElement};
|
||||||
use selectors::matching::ElementSelectorFlags;
|
use selectors::matching::ElementSelectorFlags;
|
||||||
|
use shared_lock::Locked;
|
||||||
use sink::Push;
|
use sink::Push;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
@ -230,8 +230,8 @@ pub trait PresentationalHintsSynthetizer {
|
||||||
|
|
||||||
/// The animation rules. The first one is for Animation cascade level, and the second one is for
|
/// The animation rules. The first one is for Animation cascade level, and the second one is for
|
||||||
/// Transition cascade level.
|
/// Transition cascade level.
|
||||||
pub struct AnimationRules(pub Option<Arc<RwLock<PropertyDeclarationBlock>>>,
|
pub struct AnimationRules(pub Option<Arc<Locked<PropertyDeclarationBlock>>>,
|
||||||
pub Option<Arc<RwLock<PropertyDeclarationBlock>>>);
|
pub Option<Arc<Locked<PropertyDeclarationBlock>>>);
|
||||||
|
|
||||||
/// The element trait, the main abstraction the style crate acts over.
|
/// The element trait, the main abstraction the style crate acts over.
|
||||||
pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + PresentationalHintsSynthetizer {
|
pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + PresentationalHintsSynthetizer {
|
||||||
|
@ -252,7 +252,7 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get this element's style attribute.
|
/// Get this element's style attribute.
|
||||||
fn style_attribute(&self) -> Option<&Arc<RwLock<PropertyDeclarationBlock>>>;
|
fn style_attribute(&self) -> Option<&Arc<Locked<PropertyDeclarationBlock>>>;
|
||||||
|
|
||||||
/// Get this element's animation rules.
|
/// Get this element's animation rules.
|
||||||
fn get_animation_rules(&self, _pseudo: Option<&PseudoElement>) -> AnimationRules {
|
fn get_animation_rules(&self, _pseudo: Option<&PseudoElement>) -> AnimationRules {
|
||||||
|
@ -261,13 +261,13 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre
|
||||||
|
|
||||||
/// Get this element's animation rule.
|
/// Get this element's animation rule.
|
||||||
fn get_animation_rule(&self, _pseudo: Option<&PseudoElement>)
|
fn get_animation_rule(&self, _pseudo: Option<&PseudoElement>)
|
||||||
-> Option<Arc<RwLock<PropertyDeclarationBlock>>> {
|
-> Option<Arc<Locked<PropertyDeclarationBlock>>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get this element's transition rule.
|
/// Get this element's transition rule.
|
||||||
fn get_transition_rule(&self, _pseudo: Option<&PseudoElement>)
|
fn get_transition_rule(&self, _pseudo: Option<&PseudoElement>)
|
||||||
-> Option<Arc<RwLock<PropertyDeclarationBlock>>> {
|
-> Option<Arc<Locked<PropertyDeclarationBlock>>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ impl_arc_ffi!(Stylesheet => RawServoStyleSheet
|
||||||
impl_arc_ffi!(ComputedValues => ServoComputedValues
|
impl_arc_ffi!(ComputedValues => ServoComputedValues
|
||||||
[Servo_ComputedValues_AddRef, Servo_ComputedValues_Release]);
|
[Servo_ComputedValues_AddRef, Servo_ComputedValues_Release]);
|
||||||
|
|
||||||
impl_arc_ffi!(RwLock<PropertyDeclarationBlock> => RawServoDeclarationBlock
|
impl_arc_ffi!(Locked<PropertyDeclarationBlock> => RawServoDeclarationBlock
|
||||||
[Servo_DeclarationBlock_AddRef, Servo_DeclarationBlock_Release]);
|
[Servo_DeclarationBlock_AddRef, Servo_DeclarationBlock_Release]);
|
||||||
|
|
||||||
impl_arc_ffi!(Locked<StyleRule> => RawServoStyleRule
|
impl_arc_ffi!(Locked<StyleRule> => RawServoStyleRule
|
||||||
|
|
50
components/style/gecko/global_style_data.rs
Normal file
50
components/style/gecko/global_style_data.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
//! Global style data
|
||||||
|
|
||||||
|
use num_cpus;
|
||||||
|
use rayon;
|
||||||
|
use shared_lock::SharedRwLock;
|
||||||
|
use std::cmp;
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
/// Global style data
|
||||||
|
pub struct GlobalStyleData {
|
||||||
|
/// How many threads parallel styling can use.
|
||||||
|
pub num_threads: usize,
|
||||||
|
|
||||||
|
/// The parallel styling thread pool.
|
||||||
|
pub style_thread_pool: Option<rayon::ThreadPool>,
|
||||||
|
|
||||||
|
/// Shared RWLock for CSSOM objects
|
||||||
|
pub shared_lock: SharedRwLock,
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
/// Global style data
|
||||||
|
pub static ref GLOBAL_STYLE_DATA: GlobalStyleData = {
|
||||||
|
let stylo_threads = env::var("STYLO_THREADS")
|
||||||
|
.map(|s| s.parse::<usize>().expect("invalid STYLO_THREADS value"));
|
||||||
|
let num_threads = match stylo_threads {
|
||||||
|
Ok(num) => num,
|
||||||
|
_ => cmp::max(num_cpus::get() * 3 / 4, 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
let pool = if num_threads <= 1 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let configuration =
|
||||||
|
rayon::Configuration::new().set_num_threads(num_threads);
|
||||||
|
let pool = rayon::ThreadPool::new(configuration).ok();
|
||||||
|
pool
|
||||||
|
};
|
||||||
|
|
||||||
|
GlobalStyleData {
|
||||||
|
num_threads: num_threads,
|
||||||
|
style_thread_pool: pool,
|
||||||
|
shared_lock: SharedRwLock::new(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ mod non_ts_pseudo_class_list;
|
||||||
pub mod arc_types;
|
pub mod arc_types;
|
||||||
pub mod conversions;
|
pub mod conversions;
|
||||||
pub mod data;
|
pub mod data;
|
||||||
|
pub mod global_style_data;
|
||||||
pub mod media_queries;
|
pub mod media_queries;
|
||||||
pub mod restyle_damage;
|
pub mod restyle_damage;
|
||||||
pub mod selector_parser;
|
pub mod selector_parser;
|
||||||
|
|
|
@ -20,6 +20,7 @@ use dom::{AnimationRules, LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode}
|
||||||
use dom::{OpaqueNode, PresentationalHintsSynthetizer};
|
use dom::{OpaqueNode, PresentationalHintsSynthetizer};
|
||||||
use element_state::ElementState;
|
use element_state::ElementState;
|
||||||
use error_reporting::StdoutErrorReporter;
|
use error_reporting::StdoutErrorReporter;
|
||||||
|
use gecko::global_style_data::GLOBAL_STYLE_DATA;
|
||||||
use gecko::selector_parser::{SelectorImpl, NonTSPseudoClass, PseudoElement};
|
use gecko::selector_parser::{SelectorImpl, NonTSPseudoClass, PseudoElement};
|
||||||
use gecko::snapshot_helpers;
|
use gecko::snapshot_helpers;
|
||||||
use gecko_bindings::bindings;
|
use gecko_bindings::bindings;
|
||||||
|
@ -53,6 +54,7 @@ use selectors::Element;
|
||||||
use selectors::matching::{ElementSelectorFlags, StyleRelations, matches_complex_selector};
|
use selectors::matching::{ElementSelectorFlags, StyleRelations, matches_complex_selector};
|
||||||
use selectors::parser::{AttrSelector, NamespaceConstraint};
|
use selectors::parser::{AttrSelector, NamespaceConstraint};
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
|
use shared_lock::Locked;
|
||||||
use sink::Push;
|
use sink::Push;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
@ -407,12 +409,14 @@ fn selector_flags_to_node_flags(flags: ElementSelectorFlags) -> u32 {
|
||||||
fn get_animation_rule(element: &GeckoElement,
|
fn get_animation_rule(element: &GeckoElement,
|
||||||
pseudo: Option<&PseudoElement>,
|
pseudo: Option<&PseudoElement>,
|
||||||
cascade_level: CascadeLevel)
|
cascade_level: CascadeLevel)
|
||||||
-> Option<Arc<RwLock<PropertyDeclarationBlock>>> {
|
-> Option<Arc<Locked<PropertyDeclarationBlock>>> {
|
||||||
let atom_ptr = PseudoElement::ns_atom_or_null_from_opt(pseudo);
|
let atom_ptr = PseudoElement::ns_atom_or_null_from_opt(pseudo);
|
||||||
let animation_values = Arc::new(RwLock::new(AnimationValueMap::new()));
|
let animation_values = Arc::new(RwLock::new(AnimationValueMap::new()));
|
||||||
if unsafe { Gecko_GetAnimationRule(element.0, atom_ptr, cascade_level,
|
if unsafe { Gecko_GetAnimationRule(element.0, atom_ptr, cascade_level,
|
||||||
HasArcFFI::arc_as_borrowed(&animation_values)) } {
|
HasArcFFI::arc_as_borrowed(&animation_values)) } {
|
||||||
Some(Arc::new(RwLock::new(PropertyDeclarationBlock::from_animation_value_map(&animation_values.read()))))
|
let shared_lock = &GLOBAL_STYLE_DATA.shared_lock;
|
||||||
|
Some(Arc::new(shared_lock.wrap(
|
||||||
|
PropertyDeclarationBlock::from_animation_value_map(&animation_values.read()))))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -425,7 +429,7 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
unsafe { GeckoNode(&*(self.0 as *const _ as *const RawGeckoNode)) }
|
unsafe { GeckoNode(&*(self.0 as *const _ as *const RawGeckoNode)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn style_attribute(&self) -> Option<&Arc<RwLock<PropertyDeclarationBlock>>> {
|
fn style_attribute(&self) -> Option<&Arc<Locked<PropertyDeclarationBlock>>> {
|
||||||
let declarations = unsafe { Gecko_GetStyleAttrDeclarationBlock(self.0) };
|
let declarations = unsafe { Gecko_GetStyleAttrDeclarationBlock(self.0) };
|
||||||
declarations.map(|s| s.as_arc_opt()).unwrap_or(None)
|
declarations.map(|s| s.as_arc_opt()).unwrap_or(None)
|
||||||
}
|
}
|
||||||
|
@ -436,12 +440,12 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_animation_rule(&self, pseudo: Option<&PseudoElement>)
|
fn get_animation_rule(&self, pseudo: Option<&PseudoElement>)
|
||||||
-> Option<Arc<RwLock<PropertyDeclarationBlock>>> {
|
-> Option<Arc<Locked<PropertyDeclarationBlock>>> {
|
||||||
get_animation_rule(self, pseudo, CascadeLevel::Animations)
|
get_animation_rule(self, pseudo, CascadeLevel::Animations)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_transition_rule(&self, pseudo: Option<&PseudoElement>)
|
fn get_transition_rule(&self, pseudo: Option<&PseudoElement>)
|
||||||
-> Option<Arc<RwLock<PropertyDeclarationBlock>>> {
|
-> Option<Arc<Locked<PropertyDeclarationBlock>>> {
|
||||||
get_animation_rule(self, pseudo, CascadeLevel::Transitions)
|
get_animation_rule(self, pseudo, CascadeLevel::Transitions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,14 +8,13 @@
|
||||||
|
|
||||||
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser};
|
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser};
|
||||||
use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule};
|
use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule};
|
||||||
use parking_lot::RwLock;
|
|
||||||
use parser::{ParserContext, ParserContextExtraData, log_css_error};
|
use parser::{ParserContext, ParserContextExtraData, log_css_error};
|
||||||
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId};
|
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId};
|
||||||
use properties::{PropertyDeclarationId, LonghandId, ParsedDeclaration};
|
use properties::{PropertyDeclarationId, LonghandId, ParsedDeclaration};
|
||||||
use properties::LonghandIdSet;
|
use properties::LonghandIdSet;
|
||||||
use properties::animated_properties::TransitionProperty;
|
use properties::animated_properties::TransitionProperty;
|
||||||
use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction;
|
use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction;
|
||||||
use shared_lock::{SharedRwLock, SharedRwLockReadGuard, Locked};
|
use shared_lock::{SharedRwLock, SharedRwLockReadGuard, Locked, ToCssWithGuard};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
|
@ -102,11 +101,12 @@ pub struct Keyframe {
|
||||||
///
|
///
|
||||||
/// Note that `!important` rules in keyframes don't apply, but we keep this
|
/// Note that `!important` rules in keyframes don't apply, but we keep this
|
||||||
/// `Arc` just for convenience.
|
/// `Arc` just for convenience.
|
||||||
pub block: Arc<RwLock<PropertyDeclarationBlock>>,
|
pub block: Arc<Locked<PropertyDeclarationBlock>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToCss for Keyframe {
|
impl ToCssWithGuard for Keyframe {
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
fn to_css<W>(&self, guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
|
||||||
|
where W: fmt::Write {
|
||||||
let mut iter = self.selector.percentages().iter();
|
let mut iter = self.selector.percentages().iter();
|
||||||
try!(iter.next().unwrap().to_css(dest));
|
try!(iter.next().unwrap().to_css(dest));
|
||||||
for percentage in iter {
|
for percentage in iter {
|
||||||
|
@ -114,7 +114,7 @@ impl ToCss for Keyframe {
|
||||||
try!(percentage.to_css(dest));
|
try!(percentage.to_css(dest));
|
||||||
}
|
}
|
||||||
try!(dest.write_str(" { "));
|
try!(dest.write_str(" { "));
|
||||||
try!(self.block.read().to_css(dest));
|
try!(self.block.read_with(guard).to_css(dest));
|
||||||
try!(dest.write_str(" }"));
|
try!(dest.write_str(" }"));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ pub enum KeyframesStepValue {
|
||||||
Declarations {
|
Declarations {
|
||||||
/// The declaration block per se.
|
/// The declaration block per se.
|
||||||
#[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")]
|
#[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")]
|
||||||
block: Arc<RwLock<PropertyDeclarationBlock>>
|
block: Arc<Locked<PropertyDeclarationBlock>>
|
||||||
},
|
},
|
||||||
/// A synthetic step computed from the current computed values at the time
|
/// A synthetic step computed from the current computed values at the time
|
||||||
/// of the animation.
|
/// of the animation.
|
||||||
|
@ -180,10 +180,11 @@ pub struct KeyframesStep {
|
||||||
impl KeyframesStep {
|
impl KeyframesStep {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn new(percentage: KeyframePercentage,
|
fn new(percentage: KeyframePercentage,
|
||||||
value: KeyframesStepValue) -> Self {
|
value: KeyframesStepValue,
|
||||||
|
guard: &SharedRwLockReadGuard) -> Self {
|
||||||
let declared_timing_function = match value {
|
let declared_timing_function = match value {
|
||||||
KeyframesStepValue::Declarations { ref block } => {
|
KeyframesStepValue::Declarations { ref block } => {
|
||||||
block.read().declarations().iter().any(|&(ref prop_decl, _)| {
|
block.read_with(guard).declarations().iter().any(|&(ref prop_decl, _)| {
|
||||||
match *prop_decl {
|
match *prop_decl {
|
||||||
PropertyDeclaration::AnimationTimingFunction(..) => true,
|
PropertyDeclaration::AnimationTimingFunction(..) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -201,13 +202,14 @@ impl KeyframesStep {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return specified TransitionTimingFunction if this KeyframesSteps has 'animation-timing-function'.
|
/// Return specified TransitionTimingFunction if this KeyframesSteps has 'animation-timing-function'.
|
||||||
pub fn get_animation_timing_function(&self) -> Option<SpecifiedTimingFunction> {
|
pub fn get_animation_timing_function(&self, guard: &SharedRwLockReadGuard)
|
||||||
|
-> Option<SpecifiedTimingFunction> {
|
||||||
if !self.declared_timing_function {
|
if !self.declared_timing_function {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
match self.value {
|
match self.value {
|
||||||
KeyframesStepValue::Declarations { ref block } => {
|
KeyframesStepValue::Declarations { ref block } => {
|
||||||
let guard = block.read();
|
let guard = block.read_with(guard);
|
||||||
let &(ref declaration, _) =
|
let &(ref declaration, _) =
|
||||||
guard.get(PropertyDeclarationId::Longhand(LonghandId::AnimationTimingFunction)).unwrap();
|
guard.get(PropertyDeclarationId::Longhand(LonghandId::AnimationTimingFunction)).unwrap();
|
||||||
match *declaration {
|
match *declaration {
|
||||||
|
@ -249,7 +251,8 @@ fn get_animated_properties(keyframes: &[Arc<Locked<Keyframe>>], guard: &SharedRw
|
||||||
// it here.
|
// it here.
|
||||||
for keyframe in keyframes {
|
for keyframe in keyframes {
|
||||||
let keyframe = keyframe.read_with(&guard);
|
let keyframe = keyframe.read_with(&guard);
|
||||||
for &(ref declaration, importance) in keyframe.block.read().declarations().iter() {
|
let block = keyframe.block.read_with(guard);
|
||||||
|
for &(ref declaration, importance) in block.declarations().iter() {
|
||||||
assert!(!importance.important());
|
assert!(!importance.important());
|
||||||
|
|
||||||
if let Some(property) = TransitionProperty::from_declaration(declaration) {
|
if let Some(property) = TransitionProperty::from_declaration(declaration) {
|
||||||
|
@ -294,7 +297,7 @@ impl KeyframesAnimation {
|
||||||
for percentage in keyframe.selector.0.iter() {
|
for percentage in keyframe.selector.0.iter() {
|
||||||
result.steps.push(KeyframesStep::new(*percentage, KeyframesStepValue::Declarations {
|
result.steps.push(KeyframesStep::new(*percentage, KeyframesStepValue::Declarations {
|
||||||
block: keyframe.block.clone(),
|
block: keyframe.block.clone(),
|
||||||
}));
|
}, guard));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,12 +307,14 @@ impl KeyframesAnimation {
|
||||||
// Prepend autogenerated keyframes if appropriate.
|
// Prepend autogenerated keyframes if appropriate.
|
||||||
if result.steps[0].start_percentage.0 != 0. {
|
if result.steps[0].start_percentage.0 != 0. {
|
||||||
result.steps.insert(0, KeyframesStep::new(KeyframePercentage::new(0.),
|
result.steps.insert(0, KeyframesStep::new(KeyframePercentage::new(0.),
|
||||||
KeyframesStepValue::ComputedValues));
|
KeyframesStepValue::ComputedValues,
|
||||||
|
guard));
|
||||||
}
|
}
|
||||||
|
|
||||||
if result.steps.last().unwrap().start_percentage.0 != 1. {
|
if result.steps.last().unwrap().start_percentage.0 != 1. {
|
||||||
result.steps.push(KeyframesStep::new(KeyframePercentage::new(1.),
|
result.steps.push(KeyframesStep::new(KeyframePercentage::new(1.),
|
||||||
KeyframesStepValue::ComputedValues));
|
KeyframesStepValue::ComputedValues,
|
||||||
|
guard));
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
|
@ -381,7 +386,7 @@ impl<'a> QualifiedRuleParser for KeyframeListParser<'a> {
|
||||||
}
|
}
|
||||||
Ok(Arc::new(self.shared_lock.wrap(Keyframe {
|
Ok(Arc::new(self.shared_lock.wrap(Keyframe {
|
||||||
selector: prelude,
|
selector: prelude,
|
||||||
block: Arc::new(RwLock::new(block)),
|
block: Arc::new(self.shared_lock.wrap(block)),
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@ extern crate log;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate matches;
|
extern crate matches;
|
||||||
#[cfg(feature = "gecko")] extern crate nsstring_vendor as nsstring;
|
#[cfg(feature = "gecko")] extern crate nsstring_vendor as nsstring;
|
||||||
|
#[cfg(feature = "gecko")] extern crate num_cpus;
|
||||||
extern crate num_integer;
|
extern crate num_integer;
|
||||||
extern crate num_traits;
|
extern crate num_traits;
|
||||||
extern crate ordered_float;
|
extern crate ordered_float;
|
||||||
|
|
|
@ -886,7 +886,8 @@ pub trait MatchMethods : TElement {
|
||||||
let new_node = context.shared.stylist.rule_tree
|
let new_node = context.shared.stylist.rule_tree
|
||||||
.update_rule_at_level(CascadeLevel::StyleAttributeNormal,
|
.update_rule_at_level(CascadeLevel::StyleAttributeNormal,
|
||||||
style_attribute,
|
style_attribute,
|
||||||
primary_rules);
|
primary_rules,
|
||||||
|
&context.shared.guards);
|
||||||
if let Some(n) = new_node {
|
if let Some(n) = new_node {
|
||||||
*primary_rules = n;
|
*primary_rules = n;
|
||||||
rule_node_changed = true;
|
rule_node_changed = true;
|
||||||
|
@ -895,7 +896,8 @@ pub trait MatchMethods : TElement {
|
||||||
let new_node = context.shared.stylist.rule_tree
|
let new_node = context.shared.stylist.rule_tree
|
||||||
.update_rule_at_level(CascadeLevel::StyleAttributeImportant,
|
.update_rule_at_level(CascadeLevel::StyleAttributeImportant,
|
||||||
style_attribute,
|
style_attribute,
|
||||||
primary_rules);
|
primary_rules,
|
||||||
|
&context.shared.guards);
|
||||||
if let Some(n) = new_node {
|
if let Some(n) = new_node {
|
||||||
*primary_rules = n;
|
*primary_rules = n;
|
||||||
rule_node_changed = true;
|
rule_node_changed = true;
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
use arc_ptr_eq;
|
use arc_ptr_eq;
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
use heapsize::HeapSizeOf;
|
use heapsize::HeapSizeOf;
|
||||||
use parking_lot::{RwLock, RwLockReadGuard};
|
|
||||||
use properties::{Importance, PropertyDeclarationBlock};
|
use properties::{Importance, PropertyDeclarationBlock};
|
||||||
use shared_lock::{Locked, ReadGuards, SharedRwLockReadGuard};
|
use shared_lock::{Locked, ReadGuards, SharedRwLockReadGuard};
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
@ -54,7 +53,7 @@ pub enum StyleSource {
|
||||||
/// A style rule stable pointer.
|
/// A style rule stable pointer.
|
||||||
Style(Arc<Locked<StyleRule>>),
|
Style(Arc<Locked<StyleRule>>),
|
||||||
/// A declaration block stable pointer.
|
/// A declaration block stable pointer.
|
||||||
Declarations(Arc<RwLock<PropertyDeclarationBlock>>),
|
Declarations(Arc<Locked<PropertyDeclarationBlock>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StyleSource {
|
impl StyleSource {
|
||||||
|
@ -82,13 +81,12 @@ impl StyleSource {
|
||||||
/// Read the style source guard, and obtain thus read access to the
|
/// Read the style source guard, and obtain thus read access to the
|
||||||
/// underlying property declaration block.
|
/// underlying property declaration block.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn read<'a>(&'a self, guard: &'a SharedRwLockReadGuard)
|
pub fn read<'a>(&'a self, guard: &'a SharedRwLockReadGuard) -> &'a PropertyDeclarationBlock {
|
||||||
-> RwLockReadGuard<'a, PropertyDeclarationBlock> {
|
|
||||||
let block = match *self {
|
let block = match *self {
|
||||||
StyleSource::Style(ref rule) => &rule.read_with(guard).block,
|
StyleSource::Style(ref rule) => &rule.read_with(guard).block,
|
||||||
StyleSource::Declarations(ref block) => block,
|
StyleSource::Declarations(ref block) => block,
|
||||||
};
|
};
|
||||||
block.read()
|
block.read_with(guard)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,8 +160,9 @@ impl RuleTree {
|
||||||
/// the old path is still valid.
|
/// the old path is still valid.
|
||||||
pub fn update_rule_at_level(&self,
|
pub fn update_rule_at_level(&self,
|
||||||
level: CascadeLevel,
|
level: CascadeLevel,
|
||||||
pdb: Option<&Arc<RwLock<PropertyDeclarationBlock>>>,
|
pdb: Option<&Arc<Locked<PropertyDeclarationBlock>>>,
|
||||||
path: &StrongRuleNode)
|
path: &StrongRuleNode,
|
||||||
|
guards: &ReadGuards)
|
||||||
-> Option<StrongRuleNode> {
|
-> Option<StrongRuleNode> {
|
||||||
debug_assert!(level.is_unique_per_element());
|
debug_assert!(level.is_unique_per_element());
|
||||||
// TODO(emilio): Being smarter with lifetimes we could avoid a bit of
|
// TODO(emilio): Being smarter with lifetimes we could avoid a bit of
|
||||||
|
@ -222,13 +221,13 @@ impl RuleTree {
|
||||||
// pretty bad styling cases already.
|
// pretty bad styling cases already.
|
||||||
if let Some(pdb) = pdb {
|
if let Some(pdb) = pdb {
|
||||||
if level.is_important() {
|
if level.is_important() {
|
||||||
if pdb.read().any_important() {
|
if pdb.read_with(level.guard(guards)).any_important() {
|
||||||
current = current.ensure_child(self.root.downgrade(),
|
current = current.ensure_child(self.root.downgrade(),
|
||||||
StyleSource::Declarations(pdb.clone()),
|
StyleSource::Declarations(pdb.clone()),
|
||||||
level);
|
level);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if pdb.read().any_normal() {
|
if pdb.read_with(level.guard(guards)).any_normal() {
|
||||||
current = current.ensure_child(self.root.downgrade(),
|
current = current.ensure_child(self.root.downgrade(),
|
||||||
StyleSource::Declarations(pdb.clone()),
|
StyleSource::Declarations(pdb.clone()),
|
||||||
level);
|
level);
|
||||||
|
|
|
@ -469,7 +469,7 @@ impl ToCssWithGuard for KeyframesRule {
|
||||||
}
|
}
|
||||||
first = false;
|
first = false;
|
||||||
let keyframe = lock.read_with(&guard);
|
let keyframe = lock.read_with(&guard);
|
||||||
try!(keyframe.to_css(dest));
|
try!(keyframe.to_css(guard, dest));
|
||||||
}
|
}
|
||||||
dest.write_str(" }")
|
dest.write_str(" }")
|
||||||
}
|
}
|
||||||
|
@ -528,19 +528,19 @@ impl ToCssWithGuard for SupportsRule {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StyleRule {
|
pub struct StyleRule {
|
||||||
pub selectors: SelectorList<SelectorImpl>,
|
pub selectors: SelectorList<SelectorImpl>,
|
||||||
pub block: Arc<RwLock<PropertyDeclarationBlock>>,
|
pub block: Arc<Locked<PropertyDeclarationBlock>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToCssWithGuard for StyleRule {
|
impl ToCssWithGuard for StyleRule {
|
||||||
// https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSStyleRule
|
// https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSStyleRule
|
||||||
fn to_css<W>(&self, _guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
|
fn to_css<W>(&self, guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
|
||||||
where W: fmt::Write {
|
where W: fmt::Write {
|
||||||
// Step 1
|
// Step 1
|
||||||
try!(self.selectors.to_css(dest));
|
try!(self.selectors.to_css(dest));
|
||||||
// Step 2
|
// Step 2
|
||||||
try!(dest.write_str(" { "));
|
try!(dest.write_str(" { "));
|
||||||
// Step 3
|
// Step 3
|
||||||
let declaration_block = self.block.read();
|
let declaration_block = self.block.read_with(guard);
|
||||||
try!(declaration_block.to_css(dest));
|
try!(declaration_block.to_css(dest));
|
||||||
// Step 4
|
// Step 4
|
||||||
if declaration_block.declarations().len() > 0 {
|
if declaration_block.declarations().len() > 0 {
|
||||||
|
@ -1018,9 +1018,10 @@ impl<'a, 'b> QualifiedRuleParser for NestedRuleParser<'a, 'b> {
|
||||||
|
|
||||||
fn parse_block(&mut self, prelude: SelectorList<SelectorImpl>, input: &mut Parser)
|
fn parse_block(&mut self, prelude: SelectorList<SelectorImpl>, input: &mut Parser)
|
||||||
-> Result<CssRule, ()> {
|
-> Result<CssRule, ()> {
|
||||||
|
let declarations = parse_property_declaration_list(self.context, input);
|
||||||
Ok(CssRule::Style(Arc::new(self.shared_lock.wrap(StyleRule {
|
Ok(CssRule::Style(Arc::new(self.shared_lock.wrap(StyleRule {
|
||||||
selectors: prelude,
|
selectors: prelude,
|
||||||
block: Arc::new(RwLock::new(parse_property_declaration_list(self.context, input)))
|
block: Arc::new(self.shared_lock.wrap(declarations))
|
||||||
}))))
|
}))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ use dom::{AnimationRules, PresentationalHintsSynthetizer, TElement};
|
||||||
use error_reporting::StdoutErrorReporter;
|
use error_reporting::StdoutErrorReporter;
|
||||||
use keyframes::KeyframesAnimation;
|
use keyframes::KeyframesAnimation;
|
||||||
use media_queries::Device;
|
use media_queries::Device;
|
||||||
use parking_lot::RwLock;
|
|
||||||
use pdqsort::sort_by;
|
use pdqsort::sort_by;
|
||||||
use properties::{self, CascadeFlags, ComputedValues};
|
use properties::{self, CascadeFlags, ComputedValues};
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
|
@ -542,7 +541,7 @@ impl Stylist {
|
||||||
&self,
|
&self,
|
||||||
element: &E,
|
element: &E,
|
||||||
parent_bf: Option<&BloomFilter>,
|
parent_bf: Option<&BloomFilter>,
|
||||||
style_attribute: Option<&Arc<RwLock<PropertyDeclarationBlock>>>,
|
style_attribute: Option<&Arc<Locked<PropertyDeclarationBlock>>>,
|
||||||
animation_rules: AnimationRules,
|
animation_rules: AnimationRules,
|
||||||
pseudo_element: Option<&PseudoElement>,
|
pseudo_element: Option<&PseudoElement>,
|
||||||
guards: &ReadGuards,
|
guards: &ReadGuards,
|
||||||
|
@ -613,7 +612,7 @@ impl Stylist {
|
||||||
|
|
||||||
// Step 4: Normal style attributes.
|
// Step 4: Normal style attributes.
|
||||||
if let Some(sa) = style_attribute {
|
if let Some(sa) = style_attribute {
|
||||||
if sa.read().any_normal() {
|
if sa.read_with(guards.author).any_normal() {
|
||||||
relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
|
relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
|
||||||
Push::push(
|
Push::push(
|
||||||
applicable_declarations,
|
applicable_declarations,
|
||||||
|
@ -649,7 +648,7 @@ impl Stylist {
|
||||||
|
|
||||||
// Step 7: `!important` style attributes.
|
// Step 7: `!important` style attributes.
|
||||||
if let Some(sa) = style_attribute {
|
if let Some(sa) = style_attribute {
|
||||||
if sa.read().any_important() {
|
if sa.read_with(guards.author).any_important() {
|
||||||
relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
|
relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
|
||||||
Push::push(
|
Push::push(
|
||||||
applicable_declarations,
|
applicable_declarations,
|
||||||
|
@ -1005,7 +1004,7 @@ impl SelectorMap {
|
||||||
if rule.selector.compound_selector.is_empty() &&
|
if rule.selector.compound_selector.is_empty() &&
|
||||||
rule.selector.next.is_none() {
|
rule.selector.next.is_none() {
|
||||||
let style_rule = rule.style_rule.read_with(guard);
|
let style_rule = rule.style_rule.read_with(guard);
|
||||||
let block = style_rule.block.read();
|
let block = style_rule.block.read_with(guard);
|
||||||
if block.any_normal() {
|
if block.any_normal() {
|
||||||
matching_rules_list.push(
|
matching_rules_list.push(
|
||||||
rule.to_applicable_declaration_block(cascade_level));
|
rule.to_applicable_declaration_block(cascade_level));
|
||||||
|
@ -1069,7 +1068,7 @@ impl SelectorMap {
|
||||||
{
|
{
|
||||||
for rule in rules.iter() {
|
for rule in rules.iter() {
|
||||||
let style_rule = rule.style_rule.read_with(guard);
|
let style_rule = rule.style_rule.read_with(guard);
|
||||||
let block = style_rule.block.read();
|
let block = style_rule.block.read_with(guard);
|
||||||
let any_declaration_for_importance = if cascade_level.is_important() {
|
let any_declaration_for_importance = if cascade_level.is_important() {
|
||||||
block.any_important()
|
block.any_important()
|
||||||
} else {
|
} else {
|
||||||
|
@ -1208,7 +1207,7 @@ impl ApplicableDeclarationBlock {
|
||||||
/// Constructs an applicable declaration block from a given property
|
/// Constructs an applicable declaration block from a given property
|
||||||
/// declaration block and importance.
|
/// declaration block and importance.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_declarations(declarations: Arc<RwLock<PropertyDeclarationBlock>>,
|
pub fn from_declarations(declarations: Arc<Locked<PropertyDeclarationBlock>>,
|
||||||
level: CascadeLevel)
|
level: CascadeLevel)
|
||||||
-> Self {
|
-> Self {
|
||||||
ApplicableDeclarationBlock {
|
ApplicableDeclarationBlock {
|
||||||
|
|
|
@ -20,9 +20,7 @@ env_logger = {version = "0.4", default-features = false} # disable `regex` to re
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
log = {version = "0.3.5", features = ["release_max_level_info"]}
|
log = {version = "0.3.5", features = ["release_max_level_info"]}
|
||||||
num_cpus = "1.1.0"
|
|
||||||
parking_lot = "0.3"
|
parking_lot = "0.3"
|
||||||
rayon = "0.6"
|
|
||||||
selectors = {path = "../../components/selectors"}
|
selectors = {path = "../../components/selectors"}
|
||||||
servo_url = {path = "../../components/url"}
|
servo_url = {path = "../../components/url"}
|
||||||
style = {path = "../../components/style", features = ["gecko"]}
|
style = {path = "../../components/style", features = ["gecko"]}
|
||||||
|
|
|
@ -6,13 +6,10 @@ use atomic_refcell::AtomicRefMut;
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use cssparser::ToCss as ParserToCss;
|
use cssparser::ToCss as ParserToCss;
|
||||||
use env_logger::LogBuilder;
|
use env_logger::LogBuilder;
|
||||||
use num_cpus;
|
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use rayon;
|
|
||||||
use selectors::Element;
|
use selectors::Element;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cmp;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
@ -24,6 +21,7 @@ use style::data::{ElementData, ElementStyles, RestyleData};
|
||||||
use style::dom::{ShowSubtreeData, TElement, TNode};
|
use style::dom::{ShowSubtreeData, TElement, TNode};
|
||||||
use style::error_reporting::StdoutErrorReporter;
|
use style::error_reporting::StdoutErrorReporter;
|
||||||
use style::gecko::data::{PerDocumentStyleData, PerDocumentStyleDataImpl};
|
use style::gecko::data::{PerDocumentStyleData, PerDocumentStyleDataImpl};
|
||||||
|
use style::gecko::global_style_data::GLOBAL_STYLE_DATA;
|
||||||
use style::gecko::restyle_damage::GeckoRestyleDamage;
|
use style::gecko::restyle_damage::GeckoRestyleDamage;
|
||||||
use style::gecko::selector_parser::{SelectorImpl, PseudoElement};
|
use style::gecko::selector_parser::{SelectorImpl, PseudoElement};
|
||||||
use style::gecko::traversal::RecalcStyleOnly;
|
use style::gecko::traversal::RecalcStyleOnly;
|
||||||
|
@ -96,48 +94,7 @@ use super::stylesheet_loader::StylesheetLoader;
|
||||||
* depend on but good enough for our purposes.
|
* depend on but good enough for our purposes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub struct GlobalStyleData {
|
|
||||||
// How many threads parallel styling can use.
|
|
||||||
pub num_threads: usize,
|
|
||||||
|
|
||||||
// The parallel styling thread pool.
|
|
||||||
pub style_thread_pool: Option<rayon::ThreadPool>,
|
|
||||||
|
|
||||||
// Shared RWLock for CSSOM objects
|
|
||||||
pub shared_lock: SharedRwLock,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GlobalStyleData {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
let stylo_threads = env::var("STYLO_THREADS")
|
|
||||||
.map(|s| s.parse::<usize>().expect("invalid STYLO_THREADS value"));
|
|
||||||
let num_threads = match stylo_threads {
|
|
||||||
Ok(num) => num,
|
|
||||||
_ => cmp::max(num_cpus::get() * 3 / 4, 1),
|
|
||||||
};
|
|
||||||
|
|
||||||
let pool = if num_threads <= 1 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
let configuration =
|
|
||||||
rayon::Configuration::new().set_num_threads(num_threads);
|
|
||||||
let pool = rayon::ThreadPool::new(configuration).ok();
|
|
||||||
pool
|
|
||||||
};
|
|
||||||
|
|
||||||
GlobalStyleData {
|
|
||||||
num_threads: num_threads,
|
|
||||||
style_thread_pool: pool,
|
|
||||||
shared_lock: SharedRwLock::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
pub static ref GLOBAL_STYLE_DATA: GlobalStyleData = {
|
|
||||||
GlobalStyleData::new()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_Initialize() {
|
pub extern "C" fn Servo_Initialize() {
|
||||||
|
@ -638,7 +595,7 @@ pub extern "C" fn Servo_StyleRule_SetStyle(rule: RawServoStyleRuleBorrowed,
|
||||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
let mut guard = global_style_data.shared_lock.write();
|
let mut guard = global_style_data.shared_lock.write();
|
||||||
let rule = Locked::<StyleRule>::as_arc(&rule);
|
let rule = Locked::<StyleRule>::as_arc(&rule);
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
rule.write_with(&mut guard).block = declarations.clone();
|
rule.write_with(&mut guard).block = declarations.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -829,9 +786,10 @@ pub extern "C" fn Servo_ParseProperty(property: *const nsACString, value: *const
|
||||||
|
|
||||||
match ParsedDeclaration::parse(id, &context, &mut Parser::new(value), false) {
|
match ParsedDeclaration::parse(id, &context, &mut Parser::new(value), false) {
|
||||||
Ok(parsed) => {
|
Ok(parsed) => {
|
||||||
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
let mut block = PropertyDeclarationBlock::new();
|
let mut block = PropertyDeclarationBlock::new();
|
||||||
parsed.expand(|d| block.push(d, Importance::Normal));
|
parsed.expand(|d| block.push(d, Importance::Normal));
|
||||||
Arc::new(RwLock::new(block)).into_strong()
|
Arc::new(global_style_data.shared_lock.wrap(block)).into_strong()
|
||||||
}
|
}
|
||||||
Err(_) => RawServoDeclarationBlockStrong::null()
|
Err(_) => RawServoDeclarationBlockStrong::null()
|
||||||
}
|
}
|
||||||
|
@ -842,36 +800,47 @@ pub extern "C" fn Servo_ParseStyleAttribute(data: *const nsACString,
|
||||||
base: *const nsACString,
|
base: *const nsACString,
|
||||||
raw_extra_data: *const structs::GeckoParserExtraData)
|
raw_extra_data: *const structs::GeckoParserExtraData)
|
||||||
-> RawServoDeclarationBlockStrong {
|
-> RawServoDeclarationBlockStrong {
|
||||||
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
let value = unsafe { data.as_ref().unwrap().as_str_unchecked() };
|
let value = unsafe { data.as_ref().unwrap().as_str_unchecked() };
|
||||||
make_context!((base, raw_extra_data) => (base_url, extra_data));
|
make_context!((base, raw_extra_data) => (base_url, extra_data));
|
||||||
Arc::new(RwLock::new(GeckoElement::parse_style_attribute(value, &base_url, extra_data))).into_strong()
|
Arc::new(global_style_data.shared_lock.wrap(
|
||||||
|
GeckoElement::parse_style_attribute(value, &base_url, extra_data))).into_strong()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_DeclarationBlock_CreateEmpty() -> RawServoDeclarationBlockStrong {
|
pub extern "C" fn Servo_DeclarationBlock_CreateEmpty() -> RawServoDeclarationBlockStrong {
|
||||||
Arc::new(RwLock::new(PropertyDeclarationBlock::new())).into_strong()
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
Arc::new(global_style_data.shared_lock.wrap(PropertyDeclarationBlock::new())).into_strong()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_DeclarationBlock_Clone(declarations: RawServoDeclarationBlockBorrowed)
|
pub extern "C" fn Servo_DeclarationBlock_Clone(declarations: RawServoDeclarationBlockBorrowed)
|
||||||
-> RawServoDeclarationBlockStrong {
|
-> RawServoDeclarationBlockStrong {
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
Arc::new(RwLock::new(declarations.read().clone())).into_strong()
|
let guard = global_style_data.shared_lock.read();
|
||||||
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
|
Arc::new(global_style_data.shared_lock.wrap(
|
||||||
|
declarations.read_with(&guard).clone()
|
||||||
|
)).into_strong()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_DeclarationBlock_Equals(a: RawServoDeclarationBlockBorrowed,
|
pub extern "C" fn Servo_DeclarationBlock_Equals(a: RawServoDeclarationBlockBorrowed,
|
||||||
b: RawServoDeclarationBlockBorrowed)
|
b: RawServoDeclarationBlockBorrowed)
|
||||||
-> bool {
|
-> bool {
|
||||||
*RwLock::<PropertyDeclarationBlock>::as_arc(&a).read().declarations() ==
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
*RwLock::<PropertyDeclarationBlock>::as_arc(&b).read().declarations()
|
let guard = global_style_data.shared_lock.read();
|
||||||
|
*Locked::<PropertyDeclarationBlock>::as_arc(&a).read_with(&guard).declarations() ==
|
||||||
|
*Locked::<PropertyDeclarationBlock>::as_arc(&b).read_with(&guard).declarations()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_DeclarationBlock_GetCssText(declarations: RawServoDeclarationBlockBorrowed,
|
pub extern "C" fn Servo_DeclarationBlock_GetCssText(declarations: RawServoDeclarationBlockBorrowed,
|
||||||
result: *mut nsAString) {
|
result: *mut nsAString) {
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
declarations.read().to_css(unsafe { result.as_mut().unwrap() }).unwrap();
|
let guard = global_style_data.shared_lock.read();
|
||||||
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
|
declarations.read_with(&guard).to_css(unsafe { result.as_mut().unwrap() }).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -880,9 +849,11 @@ pub extern "C" fn Servo_DeclarationBlock_SerializeOneValue(
|
||||||
property_id: nsCSSPropertyID, buffer: *mut nsAString)
|
property_id: nsCSSPropertyID, buffer: *mut nsAString)
|
||||||
{
|
{
|
||||||
let property_id = get_property_id_from_nscsspropertyid!(property_id, ());
|
let property_id = get_property_id_from_nscsspropertyid!(property_id, ());
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
let guard = global_style_data.shared_lock.read();
|
||||||
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
let mut string = String::new();
|
let mut string = String::new();
|
||||||
let rv = declarations.read().single_value_to_css(&property_id, &mut string);
|
let rv = declarations.read_with(&guard).single_value_to_css(&property_id, &mut string);
|
||||||
debug_assert!(rv.is_ok());
|
debug_assert!(rv.is_ok());
|
||||||
|
|
||||||
write!(unsafe { &mut *buffer }, "{}", string).expect("Failed to copy string");
|
write!(unsafe { &mut *buffer }, "{}", string).expect("Failed to copy string");
|
||||||
|
@ -890,15 +861,19 @@ pub extern "C" fn Servo_DeclarationBlock_SerializeOneValue(
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_DeclarationBlock_Count(declarations: RawServoDeclarationBlockBorrowed) -> u32 {
|
pub extern "C" fn Servo_DeclarationBlock_Count(declarations: RawServoDeclarationBlockBorrowed) -> u32 {
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
declarations.read().declarations().len() as u32
|
let guard = global_style_data.shared_lock.read();
|
||||||
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
|
declarations.read_with(&guard).declarations().len() as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_DeclarationBlock_GetNthProperty(declarations: RawServoDeclarationBlockBorrowed,
|
pub extern "C" fn Servo_DeclarationBlock_GetNthProperty(declarations: RawServoDeclarationBlockBorrowed,
|
||||||
index: u32, result: *mut nsAString) -> bool {
|
index: u32, result: *mut nsAString) -> bool {
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
if let Some(&(ref decl, _)) = declarations.read().declarations().get(index as usize) {
|
let guard = global_style_data.shared_lock.read();
|
||||||
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
|
if let Some(&(ref decl, _)) = declarations.read_with(&guard).declarations().get(index as usize) {
|
||||||
let result = unsafe { result.as_mut().unwrap() };
|
let result = unsafe { result.as_mut().unwrap() };
|
||||||
decl.id().to_css(result).unwrap();
|
decl.id().to_css(result).unwrap();
|
||||||
true
|
true
|
||||||
|
@ -919,8 +894,12 @@ macro_rules! get_property_id_from_property {
|
||||||
|
|
||||||
fn get_property_value(declarations: RawServoDeclarationBlockBorrowed,
|
fn get_property_value(declarations: RawServoDeclarationBlockBorrowed,
|
||||||
property_id: PropertyId, value: *mut nsAString) {
|
property_id: PropertyId, value: *mut nsAString) {
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
declarations.read().property_value_to_css(&property_id, unsafe { value.as_mut().unwrap() }).unwrap();
|
let guard = global_style_data.shared_lock.read();
|
||||||
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
|
declarations.read_with(&guard)
|
||||||
|
.property_value_to_css(&property_id, unsafe { value.as_mut().unwrap() })
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -939,8 +918,10 @@ pub extern "C" fn Servo_DeclarationBlock_GetPropertyValueById(declarations: RawS
|
||||||
pub extern "C" fn Servo_DeclarationBlock_GetPropertyIsImportant(declarations: RawServoDeclarationBlockBorrowed,
|
pub extern "C" fn Servo_DeclarationBlock_GetPropertyIsImportant(declarations: RawServoDeclarationBlockBorrowed,
|
||||||
property: *const nsACString) -> bool {
|
property: *const nsACString) -> bool {
|
||||||
let property_id = get_property_id_from_property!(property, false);
|
let property_id = get_property_id_from_property!(property, false);
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
declarations.read().property_priority(&property_id).important()
|
let guard = global_style_data.shared_lock.read();
|
||||||
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
|
declarations.read_with(&guard).property_priority(&property_id).important()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId,
|
fn set_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId,
|
||||||
|
@ -951,7 +932,10 @@ fn set_property(declarations: RawServoDeclarationBlockBorrowed, property_id: Pro
|
||||||
make_context!((base, data) => (base_url, extra_data));
|
make_context!((base, data) => (base_url, extra_data));
|
||||||
if let Ok(parsed) = parse_one_declaration(property_id, value, &base_url,
|
if let Ok(parsed) = parse_one_declaration(property_id, value, &base_url,
|
||||||
&StdoutErrorReporter, extra_data) {
|
&StdoutErrorReporter, extra_data) {
|
||||||
let mut declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations).write();
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
let mut guard = global_style_data.shared_lock.write();
|
||||||
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations)
|
||||||
|
.write_with(&mut guard);
|
||||||
let importance = if is_important { Importance::Important } else { Importance::Normal };
|
let importance = if is_important { Importance::Important } else { Importance::Normal };
|
||||||
let mut changed = false;
|
let mut changed = false;
|
||||||
parsed.expand(|decl| {
|
parsed.expand(|decl| {
|
||||||
|
@ -984,8 +968,10 @@ pub extern "C" fn Servo_DeclarationBlock_SetPropertyById(declarations: RawServoD
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId) {
|
fn remove_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId) {
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
declarations.write().remove_property(&property_id);
|
let mut guard = global_style_data.shared_lock.write();
|
||||||
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
|
declarations.write_with(&mut guard).remove_property(&property_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -1095,9 +1081,11 @@ pub extern "C" fn Servo_DeclarationBlock_PropertyIsSet(declarations:
|
||||||
property: nsCSSPropertyID)
|
property: nsCSSPropertyID)
|
||||||
-> bool {
|
-> bool {
|
||||||
use style::properties::PropertyDeclarationId;
|
use style::properties::PropertyDeclarationId;
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
let long = get_longhand_from_id!(property, false);
|
let long = get_longhand_from_id!(property, false);
|
||||||
declarations.read().get(PropertyDeclarationId::Longhand(long)).is_some()
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
let guard = global_style_data.shared_lock.read();
|
||||||
|
declarations.read_with(&guard).get(PropertyDeclarationId::Longhand(long)).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -1110,12 +1098,14 @@ pub extern "C" fn Servo_DeclarationBlock_SetIdentStringValue(declarations:
|
||||||
use style::properties::{PropertyDeclaration, LonghandId};
|
use style::properties::{PropertyDeclaration, LonghandId};
|
||||||
use style::properties::longhands::_x_lang::computed_value::T as Lang;
|
use style::properties::longhands::_x_lang::computed_value::T as Lang;
|
||||||
|
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
let long = get_longhand_from_id!(property);
|
let long = get_longhand_from_id!(property);
|
||||||
let prop = match_wrap_declared! { long,
|
let prop = match_wrap_declared! { long,
|
||||||
XLang => Lang(Atom::from(value)),
|
XLang => Lang(Atom::from(value)),
|
||||||
};
|
};
|
||||||
declarations.write().push(prop, Importance::Normal);
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
let mut guard = global_style_data.shared_lock.write();
|
||||||
|
declarations.write_with(&mut guard).push(prop, Importance::Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -1128,7 +1118,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetKeywordValue(declarations:
|
||||||
use style::properties::longhands;
|
use style::properties::longhands;
|
||||||
use style::values::specified::{BorderStyle, NoCalcLength};
|
use style::values::specified::{BorderStyle, NoCalcLength};
|
||||||
|
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
let long = get_longhand_from_id!(property);
|
let long = get_longhand_from_id!(property);
|
||||||
let value = value as u32;
|
let value = value as u32;
|
||||||
|
|
||||||
|
@ -1152,7 +1142,9 @@ pub extern "C" fn Servo_DeclarationBlock_SetKeywordValue(declarations:
|
||||||
BorderBottomStyle => BorderStyle::from_gecko_keyword(value),
|
BorderBottomStyle => BorderStyle::from_gecko_keyword(value),
|
||||||
BorderLeftStyle => BorderStyle::from_gecko_keyword(value),
|
BorderLeftStyle => BorderStyle::from_gecko_keyword(value),
|
||||||
};
|
};
|
||||||
declarations.write().push(prop, Importance::Normal);
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
let mut guard = global_style_data.shared_lock.write();
|
||||||
|
declarations.write_with(&mut guard).push(prop, Importance::Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -1162,12 +1154,14 @@ pub extern "C" fn Servo_DeclarationBlock_SetIntValue(declarations: RawServoDecla
|
||||||
use style::properties::{PropertyDeclaration, LonghandId};
|
use style::properties::{PropertyDeclaration, LonghandId};
|
||||||
use style::properties::longhands::_x_span::computed_value::T as Span;
|
use style::properties::longhands::_x_span::computed_value::T as Span;
|
||||||
|
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
let long = get_longhand_from_id!(property);
|
let long = get_longhand_from_id!(property);
|
||||||
let prop = match_wrap_declared! { long,
|
let prop = match_wrap_declared! { long,
|
||||||
XSpan => Span(value),
|
XSpan => Span(value),
|
||||||
};
|
};
|
||||||
declarations.write().push(prop, Importance::Normal);
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
let mut guard = global_style_data.shared_lock.write();
|
||||||
|
declarations.write_with(&mut guard).push(prop, Importance::Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -1180,7 +1174,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetPixelValue(declarations:
|
||||||
use style::values::specified::BorderWidth;
|
use style::values::specified::BorderWidth;
|
||||||
use style::values::specified::length::NoCalcLength;
|
use style::values::specified::length::NoCalcLength;
|
||||||
|
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
let long = get_longhand_from_id!(property);
|
let long = get_longhand_from_id!(property);
|
||||||
let nocalc = NoCalcLength::from_px(value);
|
let nocalc = NoCalcLength::from_px(value);
|
||||||
|
|
||||||
|
@ -1206,7 +1200,9 @@ pub extern "C" fn Servo_DeclarationBlock_SetPixelValue(declarations:
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
declarations.write().push(prop, Importance::Normal);
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
let mut guard = global_style_data.shared_lock.write();
|
||||||
|
declarations.write_with(&mut guard).push(prop, Importance::Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -1217,7 +1213,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetPercentValue(declarations:
|
||||||
use style::properties::{PropertyDeclaration, LonghandId};
|
use style::properties::{PropertyDeclaration, LonghandId};
|
||||||
use style::values::specified::length::Percentage;
|
use style::values::specified::length::Percentage;
|
||||||
|
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
let long = get_longhand_from_id!(property);
|
let long = get_longhand_from_id!(property);
|
||||||
let pc = Percentage(value);
|
let pc = Percentage(value);
|
||||||
|
|
||||||
|
@ -1229,7 +1225,9 @@ pub extern "C" fn Servo_DeclarationBlock_SetPercentValue(declarations:
|
||||||
MarginBottom => pc.into(),
|
MarginBottom => pc.into(),
|
||||||
MarginLeft => pc.into(),
|
MarginLeft => pc.into(),
|
||||||
};
|
};
|
||||||
declarations.write().push(prop, Importance::Normal);
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
let mut guard = global_style_data.shared_lock.write();
|
||||||
|
declarations.write_with(&mut guard).push(prop, Importance::Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -1239,7 +1237,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetAutoValue(declarations:
|
||||||
use style::properties::{PropertyDeclaration, LonghandId};
|
use style::properties::{PropertyDeclaration, LonghandId};
|
||||||
use style::values::specified::LengthOrPercentageOrAuto;
|
use style::values::specified::LengthOrPercentageOrAuto;
|
||||||
|
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
let long = get_longhand_from_id!(property);
|
let long = get_longhand_from_id!(property);
|
||||||
let auto = LengthOrPercentageOrAuto::Auto;
|
let auto = LengthOrPercentageOrAuto::Auto;
|
||||||
|
|
||||||
|
@ -1251,7 +1249,9 @@ pub extern "C" fn Servo_DeclarationBlock_SetAutoValue(declarations:
|
||||||
MarginBottom => auto,
|
MarginBottom => auto,
|
||||||
MarginLeft => auto,
|
MarginLeft => auto,
|
||||||
};
|
};
|
||||||
declarations.write().push(prop, Importance::Normal);
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
let mut guard = global_style_data.shared_lock.write();
|
||||||
|
declarations.write_with(&mut guard).push(prop, Importance::Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -1261,7 +1261,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetCurrentColor(declarations:
|
||||||
use style::properties::{PropertyDeclaration, LonghandId};
|
use style::properties::{PropertyDeclaration, LonghandId};
|
||||||
use style::values::specified::{Color, CSSColor};
|
use style::values::specified::{Color, CSSColor};
|
||||||
|
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
let long = get_longhand_from_id!(property);
|
let long = get_longhand_from_id!(property);
|
||||||
let cc = CSSColor { parsed: Color::CurrentColor, authored: None };
|
let cc = CSSColor { parsed: Color::CurrentColor, authored: None };
|
||||||
|
|
||||||
|
@ -1271,7 +1271,9 @@ pub extern "C" fn Servo_DeclarationBlock_SetCurrentColor(declarations:
|
||||||
BorderBottomColor => cc,
|
BorderBottomColor => cc,
|
||||||
BorderLeftColor => cc,
|
BorderLeftColor => cc,
|
||||||
};
|
};
|
||||||
declarations.write().push(prop, Importance::Normal);
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
let mut guard = global_style_data.shared_lock.write();
|
||||||
|
declarations.write_with(&mut guard).push(prop, Importance::Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -1284,7 +1286,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetColorValue(declarations:
|
||||||
use style::properties::longhands;
|
use style::properties::longhands;
|
||||||
use style::values::specified::{Color, CSSColor};
|
use style::values::specified::{Color, CSSColor};
|
||||||
|
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
let long = get_longhand_from_id!(property);
|
let long = get_longhand_from_id!(property);
|
||||||
let rgba = convert_nscolor_to_rgba(value);
|
let rgba = convert_nscolor_to_rgba(value);
|
||||||
let color = CSSColor { parsed: Color::RGBA(rgba), authored: None };
|
let color = CSSColor { parsed: Color::RGBA(rgba), authored: None };
|
||||||
|
@ -1297,7 +1299,9 @@ pub extern "C" fn Servo_DeclarationBlock_SetColorValue(declarations:
|
||||||
Color => longhands::color::SpecifiedValue(color),
|
Color => longhands::color::SpecifiedValue(color),
|
||||||
BackgroundColor => color,
|
BackgroundColor => color,
|
||||||
};
|
};
|
||||||
declarations.write().push(prop, Importance::Normal);
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
let mut guard = global_style_data.shared_lock.write();
|
||||||
|
declarations.write_with(&mut guard).push(prop, Importance::Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -1308,13 +1312,15 @@ pub extern "C" fn Servo_DeclarationBlock_SetFontFamily(declarations:
|
||||||
use style::properties::PropertyDeclaration;
|
use style::properties::PropertyDeclaration;
|
||||||
use style::properties::longhands::font_family::SpecifiedValue as FontFamily;
|
use style::properties::longhands::font_family::SpecifiedValue as FontFamily;
|
||||||
|
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
let string = unsafe { (*value).to_string() };
|
let string = unsafe { (*value).to_string() };
|
||||||
let mut parser = Parser::new(&string);
|
let mut parser = Parser::new(&string);
|
||||||
if let Ok(family) = FontFamily::parse(&mut parser) {
|
if let Ok(family) = FontFamily::parse(&mut parser) {
|
||||||
if parser.is_exhausted() {
|
if parser.is_exhausted() {
|
||||||
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
let mut guard = global_style_data.shared_lock.write();
|
||||||
let decl = PropertyDeclaration::FontFamily(family);
|
let decl = PropertyDeclaration::FontFamily(family);
|
||||||
declarations.write().push(decl, Importance::Normal);
|
declarations.write_with(&mut guard).push(decl, Importance::Normal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1325,11 +1331,14 @@ pub extern "C" fn Servo_DeclarationBlock_SetTextDecorationColorOverride(declarat
|
||||||
use style::properties::PropertyDeclaration;
|
use style::properties::PropertyDeclaration;
|
||||||
use style::properties::longhands::text_decoration_line;
|
use style::properties::longhands::text_decoration_line;
|
||||||
|
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
let mut guard = global_style_data.shared_lock.write();
|
||||||
|
|
||||||
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
let mut decoration = text_decoration_line::computed_value::none;
|
let mut decoration = text_decoration_line::computed_value::none;
|
||||||
decoration |= text_decoration_line::COLOR_OVERRIDE;
|
decoration |= text_decoration_line::COLOR_OVERRIDE;
|
||||||
let decl = PropertyDeclaration::TextDecorationLine(decoration);
|
let decl = PropertyDeclaration::TextDecorationLine(decoration);
|
||||||
declarations.write().push(decl, Importance::Normal);
|
declarations.write_with(&mut guard).push(decl, Importance::Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -1523,6 +1532,11 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis
|
||||||
use style::properties::LonghandIdSet;
|
use style::properties::LonghandIdSet;
|
||||||
use style::properties::declaration_block::Importance;
|
use style::properties::declaration_block::Importance;
|
||||||
use style::values::computed::Context;
|
use style::values::computed::Context;
|
||||||
|
|
||||||
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
let guard = global_style_data.shared_lock.read();
|
||||||
|
|
||||||
|
|
||||||
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
||||||
|
|
||||||
let style = ComputedValues::as_arc(&style);
|
let style = ComputedValues::as_arc(&style);
|
||||||
|
@ -1549,8 +1563,8 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis
|
||||||
.filter(|&property| !property.mServoDeclarationBlock.mRawPtr.is_null());
|
.filter(|&property| !property.mServoDeclarationBlock.mRawPtr.is_null());
|
||||||
for property in iter {
|
for property in iter {
|
||||||
let declarations = unsafe { &*property.mServoDeclarationBlock.mRawPtr.clone() };
|
let declarations = unsafe { &*property.mServoDeclarationBlock.mRawPtr.clone() };
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
let guard = declarations.read();
|
let guard = declarations.read_with(&guard);
|
||||||
|
|
||||||
let anim_iter = guard.declarations()
|
let anim_iter = guard.declarations()
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -1614,15 +1628,18 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet
|
||||||
use style::gecko_bindings::structs::Keyframe;
|
use style::gecko_bindings::structs::Keyframe;
|
||||||
use style::properties::LonghandIdSet;
|
use style::properties::LonghandIdSet;
|
||||||
|
|
||||||
|
|
||||||
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
||||||
let name = unsafe { Atom::from(name.as_ref().unwrap().as_str_unchecked()) };
|
let name = unsafe { Atom::from(name.as_ref().unwrap().as_str_unchecked()) };
|
||||||
let style_timing_function = unsafe { timing_function.as_ref().unwrap() };
|
let style_timing_function = unsafe { timing_function.as_ref().unwrap() };
|
||||||
let style = ComputedValues::as_arc(&style);
|
let style = ComputedValues::as_arc(&style);
|
||||||
|
|
||||||
if let Some(ref animation) = data.stylist.animations().get(&name) {
|
if let Some(ref animation) = data.stylist.animations().get(&name) {
|
||||||
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
let guard = global_style_data.shared_lock.read();
|
||||||
for step in &animation.steps {
|
for step in &animation.steps {
|
||||||
// Override timing_function if the keyframe has animation-timing-function.
|
// Override timing_function if the keyframe has animation-timing-function.
|
||||||
let timing_function = if let Some(val) = step.get_animation_timing_function() {
|
let timing_function = if let Some(val) = step.get_animation_timing_function(&guard) {
|
||||||
val.into()
|
val.into()
|
||||||
} else {
|
} else {
|
||||||
*style_timing_function
|
*style_timing_function
|
||||||
|
@ -1637,7 +1654,8 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet
|
||||||
fn add_computed_property_value(keyframe: *mut Keyframe,
|
fn add_computed_property_value(keyframe: *mut Keyframe,
|
||||||
index: usize,
|
index: usize,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
property: &TransitionProperty) {
|
property: &TransitionProperty,
|
||||||
|
shared_lock: &SharedRwLock) {
|
||||||
let block = style.to_declaration_block(property.clone().into());
|
let block = style.to_declaration_block(property.clone().into());
|
||||||
unsafe {
|
unsafe {
|
||||||
(*keyframe).mPropertyValues.set_len((index + 1) as u32);
|
(*keyframe).mPropertyValues.set_len((index + 1) as u32);
|
||||||
|
@ -1645,18 +1663,19 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet
|
||||||
// FIXME. Do not set computed values once we handles missing keyframes
|
// FIXME. Do not set computed values once we handles missing keyframes
|
||||||
// with additive composition.
|
// with additive composition.
|
||||||
(*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky(
|
(*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky(
|
||||||
Arc::new(RwLock::new(block)));
|
Arc::new(shared_lock.wrap(block)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match step.value {
|
match step.value {
|
||||||
KeyframesStepValue::ComputedValues => {
|
KeyframesStepValue::ComputedValues => {
|
||||||
for (index, property) in animation.properties_changed.iter().enumerate() {
|
for (index, property) in animation.properties_changed.iter().enumerate() {
|
||||||
add_computed_property_value(keyframe, index, style, property);
|
add_computed_property_value(
|
||||||
|
keyframe, index, style, property, &global_style_data.shared_lock);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
KeyframesStepValue::Declarations { ref block } => {
|
KeyframesStepValue::Declarations { ref block } => {
|
||||||
let guard = block.read();
|
let guard = block.read_with(&guard);
|
||||||
// Filter out non-animatable properties.
|
// Filter out non-animatable properties.
|
||||||
let animatable =
|
let animatable =
|
||||||
guard.declarations()
|
guard.declarations()
|
||||||
|
@ -1673,7 +1692,8 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet
|
||||||
(*keyframe).mPropertyValues.set_len((index + 1) as u32);
|
(*keyframe).mPropertyValues.set_len((index + 1) as u32);
|
||||||
(*keyframe).mPropertyValues[index].mProperty = property.into();
|
(*keyframe).mPropertyValues[index].mProperty = property.into();
|
||||||
(*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky(
|
(*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky(
|
||||||
Arc::new(RwLock::new(PropertyDeclarationBlock::with_one(
|
Arc::new(global_style_data.shared_lock.wrap(
|
||||||
|
PropertyDeclarationBlock::with_one(
|
||||||
declaration.clone(), Importance::Normal
|
declaration.clone(), Importance::Normal
|
||||||
))));
|
))));
|
||||||
if step.start_percentage.0 == 0. ||
|
if step.start_percentage.0 == 0. ||
|
||||||
|
@ -1689,7 +1709,8 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet
|
||||||
let mut index = unsafe { (*keyframe).mPropertyValues.len() };
|
let mut index = unsafe { (*keyframe).mPropertyValues.len() };
|
||||||
for property in animation.properties_changed.iter() {
|
for property in animation.properties_changed.iter() {
|
||||||
if !seen.has_transition_property_bit(&property) {
|
if !seen.has_transition_property_bit(&property) {
|
||||||
add_computed_property_value(keyframe, index, style, property);
|
add_computed_property_value(
|
||||||
|
keyframe, index, style, property, &global_style_data.shared_lock);
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,7 @@ extern crate env_logger;
|
||||||
#[macro_use] extern crate lazy_static;
|
#[macro_use] extern crate lazy_static;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
#[macro_use] extern crate log;
|
#[macro_use] extern crate log;
|
||||||
extern crate num_cpus;
|
|
||||||
extern crate parking_lot;
|
extern crate parking_lot;
|
||||||
extern crate rayon;
|
|
||||||
extern crate selectors;
|
extern crate selectors;
|
||||||
extern crate servo_url;
|
extern crate servo_url;
|
||||||
#[macro_use] extern crate style;
|
#[macro_use] extern crate style;
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use style::gecko::global_style_data::GLOBAL_STYLE_DATA;
|
||||||
use style::gecko_bindings::bindings::Gecko_LoadStyleSheet;
|
use style::gecko_bindings::bindings::Gecko_LoadStyleSheet;
|
||||||
use style::gecko_bindings::structs::{Loader, ServoStyleSheet};
|
use style::gecko_bindings::structs::{Loader, ServoStyleSheet};
|
||||||
use style::gecko_bindings::sugar::ownership::HasArcFFI;
|
use style::gecko_bindings::sugar::ownership::HasArcFFI;
|
||||||
use style::shared_lock::Locked;
|
use style::shared_lock::Locked;
|
||||||
use style::stylesheets::{ImportRule, StylesheetLoader as StyleStylesheetLoader};
|
use style::stylesheets::{ImportRule, StylesheetLoader as StyleStylesheetLoader};
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use super::glue::GLOBAL_STYLE_DATA;
|
|
||||||
|
|
||||||
pub struct StylesheetLoader(*mut Loader, *mut ServoStyleSheet);
|
pub struct StylesheetLoader(*mut Loader, *mut ServoStyleSheet);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use parking_lot::RwLock;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use style::keyframes::{Keyframe, KeyframesAnimation, KeyframePercentage, KeyframeSelector};
|
use style::keyframes::{Keyframe, KeyframesAnimation, KeyframePercentage, KeyframeSelector};
|
||||||
use style::keyframes::{KeyframesStep, KeyframesStepValue};
|
use style::keyframes::{KeyframesStep, KeyframesStepValue};
|
||||||
|
@ -30,7 +29,7 @@ fn test_no_property_in_keyframe() {
|
||||||
let keyframes = vec![
|
let keyframes = vec![
|
||||||
Arc::new(shared_lock.wrap(Keyframe {
|
Arc::new(shared_lock.wrap(Keyframe {
|
||||||
selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(1.)]),
|
selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(1.)]),
|
||||||
block: Arc::new(RwLock::new(PropertyDeclarationBlock::new()))
|
block: Arc::new(shared_lock.wrap(PropertyDeclarationBlock::new()))
|
||||||
})),
|
})),
|
||||||
];
|
];
|
||||||
let animation = KeyframesAnimation::from_keyframes(&keyframes, &shared_lock.read());
|
let animation = KeyframesAnimation::from_keyframes(&keyframes, &shared_lock.read());
|
||||||
|
@ -46,14 +45,14 @@ fn test_no_property_in_keyframe() {
|
||||||
fn test_missing_property_in_initial_keyframe() {
|
fn test_missing_property_in_initial_keyframe() {
|
||||||
let shared_lock = SharedRwLock::new();
|
let shared_lock = SharedRwLock::new();
|
||||||
let declarations_on_initial_keyframe =
|
let declarations_on_initial_keyframe =
|
||||||
Arc::new(RwLock::new(PropertyDeclarationBlock::with_one(
|
Arc::new(shared_lock.wrap(PropertyDeclarationBlock::with_one(
|
||||||
PropertyDeclaration::Width(
|
PropertyDeclaration::Width(
|
||||||
LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32))),
|
LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32))),
|
||||||
Importance::Normal
|
Importance::Normal
|
||||||
)));
|
)));
|
||||||
|
|
||||||
let declarations_on_final_keyframe =
|
let declarations_on_final_keyframe =
|
||||||
Arc::new(RwLock::new({
|
Arc::new(shared_lock.wrap({
|
||||||
let mut block = PropertyDeclarationBlock::new();
|
let mut block = PropertyDeclarationBlock::new();
|
||||||
block.push(
|
block.push(
|
||||||
PropertyDeclaration::Width(
|
PropertyDeclaration::Width(
|
||||||
|
@ -103,7 +102,7 @@ fn test_missing_property_in_initial_keyframe() {
|
||||||
fn test_missing_property_in_final_keyframe() {
|
fn test_missing_property_in_final_keyframe() {
|
||||||
let shared_lock = SharedRwLock::new();
|
let shared_lock = SharedRwLock::new();
|
||||||
let declarations_on_initial_keyframe =
|
let declarations_on_initial_keyframe =
|
||||||
Arc::new(RwLock::new({
|
Arc::new(shared_lock.wrap({
|
||||||
let mut block = PropertyDeclarationBlock::new();
|
let mut block = PropertyDeclarationBlock::new();
|
||||||
block.push(
|
block.push(
|
||||||
PropertyDeclaration::Width(
|
PropertyDeclaration::Width(
|
||||||
|
@ -119,7 +118,7 @@ fn test_missing_property_in_final_keyframe() {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let declarations_on_final_keyframe =
|
let declarations_on_final_keyframe =
|
||||||
Arc::new(RwLock::new(PropertyDeclarationBlock::with_one(
|
Arc::new(shared_lock.wrap(PropertyDeclarationBlock::with_one(
|
||||||
PropertyDeclaration::Height(
|
PropertyDeclaration::Height(
|
||||||
LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32))),
|
LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32))),
|
||||||
Importance::Normal,
|
Importance::Normal,
|
||||||
|
@ -160,7 +159,7 @@ fn test_missing_property_in_final_keyframe() {
|
||||||
fn test_missing_keyframe_in_both_of_initial_and_final_keyframe() {
|
fn test_missing_keyframe_in_both_of_initial_and_final_keyframe() {
|
||||||
let shared_lock = SharedRwLock::new();
|
let shared_lock = SharedRwLock::new();
|
||||||
let declarations =
|
let declarations =
|
||||||
Arc::new(RwLock::new({
|
Arc::new(shared_lock.wrap({
|
||||||
let mut block = PropertyDeclarationBlock::new();
|
let mut block = PropertyDeclarationBlock::new();
|
||||||
block.push(
|
block.push(
|
||||||
PropertyDeclaration::Width(
|
PropertyDeclaration::Width(
|
||||||
|
@ -178,7 +177,7 @@ fn test_missing_keyframe_in_both_of_initial_and_final_keyframe() {
|
||||||
let keyframes = vec![
|
let keyframes = vec![
|
||||||
Arc::new(shared_lock.wrap(Keyframe {
|
Arc::new(shared_lock.wrap(Keyframe {
|
||||||
selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.)]),
|
selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.)]),
|
||||||
block: Arc::new(RwLock::new(PropertyDeclarationBlock::new()))
|
block: Arc::new(shared_lock.wrap(PropertyDeclarationBlock::new()))
|
||||||
})),
|
})),
|
||||||
Arc::new(shared_lock.wrap(Keyframe {
|
Arc::new(shared_lock.wrap(Keyframe {
|
||||||
selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.5)]),
|
selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.5)]),
|
||||||
|
@ -191,7 +190,7 @@ fn test_missing_keyframe_in_both_of_initial_and_final_keyframe() {
|
||||||
KeyframesStep {
|
KeyframesStep {
|
||||||
start_percentage: KeyframePercentage(0.),
|
start_percentage: KeyframePercentage(0.),
|
||||||
value: KeyframesStepValue::Declarations {
|
value: KeyframesStepValue::Declarations {
|
||||||
block: Arc::new(RwLock::new(
|
block: Arc::new(shared_lock.wrap(
|
||||||
// XXX: Should we use ComputedValues in this case?
|
// XXX: Should we use ComputedValues in this case?
|
||||||
PropertyDeclarationBlock::new()
|
PropertyDeclarationBlock::new()
|
||||||
))
|
))
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use cssparser::{Parser, SourcePosition};
|
use cssparser::{Parser, SourcePosition};
|
||||||
use parking_lot::RwLock;
|
|
||||||
use rayon;
|
use rayon;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -65,9 +64,11 @@ fn test_insertion(rule_tree: &RuleTree, rules: Vec<(StyleSource, CascadeLevel)>)
|
||||||
rule_tree.insert_ordered_rules(rules.into_iter())
|
rule_tree.insert_ordered_rules(rules.into_iter())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_insertion_style_attribute(rule_tree: &RuleTree, rules: &[(StyleSource, CascadeLevel)]) -> StrongRuleNode {
|
fn test_insertion_style_attribute(rule_tree: &RuleTree, rules: &[(StyleSource, CascadeLevel)],
|
||||||
|
shared_lock: &SharedRwLock)
|
||||||
|
-> StrongRuleNode {
|
||||||
let mut rules = rules.to_vec();
|
let mut rules = rules.to_vec();
|
||||||
rules.push((StyleSource::Declarations(Arc::new(RwLock::new(PropertyDeclarationBlock::with_one(
|
rules.push((StyleSource::Declarations(Arc::new(shared_lock.wrap(PropertyDeclarationBlock::with_one(
|
||||||
PropertyDeclaration::Display(
|
PropertyDeclaration::Display(
|
||||||
longhands::display::SpecifiedValue::block),
|
longhands::display::SpecifiedValue::block),
|
||||||
Importance::Normal
|
Importance::Normal
|
||||||
|
@ -121,11 +122,12 @@ fn bench_expensive_insertion(b: &mut Bencher) {
|
||||||
.bar { height: 500px; } \
|
.bar { height: 500px; } \
|
||||||
.baz { display: block; }");
|
.baz { display: block; }");
|
||||||
|
|
||||||
|
let shared_lock = SharedRwLock::new();
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let _gc = AutoGCRuleTree::new(&r);
|
let _gc = AutoGCRuleTree::new(&r);
|
||||||
|
|
||||||
for _ in 0..(4000 + 400) {
|
for _ in 0..(4000 + 400) {
|
||||||
test::black_box(test_insertion_style_attribute(&r, &rules_matched));
|
test::black_box(test_insertion_style_attribute(&r, &rules_matched, &shared_lock));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -170,6 +172,7 @@ fn bench_expensive_insersion_parallel(b: &mut Bencher) {
|
||||||
.bar { height: 500px; } \
|
.bar { height: 500px; } \
|
||||||
.baz { display: block; }");
|
.baz { display: block; }");
|
||||||
|
|
||||||
|
let shared_lock = SharedRwLock::new();
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let _gc = AutoGCRuleTree::new(&r);
|
let _gc = AutoGCRuleTree::new(&r);
|
||||||
|
|
||||||
|
@ -178,12 +181,14 @@ fn bench_expensive_insersion_parallel(b: &mut Bencher) {
|
||||||
s.spawn(|s| {
|
s.spawn(|s| {
|
||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
test::black_box(test_insertion_style_attribute(&r,
|
test::black_box(test_insertion_style_attribute(&r,
|
||||||
&rules_matched));
|
&rules_matched,
|
||||||
|
&shared_lock));
|
||||||
}
|
}
|
||||||
s.spawn(|_| {
|
s.spawn(|_| {
|
||||||
for _ in 0..100 {
|
for _ in 0..100 {
|
||||||
test::black_box(test_insertion_style_attribute(&r,
|
test::black_box(test_insertion_style_attribute(&r,
|
||||||
&rules_matched));
|
&rules_matched,
|
||||||
|
&shared_lock));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -109,7 +109,7 @@ fn test_parse_stylesheet() {
|
||||||
specificity: (0 << 20) + (1 << 10) + (1 << 0),
|
specificity: (0 << 20) + (1 << 10) + (1 << 0),
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
block: Arc::new(RwLock::new(block_from(vec![
|
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
|
||||||
(PropertyDeclaration::Display(longhands::display::SpecifiedValue::none),
|
(PropertyDeclaration::Display(longhands::display::SpecifiedValue::none),
|
||||||
Importance::Important),
|
Importance::Important),
|
||||||
(PropertyDeclaration::Custom(Atom::from("a"),
|
(PropertyDeclaration::Custom(Atom::from("a"),
|
||||||
|
@ -154,7 +154,7 @@ fn test_parse_stylesheet() {
|
||||||
specificity: (0 << 20) + (0 << 10) + (1 << 0),
|
specificity: (0 << 20) + (0 << 10) + (1 << 0),
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
block: Arc::new(RwLock::new(block_from(vec![
|
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
|
||||||
(PropertyDeclaration::Display(longhands::display::SpecifiedValue::block),
|
(PropertyDeclaration::Display(longhands::display::SpecifiedValue::block),
|
||||||
Importance::Normal),
|
Importance::Normal),
|
||||||
]))),
|
]))),
|
||||||
|
@ -185,7 +185,7 @@ fn test_parse_stylesheet() {
|
||||||
specificity: (1 << 20) + (1 << 10) + (0 << 0),
|
specificity: (1 << 20) + (1 << 10) + (0 << 0),
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
block: Arc::new(RwLock::new(block_from(vec![
|
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
|
||||||
(PropertyDeclaration::BackgroundColor(
|
(PropertyDeclaration::BackgroundColor(
|
||||||
longhands::background_color::SpecifiedValue {
|
longhands::background_color::SpecifiedValue {
|
||||||
authored: Some("blue".to_owned().into_boxed_str()),
|
authored: Some("blue".to_owned().into_boxed_str()),
|
||||||
|
@ -241,7 +241,7 @@ fn test_parse_stylesheet() {
|
||||||
Arc::new(stylesheet.shared_lock.wrap(Keyframe {
|
Arc::new(stylesheet.shared_lock.wrap(Keyframe {
|
||||||
selector: KeyframeSelector::new_for_unit_testing(
|
selector: KeyframeSelector::new_for_unit_testing(
|
||||||
vec![KeyframePercentage::new(0.)]),
|
vec![KeyframePercentage::new(0.)]),
|
||||||
block: Arc::new(RwLock::new(block_from(vec![
|
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
|
||||||
(PropertyDeclaration::Width(
|
(PropertyDeclaration::Width(
|
||||||
LengthOrPercentageOrAuto::Percentage(Percentage(0.))),
|
LengthOrPercentageOrAuto::Percentage(Percentage(0.))),
|
||||||
Importance::Normal),
|
Importance::Normal),
|
||||||
|
@ -250,7 +250,7 @@ fn test_parse_stylesheet() {
|
||||||
Arc::new(stylesheet.shared_lock.wrap(Keyframe {
|
Arc::new(stylesheet.shared_lock.wrap(Keyframe {
|
||||||
selector: KeyframeSelector::new_for_unit_testing(
|
selector: KeyframeSelector::new_for_unit_testing(
|
||||||
vec![KeyframePercentage::new(1.)]),
|
vec![KeyframePercentage::new(1.)]),
|
||||||
block: Arc::new(RwLock::new(block_from(vec![
|
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
|
||||||
(PropertyDeclaration::Width(
|
(PropertyDeclaration::Width(
|
||||||
LengthOrPercentageOrAuto::Percentage(Percentage(1.))),
|
LengthOrPercentageOrAuto::Percentage(Percentage(1.))),
|
||||||
Importance::Normal),
|
Importance::Normal),
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use html5ever_atoms::LocalName;
|
use html5ever_atoms::LocalName;
|
||||||
use parking_lot::RwLock;
|
|
||||||
use selectors::parser::LocalName as LocalNameSelector;
|
use selectors::parser::LocalName as LocalNameSelector;
|
||||||
use servo_atoms::Atom;
|
use servo_atoms::Atom;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -25,7 +24,7 @@ fn get_mock_rules(css_selectors: &[&str]) -> (Vec<Vec<Rule>>, SharedRwLock) {
|
||||||
|
|
||||||
let locked = Arc::new(shared_lock.wrap(StyleRule {
|
let locked = Arc::new(shared_lock.wrap(StyleRule {
|
||||||
selectors: selectors,
|
selectors: selectors,
|
||||||
block: Arc::new(RwLock::new(PropertyDeclarationBlock::with_one(
|
block: Arc::new(shared_lock.wrap(PropertyDeclarationBlock::with_one(
|
||||||
PropertyDeclaration::Display(
|
PropertyDeclaration::Display(
|
||||||
longhands::display::SpecifiedValue::block),
|
longhands::display::SpecifiedValue::block),
|
||||||
Importance::Normal
|
Importance::Normal
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue