aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_thread
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2018-09-05 06:33:16 -0400
committerGitHub <noreply@github.com>2018-09-05 06:33:16 -0400
commitd05cebdc6b68b93a239e848fd9d63a95edf5f09a (patch)
treedcf078d44dae6388e542595b6ab4284a83241816 /components/layout_thread
parent4d1801424130d6fc8ee60d187930a0de2b119152 (diff)
parent840e696ad9857705352a897ce8c233ae7ccef604 (diff)
downloadservo-d05cebdc6b68b93a239e848fd9d63a95edf5f09a.tar.gz
servo-d05cebdc6b68b93a239e848fd9d63a95edf5f09a.zip
Auto merge of #21613 - pyfisch:layout_thread-fmt, r=Manishearth
Rustfmt layout_thread crate Part of #21373. Checked all changes looks good. :tada: Manually removed two optional semicolons within unsafe so that it is formatted in one line. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/21613) <!-- Reviewable:end -->
Diffstat (limited to 'components/layout_thread')
-rw-r--r--components/layout_thread/dom_wrapper.rs368
-rw-r--r--components/layout_thread/lib.rs1272
2 files changed, 921 insertions, 719 deletions
diff --git a/components/layout_thread/dom_wrapper.rs b/components/layout_thread/dom_wrapper.rs
index 4800704fca8..204ff023c97 100644
--- a/components/layout_thread/dom_wrapper.rs
+++ b/components/layout_thread/dom_wrapper.rs
@@ -133,17 +133,13 @@ impl<'ln> ServoLayoutNode<'ln> {
}
fn script_type_id(&self) -> NodeTypeId {
- unsafe {
- self.node.type_id_for_layout()
- }
+ unsafe { self.node.type_id_for_layout() }
}
}
impl<'ln> NodeInfo for ServoLayoutNode<'ln> {
fn is_element(&self) -> bool {
- unsafe {
- self.node.is_element_for_layout()
- }
+ unsafe { self.node.is_element_for_layout() }
}
fn is_text_node(&self) -> bool {
@@ -152,7 +148,7 @@ impl<'ln> NodeInfo for ServoLayoutNode<'ln> {
}
#[derive(Clone, Copy, PartialEq)]
-enum Impossible { }
+enum Impossible {}
#[derive(Clone, Copy, PartialEq)]
pub struct ShadowRoot<'lr>(Impossible, PhantomData<&'lr ()>);
@@ -161,18 +157,18 @@ impl<'lr> TShadowRoot for ShadowRoot<'lr> {
type ConcreteNode = ServoLayoutNode<'lr>;
fn as_node(&self) -> Self::ConcreteNode {
- match self.0 { }
+ match self.0 {}
}
fn host(&self) -> ServoLayoutElement<'lr> {
- match self.0 { }
+ match self.0 {}
}
fn style_data<'a>(&self) -> Option<&'a CascadeData>
where
Self: 'a,
{
- match self.0 { }
+ match self.0 {}
}
}
@@ -183,31 +179,41 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {
fn parent_node(&self) -> Option<Self> {
unsafe {
- self.node.parent_node_ref().map(|node| self.new_with_this_lifetime(&node))
+ self.node
+ .parent_node_ref()
+ .map(|node| self.new_with_this_lifetime(&node))
}
}
fn first_child(&self) -> Option<Self> {
unsafe {
- self.node.first_child_ref().map(|node| self.new_with_this_lifetime(&node))
+ self.node
+ .first_child_ref()
+ .map(|node| self.new_with_this_lifetime(&node))
}
}
fn last_child(&self) -> Option<Self> {
unsafe {
- self.node.last_child_ref().map(|node| self.new_with_this_lifetime(&node))
+ self.node
+ .last_child_ref()
+ .map(|node| self.new_with_this_lifetime(&node))
}
}
fn prev_sibling(&self) -> Option<Self> {
unsafe {
- self.node.prev_sibling_ref().map(|node| self.new_with_this_lifetime(&node))
+ self.node
+ .prev_sibling_ref()
+ .map(|node| self.new_with_this_lifetime(&node))
}
}
fn next_sibling(&self) -> Option<Self> {
unsafe {
- self.node.next_sibling_ref().map(|node| self.new_with_this_lifetime(&node))
+ self.node
+ .next_sibling_ref()
+ .map(|node| self.new_with_this_lifetime(&node))
}
}
@@ -232,7 +238,9 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {
}
fn as_document(&self) -> Option<ServoLayoutDocument<'ln>> {
- self.node.downcast().map(ServoLayoutDocument::from_layout_js)
+ self.node
+ .downcast()
+ .map(ServoLayoutDocument::from_layout_js)
}
fn as_shadow_root(&self) -> Option<ShadowRoot<'ln>> {
@@ -257,8 +265,7 @@ impl<'ln> LayoutNode for ServoLayoutNode<'ln> {
unsafe fn initialize_data(&self) {
if self.get_raw_data().is_none() {
- let ptr: *mut StyleAndLayoutData =
- Box::into_raw(Box::new(StyleAndLayoutData::new()));
+ let ptr: *mut StyleAndLayoutData = Box::into_raw(Box::new(StyleAndLayoutData::new()));
let opaque = OpaqueStyleAndLayoutData {
ptr: NonNull::new_unchecked(ptr as *mut StyleData),
};
@@ -277,9 +284,7 @@ impl<'ln> LayoutNode for ServoLayoutNode<'ln> {
impl<'ln> GetLayoutData for ServoLayoutNode<'ln> {
fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> {
- unsafe {
- self.get_jsmanaged().get_style_and_layout_data()
- }
+ unsafe { self.get_jsmanaged().get_style_and_layout_data() }
}
}
@@ -334,20 +339,26 @@ impl<'ld> TDocument for ServoLayoutDocument<'ld> {
impl<'ld> ServoLayoutDocument<'ld> {
pub fn root_element(&self) -> Option<ServoLayoutElement<'ld>> {
- self.as_node().dom_children().flat_map(|n| n.as_element()).next()
+ self.as_node()
+ .dom_children()
+ .flat_map(|n| n.as_element())
+ .next()
}
pub fn drain_pending_restyles(&self) -> Vec<(ServoLayoutElement<'ld>, PendingRestyle)> {
- let elements = unsafe { self.document.drain_pending_restyles() };
- elements.into_iter().map(|(el, snapshot)| (ServoLayoutElement::from_layout_js(el), snapshot)).collect()
+ let elements = unsafe { self.document.drain_pending_restyles() };
+ elements
+ .into_iter()
+ .map(|(el, snapshot)| (ServoLayoutElement::from_layout_js(el), snapshot))
+ .collect()
}
pub fn needs_paint_from_layout(&self) {
- unsafe { self.document.needs_paint_from_layout(); }
+ unsafe { self.document.needs_paint_from_layout() }
}
pub fn will_paint(&self) {
- unsafe { self.document.will_paint(); }
+ unsafe { self.document.will_paint() }
}
pub fn style_shared_lock(&self) -> &StyleSharedRwLock {
@@ -407,7 +418,9 @@ impl<'le> TElement for ServoLayoutElement<'le> {
fn style_attribute(&self) -> Option<ArcBorrow<StyleLocked<PropertyDeclarationBlock>>> {
unsafe {
- (*self.element.style_attribute()).as_ref().map(|x| x.borrow_arc())
+ (*self.element.style_attribute())
+ .as_ref()
+ .map(|x| x.borrow_arc())
}
}
@@ -422,13 +435,14 @@ impl<'le> TElement for ServoLayoutElement<'le> {
#[inline]
fn id(&self) -> Option<&Atom> {
- unsafe {
- (*self.element.id_attribute()).as_ref()
- }
+ unsafe { (*self.element.id_attribute()).as_ref() }
}
#[inline(always)]
- fn each_class<F>(&self, mut callback: F) where F: FnMut(&Atom) {
+ fn each_class<F>(&self, mut callback: F)
+ where
+ F: FnMut(&Atom),
+ {
unsafe {
if let Some(ref classes) = self.element.get_classes_for_layout() {
for class in *classes {
@@ -439,7 +453,11 @@ impl<'le> TElement for ServoLayoutElement<'le> {
}
fn has_dirty_descendants(&self) -> bool {
- unsafe { self.as_node().node.get_flag(NodeFlags::HAS_DIRTY_DESCENDANTS) }
+ unsafe {
+ self.as_node()
+ .node
+ .get_flag(NodeFlags::HAS_DIRTY_DESCENDANTS)
+ }
}
fn has_snapshot(&self) -> bool {
@@ -451,26 +469,37 @@ impl<'le> TElement for ServoLayoutElement<'le> {
}
unsafe fn set_handled_snapshot(&self) {
- self.as_node().node.set_flag(NodeFlags::HANDLED_SNAPSHOT, true);
+ self.as_node()
+ .node
+ .set_flag(NodeFlags::HANDLED_SNAPSHOT, true);
}
unsafe fn set_dirty_descendants(&self) {
debug_assert!(self.as_node().is_in_document());
- self.as_node().node.set_flag(NodeFlags::HAS_DIRTY_DESCENDANTS, true)
+ self.as_node()
+ .node
+ .set_flag(NodeFlags::HAS_DIRTY_DESCENDANTS, true)
}
unsafe fn unset_dirty_descendants(&self) {
- self.as_node().node.set_flag(NodeFlags::HAS_DIRTY_DESCENDANTS, false)
+ self.as_node()
+ .node
+ .set_flag(NodeFlags::HAS_DIRTY_DESCENDANTS, false)
}
fn store_children_to_process(&self, n: isize) {
let data = self.get_style_data().unwrap();
- data.parallel.children_to_process.store(n, Ordering::Relaxed);
+ data.parallel
+ .children_to_process
+ .store(n, Ordering::Relaxed);
}
fn did_process_child(&self) -> isize {
let data = self.get_style_data().unwrap();
- let old_value = data.parallel.children_to_process.fetch_sub(1, Ordering::Relaxed);
+ let old_value = data
+ .parallel
+ .children_to_process
+ .fetch_sub(1, Ordering::Relaxed);
debug_assert!(old_value >= 1);
old_value - 1
}
@@ -488,9 +517,8 @@ impl<'le> TElement for ServoLayoutElement<'le> {
fn get_data(&self) -> Option<&AtomicRefCell<ElementData>> {
unsafe {
- self.get_style_and_layout_data().map(|d| {
- &(*(d.ptr.as_ptr() as *mut StyleData)).element_data
- })
+ self.get_style_and_layout_data()
+ .map(|d| &(*(d.ptr.as_ptr() as *mut StyleData)).element_data)
}
}
@@ -566,12 +594,12 @@ impl<'le> TElement for ServoLayoutElement<'le> {
&self,
_visited_handling: VisitedHandlingMode,
hints: &mut V,
- )
- where
+ ) where
V: Push<ApplicableDeclarationBlock>,
{
unsafe {
- self.element.synthesize_presentational_hints_for_legacy_attributes(hints);
+ self.element
+ .synthesize_presentational_hints_for_legacy_attributes(hints);
}
}
@@ -608,26 +636,25 @@ impl<'le> ServoLayoutElement<'le> {
#[inline]
fn get_attr_enum(&self, namespace: &Namespace, name: &LocalName) -> Option<&AttrValue> {
- unsafe {
- (*self.element.unsafe_get()).get_attr_for_layout(namespace, name)
- }
+ unsafe { (*self.element.unsafe_get()).get_attr_for_layout(namespace, name) }
}
#[inline]
fn get_attr(&self, namespace: &Namespace, name: &LocalName) -> Option<&str> {
- unsafe {
- (*self.element.unsafe_get()).get_attr_val_for_layout(namespace, name)
- }
+ unsafe { (*self.element.unsafe_get()).get_attr_val_for_layout(namespace, name) }
}
fn get_style_data(&self) -> Option<&StyleData> {
unsafe {
- self.get_style_and_layout_data().map(|d| &*(d.ptr.as_ptr() as *mut StyleData))
+ self.get_style_and_layout_data()
+ .map(|d| &*(d.ptr.as_ptr() as *mut StyleData))
}
}
pub unsafe fn unset_snapshot_flags(&self) {
- self.as_node().node.set_flag(NodeFlags::HAS_SNAPSHOT | NodeFlags::HANDLED_SNAPSHOT, false);
+ self.as_node()
+ .node
+ .set_flag(NodeFlags::HAS_SNAPSHOT | NodeFlags::HANDLED_SNAPSHOT, false);
}
pub unsafe fn set_has_snapshot(&self) {
@@ -662,9 +689,7 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
}
fn parent_element(&self) -> Option<ServoLayoutElement<'le>> {
- unsafe {
- self.element.upcast().parent_node_ref().and_then(as_element)
- }
+ unsafe { self.element.upcast().parent_node_ref().and_then(as_element) }
}
fn parent_node_is_shadow_root(&self) -> bool {
@@ -679,7 +704,7 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
let mut node = self.as_node();
while let Some(sibling) = node.prev_sibling() {
if let Some(element) = sibling.as_element() {
- return Some(element)
+ return Some(element);
}
node = sibling;
}
@@ -690,52 +715,51 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
let mut node = self.as_node();
while let Some(sibling) = node.next_sibling() {
if let Some(element) = sibling.as_element() {
- return Some(element)
+ return Some(element);
}
node = sibling;
}
None
}
- fn attr_matches(&self,
- ns: &NamespaceConstraint<&Namespace>,
- local_name: &LocalName,
- operation: &AttrSelectorOperation<&String>)
- -> bool {
+ fn attr_matches(
+ &self,
+ ns: &NamespaceConstraint<&Namespace>,
+ local_name: &LocalName,
+ operation: &AttrSelectorOperation<&String>,
+ ) -> bool {
match *ns {
- NamespaceConstraint::Specific(ref ns) => {
- self.get_attr_enum(ns, local_name)
- .map_or(false, |value| value.eval_selector(operation))
- }
+ NamespaceConstraint::Specific(ref ns) => self
+ .get_attr_enum(ns, local_name)
+ .map_or(false, |value| value.eval_selector(operation)),
NamespaceConstraint::Any => {
- let values = unsafe {
- (*self.element.unsafe_get()).get_attr_vals_for_layout(local_name)
- };
+ let values =
+ unsafe { (*self.element.unsafe_get()).get_attr_vals_for_layout(local_name) };
values.iter().any(|value| value.eval_selector(operation))
- }
+ },
}
}
fn is_root(&self) -> bool {
match self.as_node().parent_node() {
None => false,
- Some(node) => {
- match node.script_type_id() {
- NodeTypeId::Document(_) => true,
- _ => false
- }
+ Some(node) => match node.script_type_id() {
+ NodeTypeId::Document(_) => true,
+ _ => false,
},
}
}
fn is_empty(&self) -> bool {
- self.as_node().dom_children().all(|node| match node.script_type_id() {
- NodeTypeId::Element(..) => false,
- NodeTypeId::CharacterData(CharacterDataTypeId::Text) => unsafe {
- node.node.downcast().unwrap().data_for_layout().is_empty()
- },
- _ => true
- })
+ self.as_node()
+ .dom_children()
+ .all(|node| match node.script_type_id() {
+ NodeTypeId::Element(..) => false,
+ NodeTypeId::CharacterData(CharacterDataTypeId::Text) => unsafe {
+ node.node.downcast().unwrap().data_for_layout().is_empty()
+ },
+ _ => true,
+ })
}
#[inline]
@@ -767,24 +791,26 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
{
match *pseudo_class {
// https://github.com/servo/servo/issues/8718
- NonTSPseudoClass::Link |
- NonTSPseudoClass::AnyLink => self.is_link(),
+ NonTSPseudoClass::Link | NonTSPseudoClass::AnyLink => self.is_link(),
NonTSPseudoClass::Visited => false,
NonTSPseudoClass::Lang(ref lang) => self.match_element_lang(None, &*lang),
NonTSPseudoClass::ServoNonZeroBorder => unsafe {
- match (*self.element.unsafe_get()).get_attr_for_layout(&ns!(), &local_name!("border")) {
+ match (*self.element.unsafe_get())
+ .get_attr_for_layout(&ns!(), &local_name!("border"))
+ {
None | Some(&AttrValue::UInt(_, 0)) => false,
_ => true,
}
},
- NonTSPseudoClass::ServoCaseSensitiveTypeAttr(ref expected_value) => {
- self.get_attr_enum(&ns!(), &local_name!("type"))
- .map_or(false, |attr| attr == expected_value)
- }
- NonTSPseudoClass::ReadOnly =>
- !self.element.get_state_for_layout().contains(pseudo_class.state_flag()),
+ NonTSPseudoClass::ServoCaseSensitiveTypeAttr(ref expected_value) => self
+ .get_attr_enum(&ns!(), &local_name!("type"))
+ .map_or(false, |attr| attr == expected_value),
+ NonTSPseudoClass::ReadOnly => !self
+ .element
+ .get_state_for_layout()
+ .contains(pseudo_class.state_flag()),
NonTSPseudoClass::Active |
NonTSPseudoClass::Focus |
@@ -796,8 +822,10 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
NonTSPseudoClass::Indeterminate |
NonTSPseudoClass::ReadWrite |
NonTSPseudoClass::PlaceholderShown |
- NonTSPseudoClass::Target =>
- self.element.get_state_for_layout().contains(pseudo_class.state_flag())
+ NonTSPseudoClass::Target => self
+ .element
+ .get_state_for_layout()
+ .contains(pseudo_class.state_flag()),
}
}
@@ -806,10 +834,17 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
unsafe {
match self.as_node().script_type_id() {
// https://html.spec.whatwg.org/multipage/#selector-link
- NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) |
- NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAreaElement)) |
- NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) =>
- (*self.element.unsafe_get()).get_attr_val_for_layout(&ns!(), &local_name!("href")).is_some(),
+ NodeTypeId::Element(ElementTypeId::HTMLElement(
+ HTMLElementTypeId::HTMLAnchorElement,
+ )) |
+ NodeTypeId::Element(ElementTypeId::HTMLElement(
+ HTMLElementTypeId::HTMLAreaElement,
+ )) |
+ NodeTypeId::Element(ElementTypeId::HTMLElement(
+ HTMLElementTypeId::HTMLLinkElement,
+ )) => (*self.element.unsafe_get())
+ .get_attr_val_for_layout(&ns!(), &local_name!("href"))
+ .is_some(),
_ => false,
}
}
@@ -826,16 +861,11 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
#[inline]
fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool {
- unsafe {
- self.element.has_class_for_layout(name, case_sensitivity)
- }
+ unsafe { self.element.has_class_for_layout(name, case_sensitivity) }
}
fn is_html_slot_element(&self) -> bool {
- unsafe {
- self.element.is_html_element() &&
- self.local_name() == &local_name!("slot")
- }
+ unsafe { self.element.is_html_element() && self.local_name() == &local_name!("slot") }
}
fn is_html_element_in_html_document(&self) -> bool {
@@ -868,18 +898,23 @@ impl<'a> PartialEq for ServoThreadSafeLayoutNode<'a> {
impl<'ln> DangerousThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
unsafe fn dangerous_first_child(&self) -> Option<Self> {
- self.get_jsmanaged().first_child_ref()
- .map(|node| self.new_with_this_lifetime(&node))
+ self.get_jsmanaged()
+ .first_child_ref()
+ .map(|node| self.new_with_this_lifetime(&node))
}
unsafe fn dangerous_next_sibling(&self) -> Option<Self> {
- self.get_jsmanaged().next_sibling_ref()
- .map(|node| self.new_with_this_lifetime(&node))
+ self.get_jsmanaged()
+ .next_sibling_ref()
+ .map(|node| self.new_with_this_lifetime(&node))
}
}
impl<'ln> ServoThreadSafeLayoutNode<'ln> {
/// Creates a new layout node with the same lifetime as this layout node.
- pub unsafe fn new_with_this_lifetime(&self, node: &LayoutDom<Node>) -> ServoThreadSafeLayoutNode<'ln> {
+ pub unsafe fn new_with_this_lifetime(
+ &self,
+ node: &LayoutDom<Node>,
+ ) -> ServoThreadSafeLayoutNode<'ln> {
ServoThreadSafeLayoutNode {
node: self.node.new_with_this_lifetime(node),
pseudo: PseudoElementType::Normal,
@@ -944,10 +979,12 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
}
fn as_element(&self) -> Option<ServoThreadSafeLayoutElement<'ln>> {
- self.node.as_element().map(|el| ServoThreadSafeLayoutElement {
- element: el,
- pseudo: self.pseudo,
- })
+ self.node
+ .as_element()
+ .map(|el| ServoThreadSafeLayoutElement {
+ element: el,
+ pseudo: self.pseudo,
+ })
}
fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> {
@@ -958,11 +995,11 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
unsafe {
let text: LayoutDom<Text> = match self.get_jsmanaged().downcast() {
Some(text) => text,
- None => return false
+ None => return false,
};
if !is_whitespace(text.upcast().data_for_layout()) {
- return false
+ return false;
}
// NB: See the rules for `white-space` here:
@@ -971,7 +1008,11 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
//
// If you implement other values for this property, you will almost certainly
// want to update this check.
- !self.style(context).get_inherited_text().white_space.preserve_newlines()
+ !self
+ .style(context)
+ .get_inherited_text()
+ .white_space
+ .preserve_newlines()
}
}
@@ -988,8 +1029,10 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
let this = unsafe { self.get_jsmanaged() };
this.selection().map(|range| {
- Range::new(ByteIndex(range.start as isize),
- ByteIndex(range.len() as isize))
+ Range::new(
+ ByteIndex(range.start as isize),
+ ByteIndex(range.len() as isize),
+ )
})
}
@@ -1022,13 +1065,19 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
fn get_colspan(&self) -> u32 {
unsafe {
- self.get_jsmanaged().downcast::<Element>().unwrap().get_colspan()
+ self.get_jsmanaged()
+ .downcast::<Element>()
+ .unwrap()
+ .get_colspan()
}
}
fn get_rowspan(&self) -> u32 {
unsafe {
- self.get_jsmanaged().downcast::<Element>().unwrap().get_rowspan()
+ self.get_jsmanaged()
+ .downcast::<Element>()
+ .unwrap()
+ .get_rowspan()
}
}
}
@@ -1039,16 +1088,17 @@ pub struct ThreadSafeLayoutNodeChildrenIterator<ConcreteNode: ThreadSafeLayoutNo
}
impl<ConcreteNode> ThreadSafeLayoutNodeChildrenIterator<ConcreteNode>
- where ConcreteNode: DangerousThreadSafeLayoutNode {
+where
+ ConcreteNode: DangerousThreadSafeLayoutNode,
+{
pub fn new(parent: ConcreteNode) -> Self {
let first_child: Option<ConcreteNode> = match parent.get_pseudo_element_type() {
- PseudoElementType::Normal => {
- parent.get_before_pseudo().or_else(|| parent.get_details_summary_pseudo()).or_else(|| {
- unsafe { parent.dangerous_first_child() }
- })
- },
- PseudoElementType::DetailsContent | PseudoElementType::DetailsSummary => {
- unsafe { parent.dangerous_first_child() }
+ PseudoElementType::Normal => parent
+ .get_before_pseudo()
+ .or_else(|| parent.get_details_summary_pseudo())
+ .or_else(|| unsafe { parent.dangerous_first_child() }),
+ PseudoElementType::DetailsContent | PseudoElementType::DetailsSummary => unsafe {
+ parent.dangerous_first_child()
},
_ => None,
};
@@ -1060,7 +1110,9 @@ impl<ConcreteNode> ThreadSafeLayoutNodeChildrenIterator<ConcreteNode>
}
impl<ConcreteNode> Iterator for ThreadSafeLayoutNodeChildrenIterator<ConcreteNode>
- where ConcreteNode: DangerousThreadSafeLayoutNode {
+where
+ ConcreteNode: DangerousThreadSafeLayoutNode,
+{
type Item = ConcreteNode;
fn next(&mut self) -> Option<ConcreteNode> {
use ::selectors::Element;
@@ -1073,7 +1125,8 @@ impl<ConcreteNode> Iterator for ThreadSafeLayoutNodeChildrenIterator<ConcreteNod
let next_node = if let Some(ref node) = current_node {
if let Some(element) = node.as_element() {
if element.local_name() == &local_name!("summary") &&
- element.namespace() == &ns!(html) {
+ element.namespace() == &ns!(html)
+ {
self.current_node = None;
return Some(node.clone());
}
@@ -1081,18 +1134,19 @@ impl<ConcreteNode> Iterator for ThreadSafeLayoutNodeChildrenIterator<ConcreteNod
unsafe { node.dangerous_next_sibling() }
} else {
self.current_node = None;
- return None
+ return None;
};
current_node = next_node;
}
- }
+ },
PseudoElementType::DetailsContent => {
let node = self.current_node.clone();
let node = node.and_then(|node| {
if node.is_element() &&
- node.as_element().unwrap().local_name() == &local_name!("summary") &&
- node.as_element().unwrap().namespace() == &ns!(html) {
+ node.as_element().unwrap().local_name() == &local_name!("summary") &&
+ node.as_element().unwrap().namespace() == &ns!(html)
+ {
unsafe { node.dangerous_next_sibling() }
} else {
Some(node)
@@ -1100,28 +1154,28 @@ impl<ConcreteNode> Iterator for ThreadSafeLayoutNodeChildrenIterator<ConcreteNod
});
self.current_node = node.and_then(|node| unsafe { node.dangerous_next_sibling() });
node
- }
+ },
PseudoElementType::Normal => {
let node = self.current_node.clone();
if let Some(ref node) = node {
self.current_node = match node.get_pseudo_element_type() {
- PseudoElementType::Before => {
- self.parent_node.get_details_summary_pseudo()
- .or_else(|| unsafe { self.parent_node.dangerous_first_child() })
- .or_else(|| self.parent_node.get_after_pseudo())
+ PseudoElementType::Before => self
+ .parent_node
+ .get_details_summary_pseudo()
+ .or_else(|| unsafe { self.parent_node.dangerous_first_child() })
+ .or_else(|| self.parent_node.get_after_pseudo()),
+ PseudoElementType::Normal => unsafe { node.dangerous_next_sibling() }
+ .or_else(|| self.parent_node.get_after_pseudo()),
+ PseudoElementType::DetailsSummary => {
+ self.parent_node.get_details_content_pseudo()
},
- PseudoElementType::Normal => {
- unsafe { node.dangerous_next_sibling() }.or_else(|| self.parent_node.get_after_pseudo())
- },
- PseudoElementType::DetailsSummary => self.parent_node.get_details_content_pseudo(),
PseudoElementType::DetailsContent => self.parent_node.get_after_pseudo(),
PseudoElementType::After => None,
};
}
node
- }
-
+ },
}
}
}
@@ -1176,7 +1230,8 @@ impl<'le> ThreadSafeLayoutElement for ServoThreadSafeLayoutElement<'le> {
}
fn style_data(&self) -> AtomicRef<ElementData> {
- self.element.get_data()
+ self.element
+ .get_data()
.expect("Unstyled layout node?")
.borrow()
}
@@ -1201,7 +1256,6 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> {
::selectors::OpaqueElement::new(self.as_node().opaque().0 as *const ())
}
-
fn parent_element(&self) -> Option<Self> {
warn!("ServoThreadSafeLayoutElement::parent_element called");
None
@@ -1249,27 +1303,27 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> {
fn match_pseudo_element(
&self,
_pseudo: &PseudoElement,
- _context: &mut MatchingContext<Self::Impl>
+ _context: &mut MatchingContext<Self::Impl>,
) -> bool {
false
}
- fn attr_matches(&self,
- ns: &NamespaceConstraint<&Namespace>,
- local_name: &LocalName,
- operation: &AttrSelectorOperation<&String>)
- -> bool {
+ fn attr_matches(
+ &self,
+ ns: &NamespaceConstraint<&Namespace>,
+ local_name: &LocalName,
+ operation: &AttrSelectorOperation<&String>,
+ ) -> bool {
match *ns {
- NamespaceConstraint::Specific(ref ns) => {
- self.get_attr_enum(ns, local_name)
- .map_or(false, |value| value.eval_selector(operation))
- }
+ NamespaceConstraint::Specific(ref ns) => self
+ .get_attr_enum(ns, local_name)
+ .map_or(false, |value| value.eval_selector(operation)),
NamespaceConstraint::Any => {
let values = unsafe {
(*self.element.element.unsafe_get()).get_attr_vals_for_layout(local_name)
};
values.iter().any(|v| v.eval_selector(operation))
- }
+ },
}
}
diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs
index 1d5676b4b54..aa520215cd2 100644
--- a/components/layout_thread/lib.rs
+++ b/components/layout_thread/lib.rs
@@ -243,8 +243,7 @@ pub struct LayoutThread {
/// All the other elements of this struct are read-only.
rw_data: Arc<Mutex<LayoutThreadData>>,
- webrender_image_cache: Arc<RwLock<FnvHashMap<(ServoUrl, UsePlaceholder),
- WebRenderImageInfo>>>,
+ webrender_image_cache: Arc<RwLock<FnvHashMap<(ServoUrl, UsePlaceholder), WebRenderImageInfo>>>,
/// The executors for paint worklets.
registered_painters: RegisteredPaintersImpl,
@@ -274,57 +273,69 @@ impl LayoutThreadFactory for LayoutThread {
type Message = Msg;
/// Spawns a new layout thread.
- fn create(id: PipelineId,
- top_level_browsing_context_id: TopLevelBrowsingContextId,
- url: ServoUrl,
- is_iframe: bool,
- chan: (Sender<Msg>, Receiver<Msg>),
- pipeline_port: IpcReceiver<LayoutControlMsg>,
- constellation_chan: IpcSender<ConstellationMsg>,
- script_chan: IpcSender<ConstellationControlMsg>,
- image_cache: Arc<ImageCache>,
- font_cache_thread: FontCacheThread,
- time_profiler_chan: time::ProfilerChan,
- mem_profiler_chan: mem::ProfilerChan,
- content_process_shutdown_chan: Option<IpcSender<()>>,
- webrender_api_sender: webrender_api::RenderApiSender,
- webrender_document: webrender_api::DocumentId,
- layout_threads: usize,
- paint_time_metrics: PaintTimeMetrics) {
- thread::Builder::new().name(format!("LayoutThread {:?}", id)).spawn(move || {
- thread_state::initialize(ThreadState::LAYOUT);
-
- // In order to get accurate crash reports, we install the top-level bc id.
- TopLevelBrowsingContextId::install(top_level_browsing_context_id);
-
- { // Ensures layout thread is destroyed before we send shutdown message
- let sender = chan.0;
- let layout = LayoutThread::new(id,
- top_level_browsing_context_id,
- url,
- is_iframe,
- chan.1,
- pipeline_port,
- constellation_chan,
- script_chan,
- image_cache.clone(),
- font_cache_thread,
- time_profiler_chan,
- mem_profiler_chan.clone(),
- webrender_api_sender,
- webrender_document,
- layout_threads,
- paint_time_metrics);
-
- let reporter_name = format!("layout-reporter-{}", id);
- mem_profiler_chan.run_with_memory_reporting(|| {
- layout.start();
- }, reporter_name, sender, Msg::CollectReports);
- }
- if let Some(content_process_shutdown_chan) = content_process_shutdown_chan {
- let _ = content_process_shutdown_chan.send(());
- }
- }).expect("Thread spawning failed");
+ fn create(
+ id: PipelineId,
+ top_level_browsing_context_id: TopLevelBrowsingContextId,
+ url: ServoUrl,
+ is_iframe: bool,
+ chan: (Sender<Msg>, Receiver<Msg>),
+ pipeline_port: IpcReceiver<LayoutControlMsg>,
+ constellation_chan: IpcSender<ConstellationMsg>,
+ script_chan: IpcSender<ConstellationControlMsg>,
+ image_cache: Arc<ImageCache>,
+ font_cache_thread: FontCacheThread,
+ time_profiler_chan: time::ProfilerChan,
+ mem_profiler_chan: mem::ProfilerChan,
+ content_process_shutdown_chan: Option<IpcSender<()>>,
+ webrender_api_sender: webrender_api::RenderApiSender,
+ webrender_document: webrender_api::DocumentId,
+ layout_threads: usize,
+ paint_time_metrics: PaintTimeMetrics,
+ ) {
+ thread::Builder::new()
+ .name(format!("LayoutThread {:?}", id))
+ .spawn(move || {
+ thread_state::initialize(ThreadState::LAYOUT);
+
+ // In order to get accurate crash reports, we install the top-level bc id.
+ TopLevelBrowsingContextId::install(top_level_browsing_context_id);
+
+ {
+ // Ensures layout thread is destroyed before we send shutdown message
+ let sender = chan.0;
+ let layout = LayoutThread::new(
+ id,
+ top_level_browsing_context_id,
+ url,
+ is_iframe,
+ chan.1,
+ pipeline_port,
+ constellation_chan,
+ script_chan,
+ image_cache.clone(),
+ font_cache_thread,
+ time_profiler_chan,
+ mem_profiler_chan.clone(),
+ webrender_api_sender,
+ webrender_document,
+ layout_threads,
+ paint_time_metrics,
+ );
+
+ let reporter_name = format!("layout-reporter-{}", id);
+ mem_profiler_chan.run_with_memory_reporting(
+ || {
+ layout.start();
+ },
+ reporter_name,
+ sender,
+ Msg::CollectReports,
+ );
+ }
+ if let Some(content_process_shutdown_chan) = content_process_shutdown_chan {
+ let _ = content_process_shutdown_chan.send(());
+ }
+ }).expect("Thread spawning failed");
}
}
@@ -357,11 +368,10 @@ impl ScriptReflowResult {
impl Drop for ScriptReflowResult {
fn drop(&mut self) {
- self.script_reflow.script_join_chan.send(
- self.result
- .borrow_mut()
- .take()
- .unwrap()).unwrap();
+ self.script_reflow
+ .script_join_chan
+ .send(self.result.borrow_mut().take().unwrap())
+ .unwrap();
}
}
@@ -415,20 +425,24 @@ impl<'a, 'b: 'a> RwData<'a, 'b> {
}
}
-fn add_font_face_rules(stylesheet: &Stylesheet,
- guard: &SharedRwLockReadGuard,
- device: &Device,
- font_cache_thread: &FontCacheThread,
- font_cache_sender: &IpcSender<()>,
- outstanding_web_fonts_counter: &Arc<AtomicUsize>) {
+fn add_font_face_rules(
+ stylesheet: &Stylesheet,
+ guard: &SharedRwLockReadGuard,
+ device: &Device,
+ font_cache_thread: &FontCacheThread,
+ font_cache_sender: &IpcSender<()>,
+ outstanding_web_fonts_counter: &Arc<AtomicUsize>,
+) {
if opts::get().load_webfonts_synchronously {
let (sender, receiver) = ipc::channel().unwrap();
stylesheet.effective_font_face_rules(&device, guard, |rule| {
if let Some(font_face) = rule.font_face() {
let effective_sources = font_face.effective_sources();
- font_cache_thread.add_web_font(font_face.family().clone(),
- effective_sources,
- sender.clone());
+ font_cache_thread.add_web_font(
+ font_face.family().clone(),
+ effective_sources,
+ sender.clone(),
+ );
receiver.recv().unwrap();
}
})
@@ -437,9 +451,11 @@ fn add_font_face_rules(stylesheet: &Stylesheet,
if let Some(font_face) = rule.font_face() {
let effective_sources = font_face.effective_sources();
outstanding_web_fonts_counter.fetch_add(1, Ordering::SeqCst);
- font_cache_thread.add_web_font(font_face.family().clone(),
- effective_sources,
- (*font_cache_sender).clone());
+ font_cache_thread.add_web_font(
+ font_face.family().clone(),
+ effective_sources,
+ (*font_cache_sender).clone(),
+ );
}
})
}
@@ -447,34 +463,36 @@ fn add_font_face_rules(stylesheet: &Stylesheet,
impl LayoutThread {
/// Creates a new `LayoutThread` structure.
- fn new(id: PipelineId,
- top_level_browsing_context_id: TopLevelBrowsingContextId,
- url: ServoUrl,
- is_iframe: bool,
- port: Receiver<Msg>,
- pipeline_port: IpcReceiver<LayoutControlMsg>,
- constellation_chan: IpcSender<ConstellationMsg>,
- script_chan: IpcSender<ConstellationControlMsg>,
- image_cache: Arc<ImageCache>,
- font_cache_thread: FontCacheThread,
- time_profiler_chan: time::ProfilerChan,
- mem_profiler_chan: mem::ProfilerChan,
- webrender_api_sender: webrender_api::RenderApiSender,
- webrender_document: webrender_api::DocumentId,
- layout_threads: usize,
- paint_time_metrics: PaintTimeMetrics)
- -> LayoutThread {
+ fn new(
+ id: PipelineId,
+ top_level_browsing_context_id: TopLevelBrowsingContextId,
+ url: ServoUrl,
+ is_iframe: bool,
+ port: Receiver<Msg>,
+ pipeline_port: IpcReceiver<LayoutControlMsg>,
+ constellation_chan: IpcSender<ConstellationMsg>,
+ script_chan: IpcSender<ConstellationControlMsg>,
+ image_cache: Arc<ImageCache>,
+ font_cache_thread: FontCacheThread,
+ time_profiler_chan: time::ProfilerChan,
+ mem_profiler_chan: mem::ProfilerChan,
+ webrender_api_sender: webrender_api::RenderApiSender,
+ webrender_document: webrender_api::DocumentId,
+ layout_threads: usize,
+ paint_time_metrics: PaintTimeMetrics,
+ ) -> LayoutThread {
// The device pixel ratio is incorrect (it does not have the hidpi value),
// but it will be set correctly when the initial reflow takes place.
let device = Device::new(
MediaType::screen(),
opts::get().initial_window_size.to_f32() * TypedScale::new(1.0),
- TypedScale::new(opts::get().device_pixels_per_px.unwrap_or(1.0)));
+ TypedScale::new(opts::get().device_pixels_per_px.unwrap_or(1.0)),
+ );
- let workers =
- rayon::ThreadPoolBuilder::new().num_threads(layout_threads)
- .start_handler(|_| thread_state::initialize_layout_worker_thread())
- .build();
+ let workers = rayon::ThreadPoolBuilder::new()
+ .num_threads(layout_threads)
+ .start_handler(|_| thread_state::initialize_layout_worker_thread())
+ .build();
let parallel_traversal = if layout_threads > 1 {
Some(workers.expect("ThreadPool creation failed"))
} else {
@@ -493,7 +511,6 @@ impl LayoutThread {
let font_cache_receiver =
ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_font_cache_receiver);
-
LayoutThread {
id: id,
top_level_browsing_context_id: top_level_browsing_context_id,
@@ -526,33 +543,33 @@ impl LayoutThread {
webrender_api: webrender_api_sender.create_api(),
webrender_document,
stylist: Stylist::new(device, QuirksMode::NoQuirks),
- rw_data: Arc::new(Mutex::new(
- LayoutThreadData {
- constellation_chan: constellation_chan,
- display_list: None,
- indexable_text: IndexableText::default(),
- content_box_response: None,
- content_boxes_response: Vec::new(),
- client_rect_response: Rect::zero(),
- scroll_id_response: None,
- scroll_area_response: Rect::zero(),
- resolved_style_response: String::new(),
- offset_parent_response: OffsetParentResponse::empty(),
- style_response: StyleResponse(None),
- scroll_offsets: HashMap::new(),
- text_index_response: TextIndexResponse(None),
- nodes_from_point_response: vec![],
- element_inner_text_response: String::new(),
- })),
- webrender_image_cache:
- Arc::new(RwLock::new(FnvHashMap::default())),
- timer:
- if PREFS.get("layout.animations.test.enabled")
- .as_boolean().unwrap_or(false) {
- Timer::test_mode()
- } else {
- Timer::new()
- },
+ rw_data: Arc::new(Mutex::new(LayoutThreadData {
+ constellation_chan: constellation_chan,
+ display_list: None,
+ indexable_text: IndexableText::default(),
+ content_box_response: None,
+ content_boxes_response: Vec::new(),
+ client_rect_response: Rect::zero(),
+ scroll_id_response: None,
+ scroll_area_response: Rect::zero(),
+ resolved_style_response: String::new(),
+ offset_parent_response: OffsetParentResponse::empty(),
+ style_response: StyleResponse(None),
+ scroll_offsets: HashMap::new(),
+ text_index_response: TextIndexResponse(None),
+ nodes_from_point_response: vec![],
+ element_inner_text_response: String::new(),
+ })),
+ webrender_image_cache: Arc::new(RwLock::new(FnvHashMap::default())),
+ timer: if PREFS
+ .get("layout.animations.test.enabled")
+ .as_boolean()
+ .unwrap_or(false)
+ {
+ Timer::test_mode()
+ } else {
+ Timer::new()
+ },
layout_threads: layout_threads,
paint_time_metrics: paint_time_metrics,
layout_query_waiting_time: Histogram::new(),
@@ -573,11 +590,12 @@ impl LayoutThread {
}
// Create a layout context for use in building display lists, hit testing, &c.
- fn build_layout_context<'a>(&'a self,
- guards: StylesheetGuards<'a>,
- script_initiated_layout: bool,
- snapshot_map: &'a SnapshotMap)
- -> LayoutContext<'a> {
+ fn build_layout_context<'a>(
+ &'a self,
+ guards: StylesheetGuards<'a>,
+ script_initiated_layout: bool,
+ snapshot_map: &'a SnapshotMap,
+ ) -> LayoutContext<'a> {
let thread_local_style_context_creation_data =
ThreadLocalStyleContextCreationInfo::new(self.new_animations_sender.clone());
@@ -599,8 +617,16 @@ impl LayoutThread {
image_cache: self.image_cache.clone(),
font_cache_thread: Mutex::new(self.font_cache_thread.clone()),
webrender_image_cache: self.webrender_image_cache.clone(),
- pending_images: if script_initiated_layout { Some(Mutex::new(vec![])) } else { None },
- newly_transitioning_nodes: if script_initiated_layout { Some(Mutex::new(vec![])) } else { None },
+ pending_images: if script_initiated_layout {
+ Some(Mutex::new(vec![]))
+ } else {
+ None
+ },
+ newly_transitioning_nodes: if script_initiated_layout {
+ Some(Mutex::new(vec![]))
+ } else {
+ None
+ },
registered_painters: &self.registered_painters,
}
}
@@ -632,20 +658,19 @@ impl LayoutThread {
};
match request {
- Request::FromPipeline(LayoutControlMsg::SetScrollStates(new_scroll_states)) => {
- self.handle_request_helper(Msg::SetScrollStates(new_scroll_states),
- possibly_locked_rw_data)
- },
+ Request::FromPipeline(LayoutControlMsg::SetScrollStates(new_scroll_states)) => self
+ .handle_request_helper(
+ Msg::SetScrollStates(new_scroll_states),
+ possibly_locked_rw_data,
+ ),
Request::FromPipeline(LayoutControlMsg::TickAnimations) => {
self.handle_request_helper(Msg::TickAnimations, possibly_locked_rw_data)
},
Request::FromPipeline(LayoutControlMsg::GetCurrentEpoch(sender)) => {
self.handle_request_helper(Msg::GetCurrentEpoch(sender), possibly_locked_rw_data)
},
- Request::FromPipeline(LayoutControlMsg::GetWebFontLoadState(sender)) => {
- self.handle_request_helper(Msg::GetWebFontLoadState(sender),
- possibly_locked_rw_data)
- },
+ Request::FromPipeline(LayoutControlMsg::GetWebFontLoadState(sender)) => self
+ .handle_request_helper(Msg::GetWebFontLoadState(sender), possibly_locked_rw_data),
Request::FromPipeline(LayoutControlMsg::ExitNow) => {
self.handle_request_helper(Msg::ExitNow, possibly_locked_rw_data)
},
@@ -653,14 +678,14 @@ impl LayoutThread {
self.paint_time_metrics.maybe_set_metric(epoch, paint_time);
true
},
- Request::FromScript(msg) => {
- self.handle_request_helper(msg, possibly_locked_rw_data)
- },
+ Request::FromScript(msg) => self.handle_request_helper(msg, possibly_locked_rw_data),
Request::FromFontCache => {
let _rw_data = possibly_locked_rw_data.lock();
self.outstanding_web_fonts.fetch_sub(1, Ordering::SeqCst);
font_context::invalidate_font_caches();
- self.script_chan.send(ConstellationControlMsg::WebFontLoaded(self.id)).unwrap();
+ self.script_chan
+ .send(ConstellationControlMsg::WebFontLoaded(self.id))
+ .unwrap();
true
},
}
@@ -678,63 +703,59 @@ impl LayoutThread {
self.handle_add_stylesheet(&stylesheet, &guard);
match before_stylesheet {
- Some(insertion_point) => {
- self.stylist.insert_stylesheet_before(
- DocumentStyleSheet(stylesheet.clone()),
- DocumentStyleSheet(insertion_point),
- &guard,
- )
- }
- None => {
- self.stylist.append_stylesheet(
- DocumentStyleSheet(stylesheet.clone()),
- &guard,
- )
- }
+ Some(insertion_point) => self.stylist.insert_stylesheet_before(
+ DocumentStyleSheet(stylesheet.clone()),
+ DocumentStyleSheet(insertion_point),
+ &guard,
+ ),
+ None => self
+ .stylist
+ .append_stylesheet(DocumentStyleSheet(stylesheet.clone()), &guard),
}
- }
+ },
Msg::RemoveStylesheet(stylesheet) => {
let guard = stylesheet.shared_lock.read();
- self.stylist.remove_stylesheet(
- DocumentStyleSheet(stylesheet.clone()),
- &guard,
- );
- }
+ self.stylist
+ .remove_stylesheet(DocumentStyleSheet(stylesheet.clone()), &guard);
+ },
Msg::SetQuirksMode(mode) => self.handle_set_quirks_mode(mode),
Msg::GetRPC(response_chan) => {
- response_chan.send(
- Box::new(LayoutRPCImpl(self.rw_data.clone())) as Box<LayoutRPC + Send>
- ).unwrap();
+ response_chan
+ .send(Box::new(LayoutRPCImpl(self.rw_data.clone())) as Box<LayoutRPC + Send>)
+ .unwrap();
},
Msg::Reflow(data) => {
let mut data = ScriptReflowResult::new(data);
- profile(time::ProfilerCategory::LayoutPerform,
- self.profiler_metadata(),
- self.time_profiler_chan.clone(),
- || self.handle_reflow(&mut data, possibly_locked_rw_data));
+ profile(
+ time::ProfilerCategory::LayoutPerform,
+ self.profiler_metadata(),
+ self.time_profiler_chan.clone(),
+ || self.handle_reflow(&mut data, possibly_locked_rw_data),
+ );
},
Msg::TickAnimations => self.tick_all_animations(possibly_locked_rw_data),
Msg::SetScrollStates(new_scroll_states) => {
self.set_scroll_states(new_scroll_states, possibly_locked_rw_data);
- }
+ },
Msg::UpdateScrollStateFromScript(state) => {
let mut rw_data = possibly_locked_rw_data.lock();
- rw_data.scroll_offsets.insert(state.scroll_id, state.scroll_offset);
+ rw_data
+ .scroll_offsets
+ .insert(state.scroll_id, state.scroll_offset);
let point = Point2D::new(-state.scroll_offset.x, -state.scroll_offset.y);
let mut txn = webrender_api::Transaction::new();
txn.scroll_node_with_id(
webrender_api::LayoutPoint::from_untyped(&point),
state.scroll_id,
- webrender_api::ScrollClamping::ToContentBounds
+ webrender_api::ScrollClamping::ToContentBounds,
);
- self.webrender_api.send_transaction(self.webrender_document, txn);
- }
- Msg::ReapStyleAndLayoutData(dead_data) => {
- unsafe {
- drop_style_and_layout_data(dead_data)
- }
- }
+ self.webrender_api
+ .send_transaction(self.webrender_document, txn);
+ },
+ Msg::ReapStyleAndLayoutData(dead_data) => unsafe {
+ drop_style_and_layout_data(dead_data)
+ },
Msg::CollectReports(reports_chan) => {
self.collect_reports(reports_chan, possibly_locked_rw_data);
},
@@ -744,26 +765,24 @@ impl LayoutThread {
},
Msg::AdvanceClockMs(how_many, do_tick) => {
self.handle_advance_clock_ms(how_many, possibly_locked_rw_data, do_tick);
- }
+ },
Msg::GetWebFontLoadState(sender) => {
let _rw_data = possibly_locked_rw_data.lock();
let outstanding_web_fonts = self.outstanding_web_fonts.load(Ordering::SeqCst);
sender.send(outstanding_web_fonts != 0).unwrap();
},
- Msg::CreateLayoutThread(info) => {
- self.create_layout_thread(info)
- }
+ Msg::CreateLayoutThread(info) => self.create_layout_thread(info),
Msg::SetFinalUrl(final_url) => {
self.url = final_url;
},
Msg::RegisterPaint(name, mut properties, painter) => {
debug!("Registering the painter");
- let properties = properties.drain(..)
+ let properties = properties
+ .drain(..)
.filter_map(|name| {
let id = PropertyId::parse_enabled_for_all_content(&*name).ok()?;
Some((name.clone(), id))
- })
- .filter(|&(_, ref id)| !id.is_shorthand())
+ }).filter(|&(_, ref id)| !id.is_shorthand())
.collect();
let registered_painter = RegisteredPainterImpl {
name: name.clone(),
@@ -774,12 +793,12 @@ impl LayoutThread {
},
Msg::PrepareToExit(response_chan) => {
self.prepare_to_exit(response_chan);
- return false
+ return false;
},
Msg::ExitNow => {
debug!("layout: ExitNow received");
self.exit_now();
- return false
+ return false;
},
Msg::SetNavigationStart(time) => {
self.paint_time_metrics.set_navigation_start(time);
@@ -789,9 +808,11 @@ impl LayoutThread {
true
}
- fn collect_reports<'a, 'b>(&self,
- reports_chan: ReportsChan,
- possibly_locked_rw_data: &mut RwData<'a, 'b>) {
+ fn collect_reports<'a, 'b>(
+ &self,
+ reports_chan: ReportsChan,
+ possibly_locked_rw_data: &mut RwData<'a, 'b>,
+ ) {
let mut reports = vec![];
// Servo uses vanilla jemalloc, which doesn't have a
// malloc_enclosing_size_of function.
@@ -824,23 +845,25 @@ impl LayoutThread {
}
fn create_layout_thread(&self, info: NewLayoutThreadInfo) {
- LayoutThread::create(info.id,
- self.top_level_browsing_context_id,
- info.url.clone(),
- info.is_parent,
- info.layout_pair,
- info.pipeline_port,
- info.constellation_chan,
- info.script_chan.clone(),
- info.image_cache.clone(),
- self.font_cache_thread.clone(),
- self.time_profiler_chan.clone(),
- self.mem_profiler_chan.clone(),
- info.content_process_shutdown_chan,
- self.webrender_api.clone_sender(),
- self.webrender_document,
- info.layout_threads,
- info.paint_time_metrics);
+ LayoutThread::create(
+ info.id,
+ self.top_level_browsing_context_id,
+ info.url.clone(),
+ info.is_parent,
+ info.layout_pair,
+ info.pipeline_port,
+ info.constellation_chan,
+ info.script_chan.clone(),
+ info.image_cache.clone(),
+ self.font_cache_thread.clone(),
+ self.time_profiler_chan.clone(),
+ self.mem_profiler_chan.clone(),
+ info.content_process_shutdown_chan,
+ self.webrender_api.clone_sender(),
+ self.webrender_document,
+ info.layout_threads,
+ info.paint_time_metrics,
+ );
}
/// Enters a quiescent state in which no new messages will be processed until an `ExitNow` is
@@ -849,22 +872,18 @@ impl LayoutThread {
response_chan.send(()).unwrap();
loop {
match self.port.recv().unwrap() {
- Msg::ReapStyleAndLayoutData(dead_data) => {
- unsafe {
- drop_style_and_layout_data(dead_data)
- }
- }
+ Msg::ReapStyleAndLayoutData(dead_data) => unsafe {
+ drop_style_and_layout_data(dead_data)
+ },
Msg::ExitNow => {
debug!("layout thread is exiting...");
self.exit_now();
- break
- }
+ break;
+ },
Msg::CollectReports(_) => {
// Just ignore these messages at this point.
- }
- _ => {
- panic!("layout: unexpected message received after `PrepareToExitMsg`")
- }
+ },
+ _ => panic!("layout: unexpected message received after `PrepareToExitMsg`"),
}
}
}
@@ -879,39 +898,38 @@ impl LayoutThread {
let waiting_time_max = self.layout_query_waiting_time.maximum().unwrap_or(0);
let waiting_time_mean = self.layout_query_waiting_time.mean().unwrap_or(0);
let waiting_time_stddev = self.layout_query_waiting_time.stddev().unwrap_or(0);
- debug!("layout: query waiting time: min: {}, max: {}, mean: {}, standard_deviation: {}",
- waiting_time_min,
- waiting_time_max,
- waiting_time_mean,
- waiting_time_stddev);
+ debug!(
+ "layout: query waiting time: min: {}, max: {}, mean: {}, standard_deviation: {}",
+ waiting_time_min, waiting_time_max, waiting_time_mean, waiting_time_stddev
+ );
self.root_flow.borrow_mut().take();
// Drop the rayon threadpool if present.
let _ = self.parallel_traversal.take();
}
- fn handle_add_stylesheet(
- &self,
- stylesheet: &Stylesheet,
- guard: &SharedRwLockReadGuard,
- ) {
+ fn handle_add_stylesheet(&self, stylesheet: &Stylesheet, guard: &SharedRwLockReadGuard) {
// Find all font-face rules and notify the font cache of them.
// GWTODO: Need to handle unloading web fonts.
if stylesheet.is_effective_for_device(self.stylist.device(), &guard) {
- add_font_face_rules(&*stylesheet,
- &guard,
- self.stylist.device(),
- &self.font_cache_thread,
- &self.font_cache_sender,
- &self.outstanding_web_fonts);
+ add_font_face_rules(
+ &*stylesheet,
+ &guard,
+ self.stylist.device(),
+ &self.font_cache_thread,
+ &self.font_cache_sender,
+ &self.outstanding_web_fonts,
+ );
}
}
/// Advances the animation clock of the document.
- fn handle_advance_clock_ms<'a, 'b>(&mut self,
- how_many_ms: i32,
- possibly_locked_rw_data: &mut RwData<'a, 'b>,
- tick_animations: bool) {
+ fn handle_advance_clock_ms<'a, 'b>(
+ &mut self,
+ how_many_ms: i32,
+ possibly_locked_rw_data: &mut RwData<'a, 'b>,
+ tick_animations: bool,
+ ) {
self.timer.increment(how_many_ms as f64 / 1000.0);
if tick_animations {
self.tick_all_animations(possibly_locked_rw_data);
@@ -935,7 +953,7 @@ impl LayoutThread {
// Set Root as CB for any remaining absolute descendants.
flow.set_absolute_descendants(abs_descendants);
flow
- }
+ },
_ => return None,
};
@@ -949,8 +967,7 @@ impl LayoutThread {
/// This corresponds to `Reflow()` in Gecko and `layout()` in WebKit/Blink and should be
/// benchmarked against those two. It is marked `#[inline(never)]` to aid profiling.
#[inline(never)]
- fn solve_constraints(layout_root: &mut Flow,
- layout_context: &LayoutContext) {
+ fn solve_constraints(layout_root: &mut Flow, layout_context: &LayoutContext) {
let _scope = layout_debug_scope!("solve_constraints");
sequential::reflow(layout_root, layout_context, RelayoutMode::Incremental);
}
@@ -960,139 +977,169 @@ impl LayoutThread {
/// This corresponds to `Reflow()` in Gecko and `layout()` in WebKit/Blink and should be
/// benchmarked against those two. It is marked `#[inline(never)]` to aid profiling.
#[inline(never)]
- fn solve_constraints_parallel(traversal: &rayon::ThreadPool,
- layout_root: &mut Flow,
- profiler_metadata: Option<TimerMetadata>,
- time_profiler_chan: time::ProfilerChan,
- layout_context: &LayoutContext) {
+ fn solve_constraints_parallel(
+ traversal: &rayon::ThreadPool,
+ layout_root: &mut Flow,
+ profiler_metadata: Option<TimerMetadata>,
+ time_profiler_chan: time::ProfilerChan,
+ layout_context: &LayoutContext,
+ ) {
let _scope = layout_debug_scope!("solve_constraints_parallel");
// NOTE: this currently computes borders, so any pruning should separate that
// operation out.
- parallel::reflow(layout_root,
- profiler_metadata,
- time_profiler_chan,
- layout_context,
- traversal);
+ parallel::reflow(
+ layout_root,
+ profiler_metadata,
+ time_profiler_chan,
+ layout_context,
+ traversal,
+ );
}
/// Computes the stacking-relative positions of all flows and, if the painting is dirty and the
/// reflow type need it, builds the display list.
- fn compute_abs_pos_and_build_display_list(&self,
- data: &Reflow,
- reflow_goal: &ReflowGoal,
- document: Option<&ServoLayoutDocument>,
- layout_root: &mut Flow,
- layout_context: &mut LayoutContext,
- rw_data: &mut LayoutThreadData) {
+ fn compute_abs_pos_and_build_display_list(
+ &self,
+ data: &Reflow,
+ reflow_goal: &ReflowGoal,
+ document: Option<&ServoLayoutDocument>,
+ layout_root: &mut Flow,
+ layout_context: &mut LayoutContext,
+ rw_data: &mut LayoutThreadData,
+ ) {
let writing_mode = layout_root.base().writing_mode;
let (metadata, sender) = (self.profiler_metadata(), self.time_profiler_chan.clone());
- profile(time::ProfilerCategory::LayoutDispListBuild,
- metadata.clone(),
- sender.clone(),
- || {
- layout_root.mut_base().stacking_relative_position =
- LogicalPoint::zero(writing_mode).to_physical(writing_mode,
- self.viewport_size).to_vector();
-
- layout_root.mut_base().clip = data.page_clip_rect;
-
- let traversal = ComputeStackingRelativePositions { layout_context: layout_context };
- traversal.traverse(layout_root);
-
- if layout_root.base().restyle_damage.contains(ServoRestyleDamage::REPAINT) ||
- rw_data.display_list.is_none() {
- if reflow_goal.needs_display_list() {
- let mut build_state =
- sequential::build_display_list_for_subtree(layout_root, layout_context);
-
- debug!("Done building display list.");
-
- let root_size = {
- let root_flow = layout_root.base();
- if self.stylist.viewport_constraints().is_some() {
- root_flow.position.size.to_physical(root_flow.writing_mode)
- } else {
- root_flow.overflow.scroll.size
+ profile(
+ time::ProfilerCategory::LayoutDispListBuild,
+ metadata.clone(),
+ sender.clone(),
+ || {
+ layout_root.mut_base().stacking_relative_position =
+ LogicalPoint::zero(writing_mode)
+ .to_physical(writing_mode, self.viewport_size)
+ .to_vector();
+
+ layout_root.mut_base().clip = data.page_clip_rect;
+
+ let traversal = ComputeStackingRelativePositions {
+ layout_context: layout_context,
+ };
+ traversal.traverse(layout_root);
+
+ if layout_root
+ .base()
+ .restyle_damage
+ .contains(ServoRestyleDamage::REPAINT) ||
+ rw_data.display_list.is_none()
+ {
+ if reflow_goal.needs_display_list() {
+ let mut build_state =
+ sequential::build_display_list_for_subtree(layout_root, layout_context);
+
+ debug!("Done building display list.");
+
+ let root_size = {
+ let root_flow = layout_root.base();
+ if self.stylist.viewport_constraints().is_some() {
+ root_flow.position.size.to_physical(root_flow.writing_mode)
+ } else {
+ root_flow.overflow.scroll.size
+ }
+ };
+
+ let origin = Rect::new(Point2D::new(Au(0), Au(0)), root_size).to_layout();
+ build_state.root_stacking_context.bounds = origin;
+ build_state.root_stacking_context.overflow = origin;
+
+ if !build_state.iframe_sizes.is_empty() {
+ // build_state.iframe_sizes is only used here, so its okay to replace
+ // it with an empty vector
+ let iframe_sizes =
+ std::mem::replace(&mut build_state.iframe_sizes, vec![]);
+ let msg = ConstellationMsg::IFrameSizes(iframe_sizes);
+ if let Err(e) = self.constellation_chan.send(msg) {
+ warn!("Layout resize to constellation failed ({}).", e);
+ }
}
- };
- let origin = Rect::new(Point2D::new(Au(0), Au(0)), root_size).to_layout();
- build_state.root_stacking_context.bounds = origin;
- build_state.root_stacking_context.overflow = origin;
-
- if !build_state.iframe_sizes.is_empty() {
- // build_state.iframe_sizes is only used here, so its okay to replace
- // it with an empty vector
- let iframe_sizes = std::mem::replace(&mut build_state.iframe_sizes, vec![]);
- let msg = ConstellationMsg::IFrameSizes(iframe_sizes);
- if let Err(e) = self.constellation_chan.send(msg) {
- warn!("Layout resize to constellation failed ({}).", e);
- }
+ rw_data.indexable_text = std::mem::replace(
+ &mut build_state.indexable_text,
+ IndexableText::default(),
+ );
+ rw_data.display_list = Some(Arc::new(build_state.to_display_list()));
}
-
- rw_data.indexable_text = std::mem::replace(
- &mut build_state.indexable_text,
- IndexableText::default());
- rw_data.display_list = Some(Arc::new(build_state.to_display_list()));
}
- }
- if !reflow_goal.needs_display() {
- // Defer the paint step until the next ForDisplay.
- //
- // We need to tell the document about this so it doesn't
- // incorrectly suppress reflows. See #13131.
- document.expect("No document in a non-display reflow?").needs_paint_from_layout();
- return;
- }
- if let Some(document) = document {
- document.will_paint();
- }
- let display_list = (*rw_data.display_list.as_ref().unwrap()).clone();
+ if !reflow_goal.needs_display() {
+ // Defer the paint step until the next ForDisplay.
+ //
+ // We need to tell the document about this so it doesn't
+ // incorrectly suppress reflows. See #13131.
+ document
+ .expect("No document in a non-display reflow?")
+ .needs_paint_from_layout();
+ return;
+ }
+ if let Some(document) = document {
+ document.will_paint();
+ }
+ let display_list = (*rw_data.display_list.as_ref().unwrap()).clone();
- if opts::get().dump_display_list {
- display_list.print();
- }
- if opts::get().dump_display_list_json {
- println!("{}", serde_json::to_string_pretty(&display_list).unwrap());
- }
+ if opts::get().dump_display_list {
+ display_list.print();
+ }
+ if opts::get().dump_display_list_json {
+ println!("{}", serde_json::to_string_pretty(&display_list).unwrap());
+ }
- debug!("Layout done!");
+ debug!("Layout done!");
- // TODO: Avoid the temporary conversion and build webrender sc/dl directly!
- let builder = rw_data.display_list.as_ref().unwrap().convert_to_webrender(self.id);
+ // TODO: Avoid the temporary conversion and build webrender sc/dl directly!
+ let builder = rw_data
+ .display_list
+ .as_ref()
+ .unwrap()
+ .convert_to_webrender(self.id);
- let viewport_size = Size2D::new(self.viewport_size.width.to_f32_px(),
- self.viewport_size.height.to_f32_px());
+ let viewport_size = Size2D::new(
+ self.viewport_size.width.to_f32_px(),
+ self.viewport_size.height.to_f32_px(),
+ );
- let mut epoch = self.epoch.get();
- epoch.next();
- self.epoch.set(epoch);
+ let mut epoch = self.epoch.get();
+ epoch.next();
+ self.epoch.set(epoch);
- let viewport_size = webrender_api::LayoutSize::from_untyped(&viewport_size);
+ let viewport_size = webrender_api::LayoutSize::from_untyped(&viewport_size);
- // Observe notifications about rendered frames if needed right before
- // sending the display list to WebRender in order to set time related
- // Progressive Web Metrics.
- self.paint_time_metrics.maybe_observe_paint_time(self, epoch, &*display_list);
+ // Observe notifications about rendered frames if needed right before
+ // sending the display list to WebRender in order to set time related
+ // Progressive Web Metrics.
+ self.paint_time_metrics
+ .maybe_observe_paint_time(self, epoch, &*display_list);
- let mut txn = webrender_api::Transaction::new();
- txn.set_display_list(
- webrender_api::Epoch(epoch.0),
- Some(get_root_flow_background_color(layout_root)),
- viewport_size,
- builder.finalize(),
- true);
- txn.generate_frame();
- self.webrender_api.send_transaction(self.webrender_document, txn);
- });
+ let mut txn = webrender_api::Transaction::new();
+ txn.set_display_list(
+ webrender_api::Epoch(epoch.0),
+ Some(get_root_flow_background_color(layout_root)),
+ viewport_size,
+ builder.finalize(),
+ true,
+ );
+ txn.generate_frame();
+ self.webrender_api
+ .send_transaction(self.webrender_document, txn);
+ },
+ );
}
/// The high-level routine that performs layout threads.
- fn handle_reflow<'a, 'b>(&mut self,
- data: &mut ScriptReflowResult,
- possibly_locked_rw_data: &mut RwData<'a, 'b>) {
+ fn handle_reflow<'a, 'b>(
+ &mut self,
+ data: &mut ScriptReflowResult,
+ possibly_locked_rw_data: &mut RwData<'a, 'b>,
+ ) {
let document = unsafe { ServoLayoutNode::new(&data.document) };
let document = document.as_document().unwrap();
@@ -1108,7 +1155,9 @@ impl LayoutThread {
// Record the time that layout query has been waited.
let now = std_time::precise_time_ns();
if let ReflowGoal::LayoutQuery(_, timestamp) = data.reflow_goal {
- self.layout_query_waiting_time.increment(now - timestamp).expect("layout: wrong layout query timestamp");
+ self.layout_query_waiting_time
+ .increment(now - timestamp)
+ .expect("layout: wrong layout query timestamp");
};
let element = match document.root_element() {
@@ -1146,27 +1195,31 @@ impl LayoutThread {
},
&QueryMsg::TextIndexQuery(..) => {
rw_data.text_index_response = TextIndexResponse(None);
- }
+ },
&QueryMsg::ElementInnerTextQuery(_) => {
rw_data.element_inner_text_response = String::new();
},
},
- ReflowGoal::Full | ReflowGoal:: TickAnimations => {}
+ ReflowGoal::Full | ReflowGoal::TickAnimations => {},
}
return;
},
Some(x) => x,
};
- debug!("layout: processing reflow request for: {:?} ({}) (query={:?})",
- element, self.url, data.reflow_goal);
+ debug!(
+ "layout: processing reflow request for: {:?} ({}) (query={:?})",
+ element, self.url, data.reflow_goal
+ );
trace!("{:?}", ShowSubtree(element.as_node()));
let initial_viewport = data.window_size.initial_viewport;
let device_pixel_ratio = data.window_size.device_pixel_ratio;
let old_viewport_size = self.viewport_size;
- let current_screen_size = Size2D::new(Au::from_f32_px(initial_viewport.width),
- Au::from_f32_px(initial_viewport.height));
+ let current_screen_size = Size2D::new(
+ Au::from_f32_px(initial_viewport.width),
+ Au::from_f32_px(initial_viewport.height),
+ );
// Calculate the actual viewport as per DEVICE-ADAPT § 6
// If the entire flow tree is invalid, then it will be reflowed anyhow.
@@ -1183,26 +1236,33 @@ impl LayoutThread {
let had_used_viewport_units = self.stylist.device().used_viewport_units();
let device = Device::new(MediaType::screen(), initial_viewport, device_pixel_ratio);
- let sheet_origins_affected_by_device_change =
- self.stylist.set_device(device, &guards);
+ let sheet_origins_affected_by_device_change = self.stylist.set_device(device, &guards);
- self.stylist.force_stylesheet_origins_dirty(sheet_origins_affected_by_device_change);
+ self.stylist
+ .force_stylesheet_origins_dirty(sheet_origins_affected_by_device_change);
self.viewport_size =
- self.stylist.viewport_constraints().map_or(current_screen_size, |constraints| {
- debug!("Viewport constraints: {:?}", constraints);
-
- // other rules are evaluated against the actual viewport
- Size2D::new(Au::from_f32_px(constraints.size.width),
- Au::from_f32_px(constraints.size.height))
- });
+ self.stylist
+ .viewport_constraints()
+ .map_or(current_screen_size, |constraints| {
+ debug!("Viewport constraints: {:?}", constraints);
+
+ // other rules are evaluated against the actual viewport
+ Size2D::new(
+ Au::from_f32_px(constraints.size.width),
+ Au::from_f32_px(constraints.size.height),
+ )
+ });
let viewport_size_changed = self.viewport_size != old_viewport_size;
if viewport_size_changed {
if let Some(constraints) = self.stylist.viewport_constraints() {
// let the constellation know about the viewport constraints
- rw_data.constellation_chan
- .send(ConstellationMsg::ViewportConstrained(self.id, constraints.clone()))
- .unwrap();
+ rw_data
+ .constellation_chan
+ .send(ConstellationMsg::ViewportConstrained(
+ self.id,
+ constraints.clone(),
+ )).unwrap();
}
if had_used_viewport_units {
if let Some(mut data) = element.mutate_data() {
@@ -1215,7 +1275,8 @@ impl LayoutThread {
if self.first_reflow.get() {
debug!("First reflow, rebuilding user and UA rules");
for stylesheet in &ua_stylesheets.user_or_user_agent_stylesheets {
- self.stylist.append_stylesheet(stylesheet.clone(), &ua_or_user_guard);
+ self.stylist
+ .append_stylesheet(stylesheet.clone(), &ua_or_user_guard);
self.handle_add_stylesheet(&stylesheet.0, &ua_or_user_guard);
}
@@ -1233,7 +1294,8 @@ impl LayoutThread {
if data.stylesheets_changed {
debug!("Doc sheets changed, flushing author sheets too");
- self.stylist.force_stylesheet_origins_dirty(Origin::Author.into());
+ self.stylist
+ .force_stylesheet_origins_dirty(Origin::Author.into());
}
}
@@ -1247,12 +1309,11 @@ impl LayoutThread {
debug!("Draining restyles: {}", restyles.len());
let mut map = SnapshotMap::new();
- let elements_with_snapshot: Vec<_> =
- restyles
- .iter()
- .filter(|r| r.1.snapshot.is_some())
- .map(|r| r.0)
- .collect();
+ let elements_with_snapshot: Vec<_> = restyles
+ .iter()
+ .filter(|r| r.1.snapshot.is_some())
+ .map(|r| r.0)
+ .collect();
for (el, restyle) in restyles {
// Propagate the descendant bit up the ancestors. Do this before
@@ -1269,7 +1330,7 @@ impl LayoutThread {
None => {
unsafe { el.unset_snapshot_flags() };
continue;
- }
+ },
};
if let Some(s) = restyle.snapshot {
@@ -1288,8 +1349,7 @@ impl LayoutThread {
self.stylist.flush(&guards, Some(element), Some(&map));
// Create a layout context for use throughout the following passes.
- let mut layout_context =
- self.build_layout_context(guards.clone(), true, &map);
+ let mut layout_context = self.build_layout_context(guards.clone(), true, &map);
let thread_pool = if self.parallel_flag {
self.parallel_traversal.as_ref()
@@ -1300,34 +1360,39 @@ impl LayoutThread {
let traversal = RecalcStyleAndConstructFlows::new(layout_context);
let token = {
let shared =
- <RecalcStyleAndConstructFlows as DomTraversal<ServoLayoutElement>>::shared_context(&traversal);
+ <RecalcStyleAndConstructFlows as DomTraversal<ServoLayoutElement>>::shared_context(
+ &traversal,
+ );
RecalcStyleAndConstructFlows::pre_traverse(element, shared)
};
if token.should_traverse() {
// Recalculate CSS styles and rebuild flows and fragments.
- profile(time::ProfilerCategory::LayoutStyleRecalc,
- self.profiler_metadata(),
- self.time_profiler_chan.clone(),
- || {
- // Perform CSS selector matching and flow construction.
- driver::traverse_dom::<ServoLayoutElement, RecalcStyleAndConstructFlows>(
- &traversal,
- token,
- thread_pool,
- );
- });
+ profile(
+ time::ProfilerCategory::LayoutStyleRecalc,
+ self.profiler_metadata(),
+ self.time_profiler_chan.clone(),
+ || {
+ // Perform CSS selector matching and flow construction.
+ driver::traverse_dom::<ServoLayoutElement, RecalcStyleAndConstructFlows>(
+ &traversal,
+ token,
+ thread_pool,
+ );
+ },
+ );
// TODO(pcwalton): Measure energy usage of text shaping, perhaps?
- let text_shaping_time =
- (font::get_and_reset_text_shaping_performance_counter() as u64) /
+ let text_shaping_time = (font::get_and_reset_text_shaping_performance_counter() as u64) /
(self.layout_threads as u64);
- time::send_profile_data(time::ProfilerCategory::LayoutTextShaping,
- self.profiler_metadata(),
- &self.time_profiler_chan,
- 0,
- text_shaping_time,
- 0,
- 0);
+ time::send_profile_data(
+ time::ProfilerCategory::LayoutTextShaping,
+ self.profiler_metadata(),
+ &self.time_profiler_chan,
+ 0,
+ text_shaping_time,
+ 0,
+ 0,
+ );
// Retrieve the (possibly rebuilt) root flow.
*self.root_flow.borrow_mut() = self.try_get_layout_root(element.as_node());
@@ -1344,34 +1409,46 @@ impl LayoutThread {
}
if opts::get().dump_rule_tree {
- layout_context.style_context.stylist.rule_tree().dump_stdout(&guards);
+ layout_context
+ .style_context
+ .stylist
+ .rule_tree()
+ .dump_stdout(&guards);
}
// GC the rule tree if some heuristics are met.
- unsafe { layout_context.style_context.stylist.rule_tree().maybe_gc(); }
+ unsafe {
+ layout_context.style_context.stylist.rule_tree().maybe_gc();
+ }
// Perform post-style recalculation layout passes.
if let Some(mut root_flow) = self.root_flow.borrow().clone() {
- self.perform_post_style_recalc_layout_passes(&mut root_flow,
- &data.reflow_info,
- &data.reflow_goal,
- Some(&document),
- &mut rw_data,
- &mut layout_context);
+ self.perform_post_style_recalc_layout_passes(
+ &mut root_flow,
+ &data.reflow_info,
+ &data.reflow_goal,
+ Some(&document),
+ &mut rw_data,
+ &mut layout_context,
+ );
}
self.first_reflow.set(false);
- self.respond_to_query_if_necessary(&data.reflow_goal,
- &mut *rw_data,
- &mut layout_context,
- data.result.borrow_mut().as_mut().unwrap());
+ self.respond_to_query_if_necessary(
+ &data.reflow_goal,
+ &mut *rw_data,
+ &mut layout_context,
+ data.result.borrow_mut().as_mut().unwrap(),
+ );
}
- fn respond_to_query_if_necessary(&self,
- reflow_goal: &ReflowGoal,
- rw_data: &mut LayoutThreadData,
- context: &mut LayoutContext,
- reflow_result: &mut ReflowComplete) {
+ fn respond_to_query_if_necessary(
+ &self,
+ reflow_goal: &ReflowGoal,
+ rw_data: &mut LayoutThreadData,
+ context: &mut LayoutContext,
+ reflow_result: &mut ReflowComplete,
+ ) {
let pending_images = match context.pending_images {
Some(ref pending) => std_mem::replace(&mut *pending.lock().unwrap(), vec![]),
None => vec![],
@@ -1404,10 +1481,12 @@ impl LayoutThread {
let opaque_node = node.opaque();
let point_in_node = Point2D::new(
Au::from_f32_px(point_in_node.x),
- Au::from_f32_px(point_in_node.y)
+ Au::from_f32_px(point_in_node.y),
);
rw_data.text_index_response = TextIndexResponse(
- rw_data.indexable_text.text_index(opaque_node, point_in_node)
+ rw_data
+ .indexable_text
+ .text_index(opaque_node, point_in_node),
);
},
&QueryMsg::NodeGeometryQuery(node) => {
@@ -1416,20 +1495,18 @@ impl LayoutThread {
},
&QueryMsg::NodeScrollGeometryQuery(node) => {
let node = unsafe { ServoLayoutNode::new(&node) };
- rw_data.scroll_area_response = process_node_scroll_area_request(node, root_flow);
+ rw_data.scroll_area_response =
+ process_node_scroll_area_request(node, root_flow);
},
&QueryMsg::NodeScrollIdQuery(node) => {
let node = unsafe { ServoLayoutNode::new(&node) };
- rw_data.scroll_id_response = Some(process_node_scroll_id_request(self.id, node));
+ rw_data.scroll_id_response =
+ Some(process_node_scroll_id_request(self.id, node));
},
&QueryMsg::ResolvedStyleQuery(node, ref pseudo, ref property) => {
let node = unsafe { ServoLayoutNode::new(&node) };
rw_data.resolved_style_response =
- process_resolved_style_request(context,
- node,
- pseudo,
- property,
- root_flow);
+ process_resolved_style_request(context, node, pseudo, property, root_flow);
},
&QueryMsg::OffsetParentQuery(node) => {
let node = unsafe { ServoLayoutNode::new(&node) };
@@ -1454,12 +1531,14 @@ impl LayoutThread {
self.webrender_document,
Some(self.id.to_webrender()),
client_point,
- flags
+ flags,
);
- rw_data.nodes_from_point_response = results.items.iter()
- .map(|item| UntrustedNodeAddress(item.tag.0 as *const c_void))
- .collect()
+ rw_data.nodes_from_point_response = results
+ .items
+ .iter()
+ .map(|item| UntrustedNodeAddress(item.tag.0 as *const c_void))
+ .collect()
},
&QueryMsg::ElementInnerTextQuery(node) => {
let node = unsafe { ServoLayoutNode::new(&node) };
@@ -1467,13 +1546,15 @@ impl LayoutThread {
process_element_inner_text_query(node, &rw_data.indexable_text);
},
},
- ReflowGoal::Full | ReflowGoal::TickAnimations => {}
+ ReflowGoal::Full | ReflowGoal::TickAnimations => {},
}
}
- fn set_scroll_states<'a, 'b>(&mut self,
- new_scroll_states: Vec<ScrollState>,
- possibly_locked_rw_data: &mut RwData<'a, 'b>) {
+ fn set_scroll_states<'a, 'b>(
+ &mut self,
+ new_scroll_states: Vec<ScrollState>,
+ possibly_locked_rw_data: &mut RwData<'a, 'b>,
+ ) {
let mut rw_data = possibly_locked_rw_data.lock();
let mut script_scroll_states = vec![];
let mut layout_scroll_states = HashMap::new();
@@ -1487,8 +1568,12 @@ impl LayoutThread {
script_scroll_states.push((UntrustedNodeAddress::from_id(node_id), offset))
}
}
- let _ = self.script_chan
- .send(ConstellationControlMsg::SetScrollState(self.id, script_scroll_states));
+ let _ = self
+ .script_chan
+ .send(ConstellationControlMsg::SetScrollState(
+ self.id,
+ script_scroll_states,
+ ));
rw_data.scroll_offsets = layout_scroll_states
}
@@ -1499,7 +1584,10 @@ impl LayoutThread {
fn tick_animations(&mut self, rw_data: &mut LayoutThreadData) {
if opts::get().relayout_event {
- println!("**** pipeline={}\tForDisplay\tSpecial\tAnimationTick", self.id);
+ println!(
+ "**** pipeline={}\tForDisplay\tSpecial\tAnimationTick",
+ self.id
+ );
}
if let Some(mut root_flow) = self.root_flow.borrow().clone() {
@@ -1517,50 +1605,53 @@ impl LayoutThread {
ua_or_user: &ua_or_user_guard,
};
let snapshots = SnapshotMap::new();
- let mut layout_context = self.build_layout_context(guards,
- false,
- &snapshots);
+ let mut layout_context = self.build_layout_context(guards, false, &snapshots);
{
// Perform an abbreviated style recalc that operates without access to the DOM.
let animations = self.running_animations.read();
- profile(time::ProfilerCategory::LayoutStyleRecalc,
- self.profiler_metadata(),
- self.time_profiler_chan.clone(),
- || {
- animation::recalc_style_for_animations::<ServoLayoutElement>(
- &layout_context,
- FlowRef::deref_mut(&mut root_flow),
- &animations,
- )
- });
+ profile(
+ time::ProfilerCategory::LayoutStyleRecalc,
+ self.profiler_metadata(),
+ self.time_profiler_chan.clone(),
+ || {
+ animation::recalc_style_for_animations::<ServoLayoutElement>(
+ &layout_context,
+ FlowRef::deref_mut(&mut root_flow),
+ &animations,
+ )
+ },
+ );
}
- self.perform_post_style_recalc_layout_passes(&mut root_flow,
- &reflow_info,
- &ReflowGoal::TickAnimations,
- None,
- &mut *rw_data,
- &mut layout_context);
+ self.perform_post_style_recalc_layout_passes(
+ &mut root_flow,
+ &reflow_info,
+ &ReflowGoal::TickAnimations,
+ None,
+ &mut *rw_data,
+ &mut layout_context,
+ );
assert!(layout_context.pending_images.is_none());
assert!(layout_context.newly_transitioning_nodes.is_none());
}
}
- fn perform_post_style_recalc_layout_passes(&self,
- root_flow: &mut FlowRef,
- data: &Reflow,
- reflow_goal: &ReflowGoal,
- document: Option<&ServoLayoutDocument>,
- rw_data: &mut LayoutThreadData,
- context: &mut LayoutContext) {
+ fn perform_post_style_recalc_layout_passes(
+ &self,
+ root_flow: &mut FlowRef,
+ data: &Reflow,
+ reflow_goal: &ReflowGoal,
+ document: Option<&ServoLayoutDocument>,
+ rw_data: &mut LayoutThreadData,
+ context: &mut LayoutContext,
+ ) {
{
let mut newly_transitioning_nodes = context
.newly_transitioning_nodes
.as_ref()
.map(|nodes| nodes.lock().unwrap());
- let newly_transitioning_nodes = newly_transitioning_nodes
- .as_mut()
- .map(|nodes| &mut **nodes);
+ let newly_transitioning_nodes =
+ newly_transitioning_nodes.as_mut().map(|nodes| &mut **nodes);
// Kick off animations if any were triggered, expire completed ones.
animation::update_animation_state::<ServoLayoutElement>(
&self.constellation_chan,
@@ -1574,89 +1665,113 @@ impl LayoutThread {
);
}
- profile(time::ProfilerCategory::LayoutRestyleDamagePropagation,
- self.profiler_metadata(),
- self.time_profiler_chan.clone(),
- || {
- // Call `compute_layout_damage` even in non-incremental mode, because it sets flags
- // that are needed in both incremental and non-incremental traversals.
- let damage = FlowRef::deref_mut(root_flow).compute_layout_damage();
-
- if opts::get().nonincremental_layout || damage.contains(SpecialRestyleDamage::REFLOW_ENTIRE_DOCUMENT) {
- FlowRef::deref_mut(root_flow).reflow_entire_document()
- }
- });
+ profile(
+ time::ProfilerCategory::LayoutRestyleDamagePropagation,
+ self.profiler_metadata(),
+ self.time_profiler_chan.clone(),
+ || {
+ // Call `compute_layout_damage` even in non-incremental mode, because it sets flags
+ // that are needed in both incremental and non-incremental traversals.
+ let damage = FlowRef::deref_mut(root_flow).compute_layout_damage();
+
+ if opts::get().nonincremental_layout ||
+ damage.contains(SpecialRestyleDamage::REFLOW_ENTIRE_DOCUMENT)
+ {
+ FlowRef::deref_mut(root_flow).reflow_entire_document()
+ }
+ },
+ );
if opts::get().trace_layout {
layout_debug::begin_trace(root_flow.clone());
}
// Resolve generated content.
- profile(time::ProfilerCategory::LayoutGeneratedContent,
- self.profiler_metadata(),
- self.time_profiler_chan.clone(),
- || sequential::resolve_generated_content(FlowRef::deref_mut(root_flow), &context));
+ profile(
+ time::ProfilerCategory::LayoutGeneratedContent,
+ self.profiler_metadata(),
+ self.time_profiler_chan.clone(),
+ || sequential::resolve_generated_content(FlowRef::deref_mut(root_flow), &context),
+ );
// Guess float placement.
- profile(time::ProfilerCategory::LayoutFloatPlacementSpeculation,
- self.profiler_metadata(),
- self.time_profiler_chan.clone(),
- || sequential::guess_float_placement(FlowRef::deref_mut(root_flow)));
+ profile(
+ time::ProfilerCategory::LayoutFloatPlacementSpeculation,
+ self.profiler_metadata(),
+ self.time_profiler_chan.clone(),
+ || sequential::guess_float_placement(FlowRef::deref_mut(root_flow)),
+ );
// Perform the primary layout passes over the flow tree to compute the locations of all
// the boxes.
- if root_flow.base().restyle_damage.intersects(ServoRestyleDamage::REFLOW |
- ServoRestyleDamage::REFLOW_OUT_OF_FLOW) {
- profile(time::ProfilerCategory::LayoutMain,
- self.profiler_metadata(),
- self.time_profiler_chan.clone(),
- || {
- let profiler_metadata = self.profiler_metadata();
-
- if let (true, Some(traversal)) = (self.parallel_flag, self.parallel_traversal.as_ref()) {
- // Parallel mode.
- LayoutThread::solve_constraints_parallel(traversal,
- FlowRef::deref_mut(root_flow),
- profiler_metadata,
- self.time_profiler_chan.clone(),
- &*context);
- } else {
- //Sequential mode
- LayoutThread::solve_constraints(FlowRef::deref_mut(root_flow), &context)
- }
- });
- }
-
- profile(time::ProfilerCategory::LayoutStoreOverflow,
+ if root_flow
+ .base()
+ .restyle_damage
+ .intersects(ServoRestyleDamage::REFLOW | ServoRestyleDamage::REFLOW_OUT_OF_FLOW)
+ {
+ profile(
+ time::ProfilerCategory::LayoutMain,
self.profiler_metadata(),
self.time_profiler_chan.clone(),
|| {
- sequential::store_overflow(context,
- FlowRef::deref_mut(root_flow) as &mut Flow);
- });
+ let profiler_metadata = self.profiler_metadata();
+
+ if let (true, Some(traversal)) =
+ (self.parallel_flag, self.parallel_traversal.as_ref())
+ {
+ // Parallel mode.
+ LayoutThread::solve_constraints_parallel(
+ traversal,
+ FlowRef::deref_mut(root_flow),
+ profiler_metadata,
+ self.time_profiler_chan.clone(),
+ &*context,
+ );
+ } else {
+ //Sequential mode
+ LayoutThread::solve_constraints(FlowRef::deref_mut(root_flow), &context)
+ }
+ },
+ );
+ }
+
+ profile(
+ time::ProfilerCategory::LayoutStoreOverflow,
+ self.profiler_metadata(),
+ self.time_profiler_chan.clone(),
+ || {
+ sequential::store_overflow(context, FlowRef::deref_mut(root_flow) as &mut Flow);
+ },
+ );
- self.perform_post_main_layout_passes(data,
- root_flow,
- reflow_goal,
- document,
- rw_data,
- context);
+ self.perform_post_main_layout_passes(
+ data,
+ root_flow,
+ reflow_goal,
+ document,
+ rw_data,
+ context,
+ );
}
- fn perform_post_main_layout_passes(&self,
- data: &Reflow,
- mut root_flow: &mut FlowRef,
- reflow_goal: &ReflowGoal,
- document: Option<&ServoLayoutDocument>,
- rw_data: &mut LayoutThreadData,
- layout_context: &mut LayoutContext) {
+ fn perform_post_main_layout_passes(
+ &self,
+ data: &Reflow,
+ mut root_flow: &mut FlowRef,
+ reflow_goal: &ReflowGoal,
+ document: Option<&ServoLayoutDocument>,
+ rw_data: &mut LayoutThreadData,
+ layout_context: &mut LayoutContext,
+ ) {
// Build the display list if necessary, and send it to the painter.
- self.compute_abs_pos_and_build_display_list(data,
- reflow_goal,
- document,
- FlowRef::deref_mut(&mut root_flow),
- &mut *layout_context,
- rw_data);
+ self.compute_abs_pos_and_build_display_list(
+ data,
+ reflow_goal,
+ document,
+ FlowRef::deref_mut(&mut root_flow),
+ &mut *layout_context,
+ rw_data,
+ );
if opts::get().trace_layout {
layout_debug::end_trace(self.generation.get());
@@ -1671,10 +1786,12 @@ impl LayoutThread {
fn reflow_all_nodes(flow: &mut Flow) {
debug!("reflowing all nodes!");
- flow.mut_base()
- .restyle_damage
- .insert(ServoRestyleDamage::REPAINT | ServoRestyleDamage::STORE_OVERFLOW |
- ServoRestyleDamage::REFLOW | ServoRestyleDamage::REPOSITION);
+ flow.mut_base().restyle_damage.insert(
+ ServoRestyleDamage::REPAINT |
+ ServoRestyleDamage::STORE_OVERFLOW |
+ ServoRestyleDamage::REFLOW |
+ ServoRestyleDamage::REPOSITION,
+ );
for child in flow.mut_base().child_iter_mut() {
LayoutThread::reflow_all_nodes(child);
@@ -1715,7 +1832,12 @@ impl ProfilerMetadataFactory for LayoutThread {
// color on an iframe element, while the iframe content itself has a default
// transparent background color is handled correctly.
fn get_root_flow_background_color(flow: &mut Flow) -> webrender_api::ColorF {
- let transparent = webrender_api::ColorF { r: 0.0, g: 0.0, b: 0.0, a: 0.0 };
+ let transparent = webrender_api::ColorF {
+ r: 0.0,
+ g: 0.0,
+ b: 0.0,
+ a: 0.0,
+ };
if !flow.is_block_like() {
return transparent;
}
@@ -1730,9 +1852,13 @@ fn get_root_flow_background_color(flow: &mut Flow) -> webrender_api::ColorF {
}
let kid_block_flow = kid.as_block();
- let color = kid_block_flow.fragment
- .style
- .resolve_color(kid_block_flow.fragment.style.get_background().background_color);
+ let color = kid_block_flow.fragment.style.resolve_color(
+ kid_block_flow
+ .fragment
+ .style
+ .get_background()
+ .background_color,
+ );
webrender_api::ColorF::new(
color.red_f32(),
color.green_f32(),
@@ -1765,17 +1891,26 @@ fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> {
// FIXME: presentational-hints.css should be at author origin with zero specificity.
// (Does it make a difference?)
let mut user_or_user_agent_stylesheets = vec![
- parse_ua_stylesheet(&shared_lock, "user-agent.css",
- &resources::read_bytes(Resource::UserAgentCSS))?,
- parse_ua_stylesheet(&shared_lock, "servo.css",
- &resources::read_bytes(Resource::ServoCSS))?,
- parse_ua_stylesheet(&shared_lock, "presentational-hints.css",
- &resources::read_bytes(Resource::PresentationalHintsCSS))?,
+ parse_ua_stylesheet(
+ &shared_lock,
+ "user-agent.css",
+ &resources::read_bytes(Resource::UserAgentCSS),
+ )?,
+ parse_ua_stylesheet(
+ &shared_lock,
+ "servo.css",
+ &resources::read_bytes(Resource::ServoCSS),
+ )?,
+ parse_ua_stylesheet(
+ &shared_lock,
+ "presentational-hints.css",
+ &resources::read_bytes(Resource::PresentationalHintsCSS),
+ )?,
];
for &(ref contents, ref url) in &opts::get().user_stylesheets {
- user_or_user_agent_stylesheets.push(
- DocumentStyleSheet(ServoArc::new(Stylesheet::from_bytes(
+ user_or_user_agent_stylesheets.push(DocumentStyleSheet(ServoArc::new(
+ Stylesheet::from_bytes(
&contents,
url.clone(),
None,
@@ -1786,12 +1921,15 @@ fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> {
None,
Some(&RustLogReporter),
QuirksMode::NoQuirks,
- )))
- );
+ ),
+ )));
}
- let quirks_mode_stylesheet = parse_ua_stylesheet(&shared_lock, "quirks-mode.css",
- &resources::read_bytes(Resource::QuirksModeCSS))?;
+ let quirks_mode_stylesheet = parse_ua_stylesheet(
+ &shared_lock,
+ "quirks-mode.css",
+ &resources::read_bytes(Resource::QuirksModeCSS),
+ )?;
Ok(UserAgentStylesheets {
shared_lock: shared_lock,
@@ -1807,7 +1945,7 @@ lazy_static! {
Err(filename) => {
error!("Failed to load UA stylesheet {}!", filename);
process::exit(1);
- }
+ },
}
};
}
@@ -1820,8 +1958,13 @@ struct RegisteredPainterImpl {
}
impl SpeculativePainter for RegisteredPainterImpl {
- fn speculatively_draw_a_paint_image(&self, properties: Vec<(Atom, String)>, arguments: Vec<String>) {
- self.painter.speculatively_draw_a_paint_image(properties, arguments);
+ fn speculatively_draw_a_paint_image(
+ &self,
+ properties: Vec<(Atom, String)>,
+ arguments: Vec<String>,
+ ) {
+ self.painter
+ .speculatively_draw_a_paint_image(properties, arguments);
}
}
@@ -1835,14 +1978,15 @@ impl RegisteredSpeculativePainter for RegisteredPainterImpl {
}
impl Painter for RegisteredPainterImpl {
- fn draw_a_paint_image(&self,
- size: TypedSize2D<f32, CSSPixel>,
- device_pixel_ratio: TypedScale<f32, CSSPixel, DevicePixel>,
- properties: Vec<(Atom, String)>,
- arguments: Vec<String>)
- -> Result<DrawAPaintImageResult, PaintWorkletError>
- {
- self.painter.draw_a_paint_image(size, device_pixel_ratio, properties, arguments)
+ fn draw_a_paint_image(
+ &self,
+ size: TypedSize2D<f32, CSSPixel>,
+ device_pixel_ratio: TypedScale<f32, CSSPixel, DevicePixel>,
+ properties: Vec<(Atom, String)>,
+ arguments: Vec<String>,
+ ) -> Result<DrawAPaintImageResult, PaintWorkletError> {
+ self.painter
+ .draw_a_paint_image(size, device_pixel_ratio, properties, arguments)
}
}
@@ -1850,14 +1994,18 @@ impl RegisteredPainter for RegisteredPainterImpl {}
struct RegisteredPaintersImpl(FnvHashMap<Atom, RegisteredPainterImpl>);
-impl RegisteredSpeculativePainters for RegisteredPaintersImpl {
+impl RegisteredSpeculativePainters for RegisteredPaintersImpl {
fn get(&self, name: &Atom) -> Option<&RegisteredSpeculativePainter> {
- self.0.get(&name).map(|painter| painter as &RegisteredSpeculativePainter)
+ self.0
+ .get(&name)
+ .map(|painter| painter as &RegisteredSpeculativePainter)
}
}
impl RegisteredPainters for RegisteredPaintersImpl {
fn get(&self, name: &Atom) -> Option<&RegisteredPainter> {
- self.0.get(&name).map(|painter| painter as &RegisteredPainter)
+ self.0
+ .get(&name)
+ .map(|painter| painter as &RegisteredPainter)
}
}