From 67ac81f4402768f43e6bd69e3901169d4af511e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 28 Jul 2016 15:13:17 -0700 Subject: [PATCH 1/5] style: Fix sequential traversal. --- components/style/sequential.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/style/sequential.rs b/components/style/sequential.rs index 56b8a563d27..2ae7a18048b 100644 --- a/components/style/sequential.rs +++ b/components/style/sequential.rs @@ -21,7 +21,7 @@ pub fn traverse_dom(root: N, for kid in node.children() { context.pre_process_child_hook(node, kid); - if context.should_process(node) { + if context.should_process(kid) { doit::(context, kid); } } From 1470d5b17443a74ebcb1f9be42f7daa124f7b01a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 28 Jul 2016 19:36:37 -0700 Subject: [PATCH 2/5] stylo: Allow computing change hints during the traversal. --- .../script_layout_interface/restyle_damage.rs | 5 +- components/style/dom.rs | 2 +- components/style/gecko_glue.rs | 5 +- components/style/matching.rs | 6 +-- components/style/traversal.rs | 1 - ports/geckolib/gecko_bindings/bindings.rs | 7 +-- ports/geckolib/wrapper.rs | 50 +++++++++++++++---- 7 files changed, 55 insertions(+), 21 deletions(-) diff --git a/components/script_layout_interface/restyle_damage.rs b/components/script_layout_interface/restyle_damage.rs index c1005099442..733b33bead0 100644 --- a/components/script_layout_interface/restyle_damage.rs +++ b/components/script_layout_interface/restyle_damage.rs @@ -44,7 +44,7 @@ bitflags! { } impl TRestyleDamage for RestyleDamage { - fn compute(old: Option<&Arc>, new: &ServoComputedValues) -> + fn compute(old: Option<&Arc>, new: &Arc) -> RestyleDamage { compute_damage(old, new) } /// Returns a bitmask that represents a flow that needs to be rebuilt and reflowed. @@ -143,7 +143,8 @@ macro_rules! add_if_not_equal( }) ); -fn compute_damage(old: Option<&Arc>, new: &ServoComputedValues) -> RestyleDamage { +fn compute_damage(old: Option<&Arc>, new: &Arc) -> RestyleDamage { + let new = &**new; let old: &ServoComputedValues = match old { None => return RestyleDamage::rebuild_and_reflow(), Some(cv) => &**cv, diff --git a/components/style/dom.rs b/components/style/dom.rs index c694ca75732..13d7e37d70c 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -46,7 +46,7 @@ impl OpaqueNode { } pub trait TRestyleDamage : BitOr + Copy { - fn compute(old: Option<&Arc>, new: &ComputedValues) -> Self; + fn compute(old: Option<&Arc>, new: &Arc) -> Self; fn rebuild_and_reflow() -> Self; } diff --git a/components/style/gecko_glue.rs b/components/style/gecko_glue.rs index fadae2f57bc..b9cbbb15a85 100644 --- a/components/style/gecko_glue.rs +++ b/components/style/gecko_glue.rs @@ -13,7 +13,6 @@ pub struct ArcHelpers { phantom2: PhantomData, } - impl ArcHelpers { pub fn with(raw: *mut GeckoType, cb: F) -> Output where F: FnOnce(&Arc) -> Output { @@ -47,6 +46,10 @@ impl ArcHelpers { unsafe { transmute(owned) } } + pub unsafe fn borrow(borrowed: &Arc) -> *const &mut GeckoType { + transmute(borrowed) + } + pub unsafe fn addref(ptr: *mut GeckoType) { Self::with(ptr, |arc| forget(arc.clone())); } diff --git a/components/style/matching.rs b/components/style/matching.rs index 2cd51352355..1b5885422fc 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -443,7 +443,7 @@ trait PrivateMatchMethods: TNode } // Calculate style difference. - let damage = Self::ConcreteRestyleDamage::compute(style.map(|s| &*s), &*this_style); + let damage = Self::ConcreteRestyleDamage::compute(style.map(|s| &*s), &this_style); // Cache the resolved style if it was cacheable. if cacheable { @@ -587,7 +587,7 @@ pub trait ElementMatchMethods : TElement { let node = self.as_node(); let style = &mut node.mutate_data().unwrap().style; let damage = <::ConcreteNode as TNode> - ::ConcreteRestyleDamage::compute((*style).as_ref(), &*shared_style); + ::ConcreteRestyleDamage::compute((*style).as_ref(), &shared_style); *style = Some(shared_style); return StyleSharingResult::StyleWasShared(i, damage) } @@ -676,7 +676,7 @@ pub trait MatchMethods : TNode { let mut data = &mut *data_ref; let cloned_parent_style = ComputedValues::style_for_child_text_node(parent_style.unwrap()); damage = Self::ConcreteRestyleDamage::compute(data.style.as_ref(), - &*cloned_parent_style); + &cloned_parent_style); data.style = Some(cloned_parent_style); } else { damage = { diff --git a/components/style/traversal.rs b/components/style/traversal.rs index d1cf9eb833b..e56db456dbf 100644 --- a/components/style/traversal.rs +++ b/components/style/traversal.rs @@ -12,7 +12,6 @@ use selector_impl::SelectorImplExt; use selectors::Element; use selectors::bloom::BloomFilter; use std::cell::RefCell; -use std::sync::Arc; use tid::tid; use util::opts; use values::HasViewportPercentage; diff --git a/ports/geckolib/gecko_bindings/bindings.rs b/ports/geckolib/gecko_bindings/bindings.rs index 10d2bbb7c43..35f89f89074 100644 --- a/ports/geckolib/gecko_bindings/bindings.rs +++ b/ports/geckolib/gecko_bindings/bindings.rs @@ -294,10 +294,11 @@ extern "C" { pub fn Gecko_GetNodeFlags(node: *mut RawGeckoNode) -> u32; pub fn Gecko_SetNodeFlags(node: *mut RawGeckoNode, flags: u32); pub fn Gecko_UnsetNodeFlags(node: *mut RawGeckoNode, flags: u32); - pub fn Gecko_CalcAndStoreStyleDifference(element: *mut RawGeckoElement, - newstyle: - *mut ServoComputedValues) + pub fn Gecko_CalcStyleDifference(oldstyle: *mut ServoComputedValues, + newstyle: *mut ServoComputedValues) -> nsChangeHint; + pub fn Gecko_StoreStyleDifference(node: *mut RawGeckoNode, + change: nsChangeHint); pub fn Gecko_EnsureTArrayCapacity(array: *mut ::std::os::raw::c_void, capacity: usize, elem_size: usize); pub fn Gecko_EnsureImageLayersLength(layers: *mut nsStyleImageLayers, diff --git a/ports/geckolib/wrapper.rs b/ports/geckolib/wrapper.rs index d71666975a0..c236ddeb7f1 100644 --- a/ports/geckolib/wrapper.rs +++ b/ports/geckolib/wrapper.rs @@ -8,7 +8,9 @@ use gecko_bindings::bindings; use gecko_bindings::bindings::Gecko_ChildrenCount; use gecko_bindings::bindings::Gecko_ClassOrClassList; use gecko_bindings::bindings::Gecko_GetNodeData; +use gecko_bindings::bindings::ServoComputedValues; use gecko_bindings::bindings::ServoNodeData; +use gecko_bindings::bindings::{Gecko_CalcStyleDifference, Gecko_StoreStyleDifference}; use gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentElement}; use gecko_bindings::bindings::{Gecko_GetFirstChild, Gecko_GetFirstChildElement}; use gecko_bindings::bindings::{Gecko_GetLastChild, Gecko_GetLastChildElement}; @@ -21,8 +23,8 @@ use gecko_bindings::bindings::{Gecko_IsLink, Gecko_IsRootElement, Gecko_IsTextNo use gecko_bindings::bindings::{Gecko_IsUnvisitedLink, Gecko_IsVisitedLink}; use gecko_bindings::bindings::{Gecko_LocalName, Gecko_Namespace, Gecko_NodeIsElement, Gecko_SetNodeData}; use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode}; -use gecko_bindings::structs::nsIAtom; use gecko_bindings::structs::{NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO, NODE_IS_DIRTY_FOR_SERVO}; +use gecko_bindings::structs::{nsIAtom, nsChangeHint}; use glue::GeckoDeclarationBlock; use libc::uintptr_t; use selectors::Element; @@ -40,6 +42,7 @@ use style::dom::{OpaqueNode, PresentationalHintsSynthetizer}; use style::dom::{TDocument, TElement, TNode, TRestyleDamage, UnsafeNode}; use style::element_state::ElementState; use style::error_reporting::StdoutErrorReporter; +use style::gecko_glue::ArcHelpers; use style::gecko_selector_impl::{GeckoSelectorImpl, NonTSPseudoClass}; use style::parser::ParserContextExtraData; use style::properties::{ComputedValues, parse_style_attribute}; @@ -91,14 +94,36 @@ impl<'ln> GeckoNode<'ln> { } #[derive(Clone, Copy)] -pub struct DummyRestyleDamage; -impl TRestyleDamage for DummyRestyleDamage { - fn compute(_: Option<&Arc>, _: &ComputedValues) -> Self { DummyRestyleDamage } - fn rebuild_and_reflow() -> Self { DummyRestyleDamage } +pub struct GeckoRestyleDamage(nsChangeHint); + +impl TRestyleDamage for GeckoRestyleDamage { + fn compute(previous_style: Option<&Arc>, + current_style: &Arc) -> Self { + type Helpers = ArcHelpers; + let previous_style = match previous_style { + Some(previous) => previous, + None => return Self::rebuild_and_reflow(), + }; + + let previous = unsafe { Helpers::borrow(previous_style) }; + let current = unsafe { Helpers::borrow(current_style) }; + let hint = unsafe { Gecko_CalcStyleDifference(*previous, *current) }; + + GeckoRestyleDamage(hint) + } + + fn rebuild_and_reflow() -> Self { + GeckoRestyleDamage(nsChangeHint::nsChangeHint_ReconstructFrame) + } } -impl BitOr for DummyRestyleDamage { + +impl BitOr for GeckoRestyleDamage { type Output = Self; - fn bitor(self, _: Self) -> Self { DummyRestyleDamage } + + fn bitor(self, other: Self) -> Self { + use std::mem; + GeckoRestyleDamage(unsafe { mem::transmute(self.0 as u32 | other.0 as u32) }) + } } @@ -106,7 +131,7 @@ impl BitOr for DummyRestyleDamage { impl<'ln> TNode for GeckoNode<'ln> { type ConcreteDocument = GeckoDocument<'ln>; type ConcreteElement = GeckoElement<'ln>; - type ConcreteRestyleDamage = DummyRestyleDamage; + type ConcreteRestyleDamage = GeckoRestyleDamage; fn to_unsafe(&self) -> UnsafeNode { (self.node as usize, 0) @@ -243,9 +268,14 @@ impl<'ln> TNode for GeckoNode<'ln> { } } - fn restyle_damage(self) -> Self::ConcreteRestyleDamage { DummyRestyleDamage } + fn restyle_damage(self) -> Self::ConcreteRestyleDamage { + // Not called from style, only for layout. + unimplemented!(); + } - fn set_restyle_damage(self, _: Self::ConcreteRestyleDamage) {} + fn set_restyle_damage(self, damage: Self::ConcreteRestyleDamage) { + unsafe { Gecko_StoreStyleDifference(self.node, damage.0) } + } fn parent_node(&self) -> Option> { unsafe { From 6d67525172811f203220f02defa7b4635e6414c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 29 Jul 2016 14:17:56 -0700 Subject: [PATCH 3/5] style: Refactor TRestyleDamage and TNode to accept/provide a "style source" In the Gecko case, this style source would be the style context. In the servo case, it will be always the computed values. We could optimise this further in the case of stylo (from three FFI calls to one) if we use an API of the form CalcAndStore(node, new_cv). But that would imply borrowing the data twice from Servo (we also have borrow_data_unchecked fwiw, but...). --- components/layout/animation.rs | 6 ++- components/script/layout_wrapper.rs | 10 ++++- .../script_layout_interface/restyle_damage.rs | 21 +++++++---- components/style/animation.rs | 19 +++------- components/style/dom.rs | 21 ++++++++++- components/style/gecko_glue.rs | 9 ++++- components/style/matching.rs | 37 ++++++++++++++----- ports/geckolib/gecko_bindings/bindings.rs | 8 +++- ports/geckolib/gecko_bindings/tools/regen.py | 2 +- ports/geckolib/wrapper.rs | 35 +++++++++++++----- 10 files changed, 120 insertions(+), 48 deletions(-) diff --git a/components/layout/animation.rs b/components/layout/animation.rs index 5a67b1af5bf..5222d4ba70a 100644 --- a/components/layout/animation.rs +++ b/components/layout/animation.rs @@ -14,6 +14,7 @@ use script_traits::{AnimationState, LayoutMsg as ConstellationMsg}; use std::collections::HashMap; use std::sync::mpsc::Receiver; use style::animation::{Animation, update_style_for_animation}; +use style::dom::TRestyleDamage; use style::timer::Timer; /// Processes any new animations that were discovered after style recalculation. @@ -130,10 +131,11 @@ pub fn recalc_style_for_animations(context: &SharedLayoutContext, flow.mutate_fragments(&mut |fragment| { if let Some(ref animations) = animations.get(&fragment.node) { for animation in animations.iter() { + let old_style = fragment.style.clone(); update_style_for_animation(&context.style_context, animation, - &mut fragment.style, - Some(&mut damage)); + &mut fragment.style); + damage |= RestyleDamage::compute(Some(&old_style), &fragment.style); } } }); diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs index bfd7a8273d9..6dcfc06884f 100644 --- a/components/script/layout_wrapper.rs +++ b/components/script/layout_wrapper.rs @@ -51,6 +51,7 @@ use selectors::matching::{DeclarationBlock, ElementFlags}; use selectors::parser::{AttrSelector, NamespaceConstraint}; use std::marker::PhantomData; use std::mem::{transmute, transmute_copy}; +use std::sync::Arc; use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace}; use style::attr::AttrValue; use style::computed_values::display; @@ -58,7 +59,7 @@ use style::context::SharedStyleContext; use style::data::PrivateStyleData; use style::dom::{PresentationalHintsSynthetizer, OpaqueNode, TDocument, TElement, TNode, UnsafeNode}; use style::element_state::*; -use style::properties::{PropertyDeclaration, PropertyDeclarationBlock}; +use style::properties::{ComputedValues, PropertyDeclaration, PropertyDeclarationBlock}; use style::refcell::{Ref, RefCell, RefMut}; use style::selector_impl::{ElementSnapshot, NonTSPseudoClass, ServoSelectorImpl}; use style::sink::Push; @@ -262,6 +263,13 @@ impl<'ln> TNode for ServoLayoutNode<'ln> { self.node.next_sibling_ref().map(|node| self.new_with_this_lifetime(&node)) } } + + #[inline] + fn existing_style_for_restyle_damage<'a>(&'a self, + current_cv: Option<&'a Arc>) + -> Option<&'a Arc> { + current_cv + } } impl<'ln> LayoutNode for ServoLayoutNode<'ln> { diff --git a/components/script_layout_interface/restyle_damage.rs b/components/script_layout_interface/restyle_damage.rs index 733b33bead0..fc7c11d4259 100644 --- a/components/script_layout_interface/restyle_damage.rs +++ b/components/script_layout_interface/restyle_damage.rs @@ -44,21 +44,28 @@ bitflags! { } impl TRestyleDamage for RestyleDamage { - fn compute(old: Option<&Arc>, new: &Arc) -> - RestyleDamage { compute_damage(old, new) } + /// For Servo the style source is always the computed values. + type PreExistingComputedValues = Arc; - /// Returns a bitmask that represents a flow that needs to be rebuilt and reflowed. + fn compute(old: Option<&Arc>, + new: &Arc) -> RestyleDamage { + compute_damage(old, new) + } + + /// Returns a bitmask that represents a flow that needs to be rebuilt and + /// reflowed. /// - /// Use this instead of `RestyleDamage::all()` because `RestyleDamage::all()` will result in - /// unnecessary sequential resolution of generated content. + /// Use this instead of `RestyleDamage::all()` because + /// `RestyleDamage::all()` will result in unnecessary sequential resolution + /// of generated content. fn rebuild_and_reflow() -> RestyleDamage { REPAINT | STORE_OVERFLOW | BUBBLE_ISIZES | REFLOW_OUT_OF_FLOW | REFLOW | RECONSTRUCT_FLOW } } impl RestyleDamage { - /// Supposing a flow has the given `position` property and this damage, returns the damage that - /// we should add to the *parent* of this flow. + /// Supposing a flow has the given `position` property and this damage, + /// returns the damage that we should add to the *parent* of this flow. pub fn damage_for_parent(self, child_is_absolutely_positioned: bool) -> RestyleDamage { if child_is_absolutely_positioned { self & (REPAINT | STORE_OVERFLOW | REFLOW_OUT_OF_FLOW | RESOLVE_GENERATED_CONTENT) diff --git a/components/style/animation.rs b/components/style/animation.rs index a4600418023..1767cd49234 100644 --- a/components/style/animation.rs +++ b/components/style/animation.rs @@ -6,7 +6,7 @@ use bezier::Bezier; use context::SharedStyleContext; -use dom::{OpaqueNode, TRestyleDamage}; +use dom::OpaqueNode; use euclid::point::Point2D; use keyframes::{KeyframesStep, KeyframesStepValue}; use properties::animated_properties::{AnimatedProperty, TransitionProperty}; @@ -490,13 +490,12 @@ pub fn update_style_for_animation_frame(mut new_style: &mut Arc, } /// Updates a single animation and associated style based on the current time. /// If `damage` is provided, inserts the appropriate restyle damage. -pub fn update_style_for_animation(context: &SharedStyleContext, - animation: &Animation, - style: &mut Arc, - damage: Option<&mut Damage>) -where Damage: TRestyleDamage { +pub fn update_style_for_animation(context: &SharedStyleContext, + animation: &Animation, + style: &mut Arc) { debug!("update_style_for_animation: entering"); debug_assert!(!animation.is_expired()); + match *animation { Animation::Transition(_, start_time, ref frame, _) => { debug!("update_style_for_animation: transition found"); @@ -506,10 +505,6 @@ where Damage: TRestyleDamage { now, start_time, frame); if updated_style { - if let Some(damage) = damage { - *damage = *damage | Damage::compute(Some(style), &new_style); - } - *style = new_style } } @@ -660,10 +655,6 @@ where Damage: TRestyleDamage { } debug!("update_style_for_animation: got style change in animation \"{}\"", name); - if let Some(damage) = damage { - *damage = *damage | Damage::compute(Some(style), &new_style); - } - *style = new_style; } } diff --git a/components/style/dom.rs b/components/style/dom.rs index 13d7e37d70c..3406cf2815e 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -46,7 +46,19 @@ impl OpaqueNode { } pub trait TRestyleDamage : BitOr + Copy { - fn compute(old: Option<&Arc>, new: &Arc) -> Self; + /// The source for our current computed values in the cascade. This is a + /// ComputedValues in Servo and a StyleContext in Gecko. + /// + /// This is needed because Gecko has a few optimisations for the calculation + /// of the difference depending on which values have been used during + /// layout. + /// + /// This should be obtained via TNode::existing_style_for_restyle_damage + type PreExistingComputedValues; + + fn compute(old: Option<&Self::PreExistingComputedValues>, + new: &Arc) -> Self; + fn rebuild_and_reflow() -> Self; } @@ -159,6 +171,13 @@ pub trait TNode : Sized + Copy + Clone { fn unstyle(self) { self.mutate_data().unwrap().style = None; } + + /// XXX: It's a bit unfortunate we need to pass the current computed values + /// as an argument here, but otherwise Servo would crash due to double + /// borrows to return it. + fn existing_style_for_restyle_damage<'a>(&'a self, + current_computed_values: Option<&'a Arc>) + -> Option<&'a ::PreExistingComputedValues>; } pub trait TDocument : Sized + Copy + Clone { diff --git a/components/style/gecko_glue.rs b/components/style/gecko_glue.rs index b9cbbb15a85..d9ec0bd5562 100644 --- a/components/style/gecko_glue.rs +++ b/components/style/gecko_glue.rs @@ -46,8 +46,13 @@ impl ArcHelpers { unsafe { transmute(owned) } } - pub unsafe fn borrow(borrowed: &Arc) -> *const &mut GeckoType { - transmute(borrowed) + pub fn borrow(borrowed: &Arc, cb: F) -> Output + where F: FnOnce(&mut GeckoType) -> Output + { + let borrowed_gecko_type: *const &mut GeckoType = + unsafe { transmute(borrowed) }; + + unsafe { cb(*borrowed_gecko_type) } } pub unsafe fn addref(ptr: *mut GeckoType) { diff --git a/components/style/matching.rs b/components/style/matching.rs index 1b5885422fc..f8a7c0dc160 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -6,7 +6,7 @@ #![allow(unsafe_code)] -use animation::{self, Animation}; +use animation; use arc_ptr_eq; use cache::{LRUCache, SimpleHashCache}; use context::{StyleContext, SharedStyleContext}; @@ -442,8 +442,13 @@ trait PrivateMatchMethods: TNode cacheable = cacheable && !animations_started } + + let existing_style = + self.existing_style_for_restyle_damage(style.map(|s| &*s)); + // Calculate style difference. - let damage = Self::ConcreteRestyleDamage::compute(style.map(|s| &*s), &this_style); + let damage = + Self::ConcreteRestyleDamage::compute(existing_style, &this_style); // Cache the resolved style if it was cacheable. if cacheable { @@ -490,8 +495,9 @@ trait PrivateMatchMethods: TNode // See #12171 and the associated PR for an example where this // happened while debugging other release panic. if !running_animation.is_expired() { - animation::update_style_for_animation::( - context, running_animation, style, None); + animation::update_style_for_animation(context, + running_animation, + style); running_animation.mark_as_expired(); } } @@ -585,9 +591,17 @@ pub trait ElementMatchMethods : TElement { if let Some(shared_style) = self.share_style_with_candidate_if_possible(parent.clone(), candidate) { // Yay, cache hit. Share the style. let node = self.as_node(); + let style = &mut node.mutate_data().unwrap().style; - let damage = <::ConcreteNode as TNode> - ::ConcreteRestyleDamage::compute((*style).as_ref(), &shared_style); + + let damage = { + let source = + node.existing_style_for_restyle_damage((*style).as_ref()); + let damage = <::ConcreteNode as TNode> + ::ConcreteRestyleDamage::compute(source, &shared_style); + damage + }; + *style = Some(shared_style); return StyleSharingResult::StyleWasShared(i, damage) } @@ -675,8 +689,14 @@ pub trait MatchMethods : TNode { let mut data_ref = self.mutate_data().unwrap(); let mut data = &mut *data_ref; let cloned_parent_style = ComputedValues::style_for_child_text_node(parent_style.unwrap()); - damage = Self::ConcreteRestyleDamage::compute(data.style.as_ref(), - &cloned_parent_style); + + { + let existing_style = + self.existing_style_for_restyle_damage(data.style.as_ref()); + damage = Self::ConcreteRestyleDamage::compute(existing_style, + &cloned_parent_style); + } + data.style = Some(cloned_parent_style); } else { damage = { @@ -697,7 +717,6 @@ pub trait MatchMethods : TNode { let applicable_declarations_for_this_pseudo = applicable_declarations.per_pseudo.get(&pseudo).unwrap(); - if !applicable_declarations_for_this_pseudo.is_empty() { // NB: Transitions and animations should only work for // pseudo-elements ::before and ::after diff --git a/ports/geckolib/gecko_bindings/bindings.rs b/ports/geckolib/gecko_bindings/bindings.rs index 35f89f89074..646e1cffc4e 100644 --- a/ports/geckolib/gecko_bindings/bindings.rs +++ b/ports/geckolib/gecko_bindings/bindings.rs @@ -144,6 +144,10 @@ use structs::nsFont; use structs::FontFamilyList; use structs::FontFamilyType; use structs::nsIAtom; +use structs::nsStyleContext; +unsafe impl Send for nsStyleContext {} +unsafe impl Sync for nsStyleContext {} +impl HeapSizeOf for nsStyleContext { fn heap_size_of_children(&self) -> usize { 0 } } pub type RawGeckoNode = nsINode; pub enum Element { } @@ -294,7 +298,9 @@ extern "C" { pub fn Gecko_GetNodeFlags(node: *mut RawGeckoNode) -> u32; pub fn Gecko_SetNodeFlags(node: *mut RawGeckoNode, flags: u32); pub fn Gecko_UnsetNodeFlags(node: *mut RawGeckoNode, flags: u32); - pub fn Gecko_CalcStyleDifference(oldstyle: *mut ServoComputedValues, + pub fn Gecko_GetStyleContext(node: *mut RawGeckoNode) + -> *mut nsStyleContext; + pub fn Gecko_CalcStyleDifference(oldstyle: *mut nsStyleContext, newstyle: *mut ServoComputedValues) -> nsChangeHint; pub fn Gecko_StoreStyleDifference(node: *mut RawGeckoNode, diff --git a/ports/geckolib/gecko_bindings/tools/regen.py b/ports/geckolib/gecko_bindings/tools/regen.py index 821a5e475a7..534acbeb146 100755 --- a/ports/geckolib/gecko_bindings/tools/regen.py +++ b/ports/geckolib/gecko_bindings/tools/regen.py @@ -128,7 +128,7 @@ COMPILATION_TARGETS = { "nsStyleCoord::Calc", "nsRestyleHint", "ServoElementSnapshot", "nsChangeHint", "SheetParsingMode", "nsMainThreadPtrHandle", "nsMainThreadPtrHolder", "nscolor", "nsFont", "FontFamilyList", - "FontFamilyType", "nsIAtom", + "FontFamilyType", "nsIAtom", "nsStyleContext" ], "void_types": [ "nsINode", "nsIDocument", "nsIPrincipal", "nsIURI", diff --git a/ports/geckolib/wrapper.rs b/ports/geckolib/wrapper.rs index c236ddeb7f1..b750fda883f 100644 --- a/ports/geckolib/wrapper.rs +++ b/ports/geckolib/wrapper.rs @@ -8,6 +8,7 @@ use gecko_bindings::bindings; use gecko_bindings::bindings::Gecko_ChildrenCount; use gecko_bindings::bindings::Gecko_ClassOrClassList; use gecko_bindings::bindings::Gecko_GetNodeData; +use gecko_bindings::bindings::Gecko_GetStyleContext; use gecko_bindings::bindings::ServoComputedValues; use gecko_bindings::bindings::ServoNodeData; use gecko_bindings::bindings::{Gecko_CalcStyleDifference, Gecko_StoreStyleDifference}; @@ -24,7 +25,7 @@ use gecko_bindings::bindings::{Gecko_IsUnvisitedLink, Gecko_IsVisitedLink}; use gecko_bindings::bindings::{Gecko_LocalName, Gecko_Namespace, Gecko_NodeIsElement, Gecko_SetNodeData}; use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode}; use gecko_bindings::structs::{NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO, NODE_IS_DIRTY_FOR_SERVO}; -use gecko_bindings::structs::{nsIAtom, nsChangeHint}; +use gecko_bindings::structs::{nsIAtom, nsChangeHint, nsStyleContext}; use glue::GeckoDeclarationBlock; use libc::uintptr_t; use selectors::Element; @@ -97,19 +98,19 @@ impl<'ln> GeckoNode<'ln> { pub struct GeckoRestyleDamage(nsChangeHint); impl TRestyleDamage for GeckoRestyleDamage { - fn compute(previous_style: Option<&Arc>, - current_style: &Arc) -> Self { + type PreExistingComputedValues = nsStyleContext; + fn compute(source: Option<&nsStyleContext>, + new_style: &Arc) -> Self { type Helpers = ArcHelpers; - let previous_style = match previous_style { - Some(previous) => previous, + let context = match source { + Some(ctx) => ctx as *const nsStyleContext as *mut nsStyleContext, None => return Self::rebuild_and_reflow(), }; - let previous = unsafe { Helpers::borrow(previous_style) }; - let current = unsafe { Helpers::borrow(current_style) }; - let hint = unsafe { Gecko_CalcStyleDifference(*previous, *current) }; - - GeckoRestyleDamage(hint) + Helpers::borrow(new_style, |new_style| { + let hint = unsafe { Gecko_CalcStyleDifference(context, new_style) }; + GeckoRestyleDamage(hint) + }) } fn rebuild_and_reflow() -> Self { @@ -307,6 +308,20 @@ impl<'ln> TNode for GeckoNode<'ln> { } } + fn existing_style_for_restyle_damage<'a>(&'a self, + current_cv: Option<&'a Arc>) + -> Option<&'a nsStyleContext> { + if current_cv.is_none() { + // Don't bother in doing an ffi call to get null back. + return None; + } + + unsafe { + let context_ptr = Gecko_GetStyleContext(self.node); + context_ptr.as_ref() + } + } + fn needs_dirty_on_viewport_size_changed(&self) -> bool { // Gecko's node doesn't have the DIRTY_ON_VIEWPORT_SIZE_CHANGE flag, // so we force them to be dirtied on viewport size change, regardless if From 27b2bad256e7a08cf647ecae37cfd80bf2310f54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 3 Aug 2016 00:36:45 -0700 Subject: [PATCH 4/5] stylo: Fix and ensure alignment of restyle hints. Test it on Travis. Turns out eRestyle_LaterSiblings was not really matching, sigh... --- .travis.yml | 1 + components/style/restyle_hints.rs | 2 +- ports/geckolib/lib.rs | 1 + ports/geckolib/sanity_checks.rs | 44 +++++++++++++++++++++++++++++++ python/servo/testing_commands.py | 11 ++++++++ 5 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 ports/geckolib/sanity_checks.rs diff --git a/.travis.yml b/.travis.yml index 7796d98cd23..d1f71944887 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ matrix: script: - ./mach build -d --verbose - ./mach build-geckolib + - ./mach test-geckolib - ./mach test-unit - ./mach test-compiletest - bash etc/ci/check_no_unwrap.sh diff --git a/components/style/restyle_hints.rs b/components/style/restyle_hints.rs index 5dcaa147453..619aa22724b 100644 --- a/components/style/restyle_hints.rs +++ b/components/style/restyle_hints.rs @@ -28,7 +28,7 @@ bitflags! { // of a good reason for that. const RESTYLE_DESCENDANTS = 0x02, #[doc = "Rerun selector matching on all later siblings of the element and all of their descendants."] - const RESTYLE_LATER_SIBLINGS = 0x04, + const RESTYLE_LATER_SIBLINGS = 0x08, } } diff --git a/ports/geckolib/lib.rs b/ports/geckolib/lib.rs index 81923a9188c..c5c31eae733 100644 --- a/ports/geckolib/lib.rs +++ b/ports/geckolib/lib.rs @@ -26,6 +26,7 @@ mod snapshot; mod snapshot_helpers; #[allow(non_snake_case)] pub mod glue; +mod sanity_checks; mod traversal; mod wrapper; diff --git a/ports/geckolib/sanity_checks.rs b/ports/geckolib/sanity_checks.rs new file mode 100644 index 00000000000..96fd1e555b3 --- /dev/null +++ b/ports/geckolib/sanity_checks.rs @@ -0,0 +1,44 @@ +/* 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/. */ + +//! Different static asserts that ensure the build does what it's expected to. +//! +//! TODO: maybe cfg(test) this? + +#![allow(unused_imports)] + +use std::mem; + +macro_rules! check_enum_value { + ($a:expr, $b:expr) => { + unsafe { + mem::transmute::<[u32; $a as usize], + [u32; $b as usize]>([0; $a as usize]); + } + } +} + +// NB: It's a shame we can't do this statically with bitflags, but no +// const-fn and no other way to access the numerical value :-( +macro_rules! check_enum_value_non_static { + ($a:expr, $b:expr) => { + assert_eq!($a as usize, $b as usize); + } +} + +#[test] +fn assert_restyle_hints_match() { + use style::restyle_hints::*; // For flags + use gecko_bindings::structs::nsRestyleHint; + + check_enum_value_non_static!(nsRestyleHint::eRestyle_Self, RESTYLE_SELF.bits()); + // XXX This for Servo actually means something like an hypothetical + // Restyle_AllDescendants (but without running selector matching on the + // element). ServoRestyleManager interprets it like that, but in practice we + // should align the behavior with Gecko adding a new restyle hint, maybe? + // + // See https://bugzilla.mozilla.org/show_bug.cgi?id=1291786 + check_enum_value_non_static!(nsRestyleHint::eRestyle_SomeDescendants, RESTYLE_DESCENDANTS.bits()); + check_enum_value_non_static!(nsRestyleHint::eRestyle_LaterSiblings, RESTYLE_LATER_SIBLINGS.bits()); +} diff --git a/python/servo/testing_commands.py b/python/servo/testing_commands.py index 4776a9209d1..5eaad0ba7b9 100644 --- a/python/servo/testing_commands.py +++ b/python/servo/testing_commands.py @@ -158,6 +158,17 @@ class MachCommands(CommandBase): return suite return None + @Command('test-geckolib', + description='Test geckolib sanity checks', + category='testing') + def test_geckolib(self): + self.ensure_bootstrapped() + + env = self.build_env() + env["RUST_BACKTRACE"] = "1" + + return call(["cargo", "test"], env=env, cwd=path.join("ports", "geckolib")) + @Command('test-unit', description='Run unit tests', category='testing') From 444e8f85c8f5d0c1815f7227ec63c6b5a91f946a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 29 Jul 2016 16:53:11 -0700 Subject: [PATCH 5/5] Update bindings --- .../geckolib/gecko_bindings/structs_debug.rs | 135 +++++++++++++++--- .../gecko_bindings/structs_release.rs | 135 +++++++++++++++--- ports/geckolib/gecko_bindings/tools/regen.py | 7 +- 3 files changed, 230 insertions(+), 47 deletions(-) diff --git a/ports/geckolib/gecko_bindings/structs_debug.rs b/ports/geckolib/gecko_bindings/structs_debug.rs index 1ac5b06026e..fbad408e73a 100644 --- a/ports/geckolib/gecko_bindings/structs_debug.rs +++ b/ports/geckolib/gecko_bindings/structs_debug.rs @@ -188,6 +188,12 @@ pub const NS_ERROR_MODULE_BASE_OFFSET: ::std::os::raw::c_uint = 69; pub const MOZ_STRING_WITH_OBSOLETE_API: ::std::os::raw::c_uint = 1; pub const NSID_LENGTH: ::std::os::raw::c_uint = 39; pub const NS_NUMBER_OF_FLAGS_IN_REFCNT: ::std::os::raw::c_uint = 2; +pub const _STL_PAIR_H: ::std::os::raw::c_uint = 1; +pub const _GLIBCXX_UTILITY: ::std::os::raw::c_uint = 1; +pub const __cpp_lib_tuple_element_t: ::std::os::raw::c_uint = 201402; +pub const __cpp_lib_tuples_by_type: ::std::os::raw::c_uint = 201304; +pub const __cpp_lib_exchange_function: ::std::os::raw::c_uint = 201304; +pub const __cpp_lib_integer_sequence: ::std::os::raw::c_uint = 201304; pub const NS_EVENT_STATE_HIGHEST_SERVO_BIT: ::std::os::raw::c_uint = 6; pub const DOM_USER_DATA: ::std::os::raw::c_uint = 1; pub const SMIL_MAPPED_ATTR_ANIMVAL: ::std::os::raw::c_uint = 2; @@ -1484,6 +1490,53 @@ pub enum nsresult { NS_OK_NO_NAME_CLAUSE_HANDLED = 7864354, } pub type nsrefcnt = MozRefCountType; +#[repr(C)] +#[derive(Debug, Copy)] +pub struct HasPointerTypeHelper; +impl ::std::clone::Clone for HasPointerTypeHelper { + fn clone(&self) -> Self { *self } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct PointerType { + pub _phantom0: ::std::marker::PhantomData, + pub _phantom1: ::std::marker::PhantomData, +} +/** + *
+ * + * TODO(Emilio): This is a workaround and we should be able to get rid of this + * one. + */ +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct UniquePtr { + pub mPtr: *mut T, + pub _phantom0: ::std::marker::PhantomData, +} +/** + * A default deletion policy using plain old operator delete. + * + * Note that this type can be specialized, but authors should beware of the risk + * that the specialization may at some point cease to match (either because it + * gets moved to a different compilation unit or the signature changes). If the + * non-specialized (|delete|-based) version compiles for that type but does the + * wrong thing, bad things could happen. + * + * This is a non-issue for types which are always incomplete (i.e. opaque handle + * types), since |delete|-ing such a type will always trigger a compilation + * error. + */ +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct DefaultDelete { + pub _phantom0: ::std::marker::PhantomData, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct UniqueSelector { + pub _phantom0: ::std::marker::PhantomData, +} /** * typedefs for backwards compatibility */ @@ -2703,6 +2756,12 @@ impl ::std::clone::Clone for nsIExpandedPrincipal { fn clone(&self) -> Self { *self } } #[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _Make_integer_sequence<_Tp, _ISeq> { + pub _phantom0: ::std::marker::PhantomData<_Tp>, + pub _phantom1: ::std::marker::PhantomData<_ISeq>, +} +#[repr(C)] #[derive(Debug, Copy)] pub struct nsIURI { pub _base: nsISupports, @@ -2754,7 +2813,7 @@ impl ::std::clone::Clone for nsIRequest { #[repr(C)] #[derive(Debug, Copy)] pub struct EventStates { - pub mStates: ::std::os::raw::c_ulonglong, + pub mStates: ::std::os::raw::c_ulong, } impl ::std::clone::Clone for EventStates { fn clone(&self) -> Self { *self } @@ -2818,11 +2877,6 @@ pub enum nsNodeSupportsWeakRefTearoff { } pub enum nsNodeWeakReference { } pub enum nsDOMMutationObserver { } pub enum ServoNodeData { } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct DefaultDelete<> { - pub _phantom0: ::std::marker::PhantomData, -} pub enum EventListenerManager { } pub enum BoxQuadOptions { } pub enum ConvertCoordinateOptions { } @@ -2889,7 +2943,7 @@ fn bindgen_test_layout_nsMutationGuard() { extern "C" { #[link_name = "_ZN15nsMutationGuard11sGenerationE"] pub static mut nsMutationGuard_consts_sGeneration: - ::std::os::raw::c_ulonglong; + ::std::os::raw::c_ulong; } pub type Float = f32; #[repr(i8)] @@ -3280,7 +3334,7 @@ pub type nscolor = u32; #[repr(i8)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum nsHexColorType { NoAlpha = 0, AllowAlpha = 1, } -pub enum nsStyledElementNotElementCSSInlineStyle { } +pub enum nsStyledElement { } pub enum MiscContainer { } pub enum ServoDeclarationBlock { } pub enum Declaration { } @@ -3491,12 +3545,7 @@ fn bindgen_test_layout_ServoAttrSnapshot() { */ #[repr(i8)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum ServoElementSnapshotFlags { - State = 1, - Attributes = 2, - HTMLElementInHTMLDocument = 4, - All = 7, -} +pub enum ServoElementSnapshotFlags { State = 1, Attributes = 2, All = 3, } /** * This class holds all non-tree-structural state of an element that might be * used for selector matching eventually. @@ -3513,6 +3562,7 @@ pub struct ServoElementSnapshot { pub mExplicitRestyleHint: nsRestyleHint, pub mExplicitChangeHint: nsChangeHint, pub mIsHTMLElementInHTMLDocument: bool, + pub mIsInChromeDocument: bool, } #[test] fn bindgen_test_layout_ServoElementSnapshot() { @@ -5362,6 +5412,16 @@ pub enum nsStyleImageType { eStyleImageType_Gradient = 2, eStyleImageType_Element = 3, } +#[repr(C)] +pub struct CachedBorderImageData { + pub mCachedSVGViewportSize: [u64; 2usize], + pub mSubImages: u64, +} +#[test] +fn bindgen_test_layout_CachedBorderImageData() { + assert_eq!(::std::mem::size_of::() , 24usize); + assert_eq!(::std::mem::align_of::() , 8usize); +} /** * Represents a paintable image of one of the following types. * (1) A real image loaded from an external source. @@ -5374,10 +5434,11 @@ pub enum nsStyleImageType { */ #[repr(C)] pub struct nsStyleImage { - pub mSubImages: u64, + pub mCachedBIData: UniquePtr>, pub mType: nsStyleImageType, pub nsStyleImage_nsStyleStruct_h_unnamed_21: nsStyleImage_nsStyleStruct_h_unnamed_21, - pub mCropRect: nsAutoPtr, + pub mCropRect: UniquePtr>, pub mImageTracked: bool, } #[repr(C)] @@ -6261,6 +6322,17 @@ extern "C" { #[link_name = "_ZN13nsStyleColumn15kMaxColumnCountE"] pub static nsStyleColumn_consts_kMaxColumnCount: ::std::os::raw::c_uint; } +#[repr(C)] +#[derive(Debug)] +pub struct FragmentOrURL { + pub mURL: nsCOMPtr, + pub mIsLocalRef: bool, +} +#[test] +fn bindgen_test_layout_FragmentOrURL() { + assert_eq!(::std::mem::size_of::() , 16usize); + assert_eq!(::std::mem::align_of::() , 8usize); +} #[repr(u32)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum nsStyleSVGPaintType { @@ -6288,7 +6360,7 @@ pub struct nsStyleSVGPaint { #[derive(Debug, Copy)] pub struct nsStyleSVGPaint_nsStyleStruct_h_unnamed_27 { pub mColor: __BindgenUnionField, - pub mPaintServer: __BindgenUnionField<*mut nsIURI>, + pub mPaintServer: __BindgenUnionField<*mut FragmentOrURL>, pub _bindgen_data_: u64, } impl nsStyleSVGPaint_nsStyleStruct_h_unnamed_27 { } @@ -6312,9 +6384,9 @@ fn bindgen_test_layout_nsStyleSVGPaint() { pub struct nsStyleSVG { pub mFill: nsStyleSVGPaint, pub mStroke: nsStyleSVGPaint, - pub mMarkerEnd: nsCOMPtr, - pub mMarkerMid: nsCOMPtr, - pub mMarkerStart: nsCOMPtr, + pub mMarkerEnd: FragmentOrURL, + pub mMarkerMid: FragmentOrURL, + pub mMarkerStart: FragmentOrURL, pub mStrokeDasharray: nsTArray, pub mStrokeDashoffset: nsStyleCoord, pub mStrokeWidth: nsStyleCoord, @@ -6345,7 +6417,7 @@ pub enum nsStyleSVG_nsStyleStruct_h_unnamed_28 { } #[test] fn bindgen_test_layout_nsStyleSVG() { - assert_eq!(::std::mem::size_of::() , 120usize); + assert_eq!(::std::mem::size_of::() , 144usize); assert_eq!(::std::mem::align_of::() , 8usize); } #[repr(C)] @@ -6383,7 +6455,7 @@ pub struct nsStyleClipPath { #[derive(Debug, Copy)] pub struct nsStyleClipPath_nsStyleStruct_h_unnamed_29 { pub mBasicShape: __BindgenUnionField<*mut nsStyleBasicShape>, - pub mURL: __BindgenUnionField<*mut nsIURI>, + pub mURL: __BindgenUnionField<*mut FragmentOrURL>, pub _bindgen_data_: u64, } impl nsStyleClipPath_nsStyleStruct_h_unnamed_29 { } @@ -6412,7 +6484,7 @@ pub struct nsStyleFilter { #[repr(C)] #[derive(Debug, Copy)] pub struct nsStyleFilter_nsStyleStruct_h_unnamed_30 { - pub mURL: __BindgenUnionField<*mut nsIURI>, + pub mURL: __BindgenUnionField<*mut FragmentOrURL>, pub mDropShadow: __BindgenUnionField<*mut nsCSSShadowArray>, pub _bindgen_data_: u64, } @@ -6474,3 +6546,20 @@ fn bindgen_test_layout_nsStyleEffects() { assert_eq!(::std::mem::size_of::() , 40usize); assert_eq!(::std::mem::align_of::() , 8usize); } +/** + *
+ */ +#[repr(C)] +#[derive(Debug, Copy)] +pub struct nsSize { + pub width: nscoord, + pub height: nscoord, +} +impl ::std::clone::Clone for nsSize { + fn clone(&self) -> Self { *self } +} +#[test] +fn bindgen_test_layout_nsSize() { + assert_eq!(::std::mem::size_of::() , 8usize); + assert_eq!(::std::mem::align_of::() , 4usize); +} diff --git a/ports/geckolib/gecko_bindings/structs_release.rs b/ports/geckolib/gecko_bindings/structs_release.rs index 418b428cc16..111bb6347a2 100644 --- a/ports/geckolib/gecko_bindings/structs_release.rs +++ b/ports/geckolib/gecko_bindings/structs_release.rs @@ -188,6 +188,12 @@ pub const NS_ERROR_MODULE_BASE_OFFSET: ::std::os::raw::c_uint = 69; pub const MOZ_STRING_WITH_OBSOLETE_API: ::std::os::raw::c_uint = 1; pub const NSID_LENGTH: ::std::os::raw::c_uint = 39; pub const NS_NUMBER_OF_FLAGS_IN_REFCNT: ::std::os::raw::c_uint = 2; +pub const _STL_PAIR_H: ::std::os::raw::c_uint = 1; +pub const _GLIBCXX_UTILITY: ::std::os::raw::c_uint = 1; +pub const __cpp_lib_tuple_element_t: ::std::os::raw::c_uint = 201402; +pub const __cpp_lib_tuples_by_type: ::std::os::raw::c_uint = 201304; +pub const __cpp_lib_exchange_function: ::std::os::raw::c_uint = 201304; +pub const __cpp_lib_integer_sequence: ::std::os::raw::c_uint = 201304; pub const NS_EVENT_STATE_HIGHEST_SERVO_BIT: ::std::os::raw::c_uint = 6; pub const DOM_USER_DATA: ::std::os::raw::c_uint = 1; pub const SMIL_MAPPED_ATTR_ANIMVAL: ::std::os::raw::c_uint = 2; @@ -1484,6 +1490,53 @@ pub enum nsresult { NS_OK_NO_NAME_CLAUSE_HANDLED = 7864354, } pub type nsrefcnt = MozRefCountType; +#[repr(C)] +#[derive(Debug, Copy)] +pub struct HasPointerTypeHelper; +impl ::std::clone::Clone for HasPointerTypeHelper { + fn clone(&self) -> Self { *self } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct PointerType { + pub _phantom0: ::std::marker::PhantomData, + pub _phantom1: ::std::marker::PhantomData, +} +/** + *
+ * + * TODO(Emilio): This is a workaround and we should be able to get rid of this + * one. + */ +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct UniquePtr { + pub mPtr: *mut T, + pub _phantom0: ::std::marker::PhantomData, +} +/** + * A default deletion policy using plain old operator delete. + * + * Note that this type can be specialized, but authors should beware of the risk + * that the specialization may at some point cease to match (either because it + * gets moved to a different compilation unit or the signature changes). If the + * non-specialized (|delete|-based) version compiles for that type but does the + * wrong thing, bad things could happen. + * + * This is a non-issue for types which are always incomplete (i.e. opaque handle + * types), since |delete|-ing such a type will always trigger a compilation + * error. + */ +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct DefaultDelete { + pub _phantom0: ::std::marker::PhantomData, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct UniqueSelector { + pub _phantom0: ::std::marker::PhantomData, +} /** * typedefs for backwards compatibility */ @@ -2682,6 +2735,12 @@ impl ::std::clone::Clone for nsIExpandedPrincipal { fn clone(&self) -> Self { *self } } #[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _Make_integer_sequence<_Tp, _ISeq> { + pub _phantom0: ::std::marker::PhantomData<_Tp>, + pub _phantom1: ::std::marker::PhantomData<_ISeq>, +} +#[repr(C)] #[derive(Debug, Copy)] pub struct nsIURI { pub _base: nsISupports, @@ -2733,7 +2792,7 @@ impl ::std::clone::Clone for nsIRequest { #[repr(C)] #[derive(Debug, Copy)] pub struct EventStates { - pub mStates: ::std::os::raw::c_ulonglong, + pub mStates: ::std::os::raw::c_ulong, } impl ::std::clone::Clone for EventStates { fn clone(&self) -> Self { *self } @@ -2797,11 +2856,6 @@ pub enum nsNodeSupportsWeakRefTearoff { } pub enum nsNodeWeakReference { } pub enum nsDOMMutationObserver { } pub enum ServoNodeData { } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct DefaultDelete<> { - pub _phantom0: ::std::marker::PhantomData, -} pub enum EventListenerManager { } pub enum BoxQuadOptions { } pub enum ConvertCoordinateOptions { } @@ -2868,7 +2922,7 @@ fn bindgen_test_layout_nsMutationGuard() { extern "C" { #[link_name = "_ZN15nsMutationGuard11sGenerationE"] pub static mut nsMutationGuard_consts_sGeneration: - ::std::os::raw::c_ulonglong; + ::std::os::raw::c_ulong; } pub type Float = f32; #[repr(i8)] @@ -3259,7 +3313,7 @@ pub type nscolor = u32; #[repr(i8)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum nsHexColorType { NoAlpha = 0, AllowAlpha = 1, } -pub enum nsStyledElementNotElementCSSInlineStyle { } +pub enum nsStyledElement { } pub enum MiscContainer { } pub enum ServoDeclarationBlock { } pub enum Declaration { } @@ -3470,12 +3524,7 @@ fn bindgen_test_layout_ServoAttrSnapshot() { */ #[repr(i8)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum ServoElementSnapshotFlags { - State = 1, - Attributes = 2, - HTMLElementInHTMLDocument = 4, - All = 7, -} +pub enum ServoElementSnapshotFlags { State = 1, Attributes = 2, All = 3, } /** * This class holds all non-tree-structural state of an element that might be * used for selector matching eventually. @@ -3492,6 +3541,7 @@ pub struct ServoElementSnapshot { pub mExplicitRestyleHint: nsRestyleHint, pub mExplicitChangeHint: nsChangeHint, pub mIsHTMLElementInHTMLDocument: bool, + pub mIsInChromeDocument: bool, } #[test] fn bindgen_test_layout_ServoElementSnapshot() { @@ -5341,6 +5391,16 @@ pub enum nsStyleImageType { eStyleImageType_Gradient = 2, eStyleImageType_Element = 3, } +#[repr(C)] +pub struct CachedBorderImageData { + pub mCachedSVGViewportSize: [u64; 2usize], + pub mSubImages: u64, +} +#[test] +fn bindgen_test_layout_CachedBorderImageData() { + assert_eq!(::std::mem::size_of::() , 24usize); + assert_eq!(::std::mem::align_of::() , 8usize); +} /** * Represents a paintable image of one of the following types. * (1) A real image loaded from an external source. @@ -5353,10 +5413,11 @@ pub enum nsStyleImageType { */ #[repr(C)] pub struct nsStyleImage { - pub mSubImages: u64, + pub mCachedBIData: UniquePtr>, pub mType: nsStyleImageType, pub nsStyleImage_nsStyleStruct_h_unnamed_21: nsStyleImage_nsStyleStruct_h_unnamed_21, - pub mCropRect: nsAutoPtr, + pub mCropRect: UniquePtr>, } #[repr(C)] #[derive(Debug, Copy)] @@ -6238,6 +6299,17 @@ extern "C" { #[link_name = "_ZN13nsStyleColumn15kMaxColumnCountE"] pub static nsStyleColumn_consts_kMaxColumnCount: ::std::os::raw::c_uint; } +#[repr(C)] +#[derive(Debug)] +pub struct FragmentOrURL { + pub mURL: nsCOMPtr, + pub mIsLocalRef: bool, +} +#[test] +fn bindgen_test_layout_FragmentOrURL() { + assert_eq!(::std::mem::size_of::() , 16usize); + assert_eq!(::std::mem::align_of::() , 8usize); +} #[repr(u32)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum nsStyleSVGPaintType { @@ -6265,7 +6337,7 @@ pub struct nsStyleSVGPaint { #[derive(Debug, Copy)] pub struct nsStyleSVGPaint_nsStyleStruct_h_unnamed_27 { pub mColor: __BindgenUnionField, - pub mPaintServer: __BindgenUnionField<*mut nsIURI>, + pub mPaintServer: __BindgenUnionField<*mut FragmentOrURL>, pub _bindgen_data_: u64, } impl nsStyleSVGPaint_nsStyleStruct_h_unnamed_27 { } @@ -6289,9 +6361,9 @@ fn bindgen_test_layout_nsStyleSVGPaint() { pub struct nsStyleSVG { pub mFill: nsStyleSVGPaint, pub mStroke: nsStyleSVGPaint, - pub mMarkerEnd: nsCOMPtr, - pub mMarkerMid: nsCOMPtr, - pub mMarkerStart: nsCOMPtr, + pub mMarkerEnd: FragmentOrURL, + pub mMarkerMid: FragmentOrURL, + pub mMarkerStart: FragmentOrURL, pub mStrokeDasharray: nsTArray, pub mStrokeDashoffset: nsStyleCoord, pub mStrokeWidth: nsStyleCoord, @@ -6322,7 +6394,7 @@ pub enum nsStyleSVG_nsStyleStruct_h_unnamed_28 { } #[test] fn bindgen_test_layout_nsStyleSVG() { - assert_eq!(::std::mem::size_of::() , 120usize); + assert_eq!(::std::mem::size_of::() , 144usize); assert_eq!(::std::mem::align_of::() , 8usize); } #[repr(C)] @@ -6360,7 +6432,7 @@ pub struct nsStyleClipPath { #[derive(Debug, Copy)] pub struct nsStyleClipPath_nsStyleStruct_h_unnamed_29 { pub mBasicShape: __BindgenUnionField<*mut nsStyleBasicShape>, - pub mURL: __BindgenUnionField<*mut nsIURI>, + pub mURL: __BindgenUnionField<*mut FragmentOrURL>, pub _bindgen_data_: u64, } impl nsStyleClipPath_nsStyleStruct_h_unnamed_29 { } @@ -6389,7 +6461,7 @@ pub struct nsStyleFilter { #[repr(C)] #[derive(Debug, Copy)] pub struct nsStyleFilter_nsStyleStruct_h_unnamed_30 { - pub mURL: __BindgenUnionField<*mut nsIURI>, + pub mURL: __BindgenUnionField<*mut FragmentOrURL>, pub mDropShadow: __BindgenUnionField<*mut nsCSSShadowArray>, pub _bindgen_data_: u64, } @@ -6451,3 +6523,20 @@ fn bindgen_test_layout_nsStyleEffects() { assert_eq!(::std::mem::size_of::() , 40usize); assert_eq!(::std::mem::align_of::() , 8usize); } +/** + *
+ */ +#[repr(C)] +#[derive(Debug, Copy)] +pub struct nsSize { + pub width: nscoord, + pub height: nscoord, +} +impl ::std::clone::Clone for nsSize { + fn clone(&self) -> Self { *self } +} +#[test] +fn bindgen_test_layout_nsSize() { + assert_eq!(::std::mem::size_of::() , 8usize); + assert_eq!(::std::mem::align_of::() , 4usize); +} diff --git a/ports/geckolib/gecko_bindings/tools/regen.py b/ports/geckolib/gecko_bindings/tools/regen.py index 534acbeb146..653213f848d 100755 --- a/ports/geckolib/gecko_bindings/tools/regen.py +++ b/ports/geckolib/gecko_bindings/tools/regen.py @@ -80,6 +80,7 @@ COMPILATION_TARGETS = { "/Types.h", # <- Disallow UnionTypes.h "/utility", # <- Disallow xutility "nsINode.h", # <- For `NodeFlags`. + "UniquePtr.h" ], "blacklist": [ "IsDestructibleFallbackImpl", "IsDestructibleFallback", @@ -90,13 +91,17 @@ COMPILATION_TARGETS = { "FastAnimationEffectTimingProperties", "ComputedTimingProperties", "FastComputedTimingProperties", "nsINode", + "HasPointerType" ], "opaque_types": [ "nsIntMargin", "nsIntPoint", "nsIntRect", "nsCOMArray", "nsDependentString", "EntryStore", "gfxFontFeatureValueSet", "imgRequestProxy", "imgRequestProxyStatic", "CounterStyleManager", "ImageValue", "URLValue", "URLValueData", "nsIPrincipal", - "nsDataHashtable", "imgIRequest" + "nsDataHashtable", "imgIRequest", + "Maybe", # <- AlignedStorage, which means templated union, which + # means impossible to represent in stable rust as of + # right now. ], }, # Generation of the ffi bindings.