servo: Merge #12645 - stylo: Allow computing change hints during the traversal (from emilio:stylo); r=bholley

<!-- Please describe your changes on the following line: -->

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors

<!-- Either: -->
- [x] These changes do not require tests because geckolib :-(

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

r? @bholley
cc @heycam

Source-Repo: https://github.com/servo/servo
Source-Revision: cbf71a2cf39e792f75309e68f7cabe862d4a70eb
This commit is contained in:
Emilio Cobos Álvarez 2016-08-03 19:02:26 -05:00
parent 6b750f0509
commit 923c16c719
19 changed files with 446 additions and 100 deletions

View File

@ -13,6 +13,7 @@ matrix:
script: script:
- ./mach build -d --verbose - ./mach build -d --verbose
- ./mach build-geckolib - ./mach build-geckolib
- ./mach test-geckolib
- ./mach test-unit - ./mach test-unit
- ./mach test-compiletest - ./mach test-compiletest
- bash etc/ci/check_no_unwrap.sh - bash etc/ci/check_no_unwrap.sh

View File

@ -14,6 +14,7 @@ use script_traits::{AnimationState, LayoutMsg as ConstellationMsg};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::mpsc::Receiver; use std::sync::mpsc::Receiver;
use style::animation::{Animation, update_style_for_animation}; use style::animation::{Animation, update_style_for_animation};
use style::dom::TRestyleDamage;
use style::timer::Timer; use style::timer::Timer;
/// Processes any new animations that were discovered after style recalculation. /// 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| { flow.mutate_fragments(&mut |fragment| {
if let Some(ref animations) = animations.get(&fragment.node) { if let Some(ref animations) = animations.get(&fragment.node) {
for animation in animations.iter() { for animation in animations.iter() {
let old_style = fragment.style.clone();
update_style_for_animation(&context.style_context, update_style_for_animation(&context.style_context,
animation, animation,
&mut fragment.style, &mut fragment.style);
Some(&mut damage)); damage |= RestyleDamage::compute(Some(&old_style), &fragment.style);
} }
} }
}); });

View File

@ -51,6 +51,7 @@ use selectors::matching::{DeclarationBlock, ElementFlags};
use selectors::parser::{AttrSelector, NamespaceConstraint}; use selectors::parser::{AttrSelector, NamespaceConstraint};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::mem::{transmute, transmute_copy}; use std::mem::{transmute, transmute_copy};
use std::sync::Arc;
use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace}; use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace};
use style::attr::AttrValue; use style::attr::AttrValue;
use style::computed_values::display; use style::computed_values::display;
@ -58,7 +59,7 @@ use style::context::SharedStyleContext;
use style::data::PrivateStyleData; use style::data::PrivateStyleData;
use style::dom::{PresentationalHintsSynthetizer, OpaqueNode, TDocument, TElement, TNode, UnsafeNode}; use style::dom::{PresentationalHintsSynthetizer, OpaqueNode, TDocument, TElement, TNode, UnsafeNode};
use style::element_state::*; use style::element_state::*;
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock}; use style::properties::{ComputedValues, PropertyDeclaration, PropertyDeclarationBlock};
use style::refcell::{Ref, RefCell, RefMut}; use style::refcell::{Ref, RefCell, RefMut};
use style::selector_impl::{ElementSnapshot, NonTSPseudoClass, ServoSelectorImpl}; use style::selector_impl::{ElementSnapshot, NonTSPseudoClass, ServoSelectorImpl};
use style::sink::Push; 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)) 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<ComputedValues>>)
-> Option<&'a Arc<ComputedValues>> {
current_cv
}
} }
impl<'ln> LayoutNode for ServoLayoutNode<'ln> { impl<'ln> LayoutNode for ServoLayoutNode<'ln> {

View File

@ -44,21 +44,28 @@ bitflags! {
} }
impl TRestyleDamage for RestyleDamage { impl TRestyleDamage for RestyleDamage {
fn compute(old: Option<&Arc<ServoComputedValues>>, new: &ServoComputedValues) -> /// For Servo the style source is always the computed values.
RestyleDamage { compute_damage(old, new) } type PreExistingComputedValues = Arc<ServoComputedValues>;
/// Returns a bitmask that represents a flow that needs to be rebuilt and reflowed. fn compute(old: Option<&Arc<ServoComputedValues>>,
new: &Arc<ServoComputedValues>) -> 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 /// Use this instead of `RestyleDamage::all()` because
/// unnecessary sequential resolution of generated content. /// `RestyleDamage::all()` will result in unnecessary sequential resolution
/// of generated content.
fn rebuild_and_reflow() -> RestyleDamage { fn rebuild_and_reflow() -> RestyleDamage {
REPAINT | STORE_OVERFLOW | BUBBLE_ISIZES | REFLOW_OUT_OF_FLOW | REFLOW | RECONSTRUCT_FLOW REPAINT | STORE_OVERFLOW | BUBBLE_ISIZES | REFLOW_OUT_OF_FLOW | REFLOW | RECONSTRUCT_FLOW
} }
} }
impl RestyleDamage { impl RestyleDamage {
/// Supposing a flow has the given `position` property and this damage, returns the damage that /// Supposing a flow has the given `position` property and this damage,
/// we should add to the *parent* of this flow. /// 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 { pub fn damage_for_parent(self, child_is_absolutely_positioned: bool) -> RestyleDamage {
if child_is_absolutely_positioned { if child_is_absolutely_positioned {
self & (REPAINT | STORE_OVERFLOW | REFLOW_OUT_OF_FLOW | RESOLVE_GENERATED_CONTENT) self & (REPAINT | STORE_OVERFLOW | REFLOW_OUT_OF_FLOW | RESOLVE_GENERATED_CONTENT)
@ -143,7 +150,8 @@ macro_rules! add_if_not_equal(
}) })
); );
fn compute_damage(old: Option<&Arc<ServoComputedValues>>, new: &ServoComputedValues) -> RestyleDamage { fn compute_damage(old: Option<&Arc<ServoComputedValues>>, new: &Arc<ServoComputedValues>) -> RestyleDamage {
let new = &**new;
let old: &ServoComputedValues = match old { let old: &ServoComputedValues = match old {
None => return RestyleDamage::rebuild_and_reflow(), None => return RestyleDamage::rebuild_and_reflow(),
Some(cv) => &**cv, Some(cv) => &**cv,

View File

@ -6,7 +6,7 @@
use bezier::Bezier; use bezier::Bezier;
use context::SharedStyleContext; use context::SharedStyleContext;
use dom::{OpaqueNode, TRestyleDamage}; use dom::OpaqueNode;
use euclid::point::Point2D; use euclid::point::Point2D;
use keyframes::{KeyframesStep, KeyframesStepValue}; use keyframes::{KeyframesStep, KeyframesStepValue};
use properties::animated_properties::{AnimatedProperty, TransitionProperty}; use properties::animated_properties::{AnimatedProperty, TransitionProperty};
@ -490,13 +490,12 @@ pub fn update_style_for_animation_frame(mut new_style: &mut Arc<ComputedValues>,
} }
/// Updates a single animation and associated style based on the current time. /// Updates a single animation and associated style based on the current time.
/// If `damage` is provided, inserts the appropriate restyle damage. /// If `damage` is provided, inserts the appropriate restyle damage.
pub fn update_style_for_animation<Damage>(context: &SharedStyleContext, pub fn update_style_for_animation(context: &SharedStyleContext,
animation: &Animation, animation: &Animation,
style: &mut Arc<ComputedValues>, style: &mut Arc<ComputedValues>) {
damage: Option<&mut Damage>)
where Damage: TRestyleDamage {
debug!("update_style_for_animation: entering"); debug!("update_style_for_animation: entering");
debug_assert!(!animation.is_expired()); debug_assert!(!animation.is_expired());
match *animation { match *animation {
Animation::Transition(_, start_time, ref frame, _) => { Animation::Transition(_, start_time, ref frame, _) => {
debug!("update_style_for_animation: transition found"); debug!("update_style_for_animation: transition found");
@ -506,10 +505,6 @@ where Damage: TRestyleDamage {
now, start_time, now, start_time,
frame); frame);
if updated_style { if updated_style {
if let Some(damage) = damage {
*damage = *damage | Damage::compute(Some(style), &new_style);
}
*style = new_style *style = new_style
} }
} }
@ -660,10 +655,6 @@ where Damage: TRestyleDamage {
} }
debug!("update_style_for_animation: got style change in animation \"{}\"", name); 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; *style = new_style;
} }
} }

View File

@ -46,7 +46,19 @@ impl OpaqueNode {
} }
pub trait TRestyleDamage : BitOr<Output=Self> + Copy { pub trait TRestyleDamage : BitOr<Output=Self> + Copy {
fn compute(old: Option<&Arc<ComputedValues>>, new: &ComputedValues) -> 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<ComputedValues>) -> Self;
fn rebuild_and_reflow() -> Self; fn rebuild_and_reflow() -> Self;
} }
@ -159,6 +171,13 @@ pub trait TNode : Sized + Copy + Clone {
fn unstyle(self) { fn unstyle(self) {
self.mutate_data().unwrap().style = None; 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<ComputedValues>>)
-> Option<&'a <Self::ConcreteRestyleDamage as TRestyleDamage>::PreExistingComputedValues>;
} }
pub trait TDocument : Sized + Copy + Clone { pub trait TDocument : Sized + Copy + Clone {

View File

@ -13,7 +13,6 @@ pub struct ArcHelpers<GeckoType, ServoType> {
phantom2: PhantomData<ServoType>, phantom2: PhantomData<ServoType>,
} }
impl<GeckoType, ServoType> ArcHelpers<GeckoType, ServoType> { impl<GeckoType, ServoType> ArcHelpers<GeckoType, ServoType> {
pub fn with<F, Output>(raw: *mut GeckoType, cb: F) -> Output pub fn with<F, Output>(raw: *mut GeckoType, cb: F) -> Output
where F: FnOnce(&Arc<ServoType>) -> Output { where F: FnOnce(&Arc<ServoType>) -> Output {
@ -47,6 +46,15 @@ impl<GeckoType, ServoType> ArcHelpers<GeckoType, ServoType> {
unsafe { transmute(owned) } unsafe { transmute(owned) }
} }
pub fn borrow<F, Output>(borrowed: &Arc<ServoType>, 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) { pub unsafe fn addref(ptr: *mut GeckoType) {
Self::with(ptr, |arc| forget(arc.clone())); Self::with(ptr, |arc| forget(arc.clone()));
} }

View File

@ -6,7 +6,7 @@
#![allow(unsafe_code)] #![allow(unsafe_code)]
use animation::{self, Animation}; use animation;
use arc_ptr_eq; use arc_ptr_eq;
use cache::{LRUCache, SimpleHashCache}; use cache::{LRUCache, SimpleHashCache};
use context::{StyleContext, SharedStyleContext}; use context::{StyleContext, SharedStyleContext};
@ -442,8 +442,13 @@ trait PrivateMatchMethods: TNode
cacheable = cacheable && !animations_started cacheable = cacheable && !animations_started
} }
let existing_style =
self.existing_style_for_restyle_damage(style.map(|s| &*s));
// Calculate style difference. // 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. // Cache the resolved style if it was cacheable.
if cacheable { if cacheable {
@ -490,8 +495,9 @@ trait PrivateMatchMethods: TNode
// See #12171 and the associated PR for an example where this // See #12171 and the associated PR for an example where this
// happened while debugging other release panic. // happened while debugging other release panic.
if !running_animation.is_expired() { if !running_animation.is_expired() {
animation::update_style_for_animation::<Self::ConcreteRestyleDamage>( animation::update_style_for_animation(context,
context, running_animation, style, None); running_animation,
style);
running_animation.mark_as_expired(); 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) { if let Some(shared_style) = self.share_style_with_candidate_if_possible(parent.clone(), candidate) {
// Yay, cache hit. Share the style. // Yay, cache hit. Share the style.
let node = self.as_node(); let node = self.as_node();
let style = &mut node.mutate_data().unwrap().style; let style = &mut node.mutate_data().unwrap().style;
let damage = <<Self as TElement>::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 = <<Self as TElement>::ConcreteNode as TNode>
::ConcreteRestyleDamage::compute(source, &shared_style);
damage
};
*style = Some(shared_style); *style = Some(shared_style);
return StyleSharingResult::StyleWasShared(i, damage) return StyleSharingResult::StyleWasShared(i, damage)
} }
@ -675,8 +689,14 @@ pub trait MatchMethods : TNode {
let mut data_ref = self.mutate_data().unwrap(); let mut data_ref = self.mutate_data().unwrap();
let mut data = &mut *data_ref; let mut data = &mut *data_ref;
let cloned_parent_style = ComputedValues::style_for_child_text_node(parent_style.unwrap()); 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); data.style = Some(cloned_parent_style);
} else { } else {
damage = { damage = {
@ -697,7 +717,6 @@ pub trait MatchMethods : TNode {
let applicable_declarations_for_this_pseudo = let applicable_declarations_for_this_pseudo =
applicable_declarations.per_pseudo.get(&pseudo).unwrap(); applicable_declarations.per_pseudo.get(&pseudo).unwrap();
if !applicable_declarations_for_this_pseudo.is_empty() { if !applicable_declarations_for_this_pseudo.is_empty() {
// NB: Transitions and animations should only work for // NB: Transitions and animations should only work for
// pseudo-elements ::before and ::after // pseudo-elements ::before and ::after

View File

@ -28,7 +28,7 @@ bitflags! {
// of a good reason for that. // of a good reason for that.
const RESTYLE_DESCENDANTS = 0x02, const RESTYLE_DESCENDANTS = 0x02,
#[doc = "Rerun selector matching on all later siblings of the element and all of their descendants."] #[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,
} }
} }

View File

@ -21,7 +21,7 @@ pub fn traverse_dom<N, C>(root: N,
for kid in node.children() { for kid in node.children() {
context.pre_process_child_hook(node, kid); context.pre_process_child_hook(node, kid);
if context.should_process(node) { if context.should_process(kid) {
doit::<N, C>(context, kid); doit::<N, C>(context, kid);
} }
} }

View File

@ -12,7 +12,6 @@ use selector_impl::SelectorImplExt;
use selectors::Element; use selectors::Element;
use selectors::bloom::BloomFilter; use selectors::bloom::BloomFilter;
use std::cell::RefCell; use std::cell::RefCell;
use std::sync::Arc;
use tid::tid; use tid::tid;
use util::opts; use util::opts;
use values::HasViewportPercentage; use values::HasViewportPercentage;

View File

@ -144,6 +144,10 @@ use structs::nsFont;
use structs::FontFamilyList; use structs::FontFamilyList;
use structs::FontFamilyType; use structs::FontFamilyType;
use structs::nsIAtom; 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 type RawGeckoNode = nsINode;
pub enum Element { } pub enum Element { }
@ -294,10 +298,13 @@ extern "C" {
pub fn Gecko_GetNodeFlags(node: *mut RawGeckoNode) -> u32; pub fn Gecko_GetNodeFlags(node: *mut RawGeckoNode) -> u32;
pub fn Gecko_SetNodeFlags(node: *mut RawGeckoNode, flags: u32); pub fn Gecko_SetNodeFlags(node: *mut RawGeckoNode, flags: u32);
pub fn Gecko_UnsetNodeFlags(node: *mut RawGeckoNode, flags: u32); pub fn Gecko_UnsetNodeFlags(node: *mut RawGeckoNode, flags: u32);
pub fn Gecko_CalcAndStoreStyleDifference(element: *mut RawGeckoElement, pub fn Gecko_GetStyleContext(node: *mut RawGeckoNode)
newstyle: -> *mut nsStyleContext;
*mut ServoComputedValues) pub fn Gecko_CalcStyleDifference(oldstyle: *mut nsStyleContext,
newstyle: *mut ServoComputedValues)
-> nsChangeHint; -> nsChangeHint;
pub fn Gecko_StoreStyleDifference(node: *mut RawGeckoNode,
change: nsChangeHint);
pub fn Gecko_EnsureTArrayCapacity(array: *mut ::std::os::raw::c_void, pub fn Gecko_EnsureTArrayCapacity(array: *mut ::std::os::raw::c_void,
capacity: usize, elem_size: usize); capacity: usize, elem_size: usize);
pub fn Gecko_EnsureImageLayersLength(layers: *mut nsStyleImageLayers, pub fn Gecko_EnsureImageLayersLength(layers: *mut nsStyleImageLayers,

View File

@ -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 MOZ_STRING_WITH_OBSOLETE_API: ::std::os::raw::c_uint = 1;
pub const NSID_LENGTH: ::std::os::raw::c_uint = 39; 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 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 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 DOM_USER_DATA: ::std::os::raw::c_uint = 1;
pub const SMIL_MAPPED_ATTR_ANIMVAL: ::std::os::raw::c_uint = 2; 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, NS_OK_NO_NAME_CLAUSE_HANDLED = 7864354,
} }
pub type nsrefcnt = MozRefCountType; 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<T, D> {
pub _phantom0: ::std::marker::PhantomData<T>,
pub _phantom1: ::std::marker::PhantomData<D>,
}
/**
* <div rustbindgen="true" replaces="UniquePtr">
*
* 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<T, Deleter> {
pub mPtr: *mut T,
pub _phantom0: ::std::marker::PhantomData<Deleter>,
}
/**
* 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<T> {
pub _phantom0: ::std::marker::PhantomData<T>,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct UniqueSelector<T> {
pub _phantom0: ::std::marker::PhantomData<T>,
}
/** /**
* typedefs for backwards compatibility * typedefs for backwards compatibility
*/ */
@ -2703,6 +2756,12 @@ impl ::std::clone::Clone for nsIExpandedPrincipal {
fn clone(&self) -> Self { *self } fn clone(&self) -> Self { *self }
} }
#[repr(C)] #[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)] #[derive(Debug, Copy)]
pub struct nsIURI { pub struct nsIURI {
pub _base: nsISupports, pub _base: nsISupports,
@ -2754,7 +2813,7 @@ impl ::std::clone::Clone for nsIRequest {
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy)] #[derive(Debug, Copy)]
pub struct EventStates { pub struct EventStates {
pub mStates: ::std::os::raw::c_ulonglong, pub mStates: ::std::os::raw::c_ulong,
} }
impl ::std::clone::Clone for EventStates { impl ::std::clone::Clone for EventStates {
fn clone(&self) -> Self { *self } fn clone(&self) -> Self { *self }
@ -2818,11 +2877,6 @@ pub enum nsNodeSupportsWeakRefTearoff { }
pub enum nsNodeWeakReference { } pub enum nsNodeWeakReference { }
pub enum nsDOMMutationObserver { } pub enum nsDOMMutationObserver { }
pub enum ServoNodeData { } pub enum ServoNodeData { }
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct DefaultDelete<> {
pub _phantom0: ::std::marker::PhantomData<ServoNodeData>,
}
pub enum EventListenerManager { } pub enum EventListenerManager { }
pub enum BoxQuadOptions { } pub enum BoxQuadOptions { }
pub enum ConvertCoordinateOptions { } pub enum ConvertCoordinateOptions { }
@ -2889,7 +2943,7 @@ fn bindgen_test_layout_nsMutationGuard() {
extern "C" { extern "C" {
#[link_name = "_ZN15nsMutationGuard11sGenerationE"] #[link_name = "_ZN15nsMutationGuard11sGenerationE"]
pub static mut nsMutationGuard_consts_sGeneration: pub static mut nsMutationGuard_consts_sGeneration:
::std::os::raw::c_ulonglong; ::std::os::raw::c_ulong;
} }
pub type Float = f32; pub type Float = f32;
#[repr(i8)] #[repr(i8)]
@ -3280,7 +3334,7 @@ pub type nscolor = u32;
#[repr(i8)] #[repr(i8)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum nsHexColorType { NoAlpha = 0, AllowAlpha = 1, } pub enum nsHexColorType { NoAlpha = 0, AllowAlpha = 1, }
pub enum nsStyledElementNotElementCSSInlineStyle { } pub enum nsStyledElement { }
pub enum MiscContainer { } pub enum MiscContainer { }
pub enum ServoDeclarationBlock { } pub enum ServoDeclarationBlock { }
pub enum Declaration { } pub enum Declaration { }
@ -3491,12 +3545,7 @@ fn bindgen_test_layout_ServoAttrSnapshot() {
*/ */
#[repr(i8)] #[repr(i8)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum ServoElementSnapshotFlags { pub enum ServoElementSnapshotFlags { State = 1, Attributes = 2, All = 3, }
State = 1,
Attributes = 2,
HTMLElementInHTMLDocument = 4,
All = 7,
}
/** /**
* This class holds all non-tree-structural state of an element that might be * This class holds all non-tree-structural state of an element that might be
* used for selector matching eventually. * used for selector matching eventually.
@ -3513,6 +3562,7 @@ pub struct ServoElementSnapshot {
pub mExplicitRestyleHint: nsRestyleHint, pub mExplicitRestyleHint: nsRestyleHint,
pub mExplicitChangeHint: nsChangeHint, pub mExplicitChangeHint: nsChangeHint,
pub mIsHTMLElementInHTMLDocument: bool, pub mIsHTMLElementInHTMLDocument: bool,
pub mIsInChromeDocument: bool,
} }
#[test] #[test]
fn bindgen_test_layout_ServoElementSnapshot() { fn bindgen_test_layout_ServoElementSnapshot() {
@ -5362,6 +5412,16 @@ pub enum nsStyleImageType {
eStyleImageType_Gradient = 2, eStyleImageType_Gradient = 2,
eStyleImageType_Element = 3, 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::<CachedBorderImageData>() , 24usize);
assert_eq!(::std::mem::align_of::<CachedBorderImageData>() , 8usize);
}
/** /**
* Represents a paintable image of one of the following types. * Represents a paintable image of one of the following types.
* (1) A real image loaded from an external source. * (1) A real image loaded from an external source.
@ -5374,10 +5434,11 @@ pub enum nsStyleImageType {
*/ */
#[repr(C)] #[repr(C)]
pub struct nsStyleImage { pub struct nsStyleImage {
pub mSubImages: u64, pub mCachedBIData: UniquePtr<CachedBorderImageData,
DefaultDelete<CachedBorderImageData>>,
pub mType: nsStyleImageType, pub mType: nsStyleImageType,
pub nsStyleImage_nsStyleStruct_h_unnamed_21: nsStyleImage_nsStyleStruct_h_unnamed_21, pub nsStyleImage_nsStyleStruct_h_unnamed_21: nsStyleImage_nsStyleStruct_h_unnamed_21,
pub mCropRect: nsAutoPtr<nsStyleSides>, pub mCropRect: UniquePtr<nsStyleSides, DefaultDelete<nsStyleSides>>,
pub mImageTracked: bool, pub mImageTracked: bool,
} }
#[repr(C)] #[repr(C)]
@ -6261,6 +6322,17 @@ extern "C" {
#[link_name = "_ZN13nsStyleColumn15kMaxColumnCountE"] #[link_name = "_ZN13nsStyleColumn15kMaxColumnCountE"]
pub static nsStyleColumn_consts_kMaxColumnCount: ::std::os::raw::c_uint; pub static nsStyleColumn_consts_kMaxColumnCount: ::std::os::raw::c_uint;
} }
#[repr(C)]
#[derive(Debug)]
pub struct FragmentOrURL {
pub mURL: nsCOMPtr<nsIURI>,
pub mIsLocalRef: bool,
}
#[test]
fn bindgen_test_layout_FragmentOrURL() {
assert_eq!(::std::mem::size_of::<FragmentOrURL>() , 16usize);
assert_eq!(::std::mem::align_of::<FragmentOrURL>() , 8usize);
}
#[repr(u32)] #[repr(u32)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum nsStyleSVGPaintType { pub enum nsStyleSVGPaintType {
@ -6288,7 +6360,7 @@ pub struct nsStyleSVGPaint {
#[derive(Debug, Copy)] #[derive(Debug, Copy)]
pub struct nsStyleSVGPaint_nsStyleStruct_h_unnamed_27 { pub struct nsStyleSVGPaint_nsStyleStruct_h_unnamed_27 {
pub mColor: __BindgenUnionField<nscolor>, pub mColor: __BindgenUnionField<nscolor>,
pub mPaintServer: __BindgenUnionField<*mut nsIURI>, pub mPaintServer: __BindgenUnionField<*mut FragmentOrURL>,
pub _bindgen_data_: u64, pub _bindgen_data_: u64,
} }
impl nsStyleSVGPaint_nsStyleStruct_h_unnamed_27 { } impl nsStyleSVGPaint_nsStyleStruct_h_unnamed_27 { }
@ -6312,9 +6384,9 @@ fn bindgen_test_layout_nsStyleSVGPaint() {
pub struct nsStyleSVG { pub struct nsStyleSVG {
pub mFill: nsStyleSVGPaint, pub mFill: nsStyleSVGPaint,
pub mStroke: nsStyleSVGPaint, pub mStroke: nsStyleSVGPaint,
pub mMarkerEnd: nsCOMPtr<nsIURI>, pub mMarkerEnd: FragmentOrURL,
pub mMarkerMid: nsCOMPtr<nsIURI>, pub mMarkerMid: FragmentOrURL,
pub mMarkerStart: nsCOMPtr<nsIURI>, pub mMarkerStart: FragmentOrURL,
pub mStrokeDasharray: nsTArray<nsStyleCoord>, pub mStrokeDasharray: nsTArray<nsStyleCoord>,
pub mStrokeDashoffset: nsStyleCoord, pub mStrokeDashoffset: nsStyleCoord,
pub mStrokeWidth: nsStyleCoord, pub mStrokeWidth: nsStyleCoord,
@ -6345,7 +6417,7 @@ pub enum nsStyleSVG_nsStyleStruct_h_unnamed_28 {
} }
#[test] #[test]
fn bindgen_test_layout_nsStyleSVG() { fn bindgen_test_layout_nsStyleSVG() {
assert_eq!(::std::mem::size_of::<nsStyleSVG>() , 120usize); assert_eq!(::std::mem::size_of::<nsStyleSVG>() , 144usize);
assert_eq!(::std::mem::align_of::<nsStyleSVG>() , 8usize); assert_eq!(::std::mem::align_of::<nsStyleSVG>() , 8usize);
} }
#[repr(C)] #[repr(C)]
@ -6383,7 +6455,7 @@ pub struct nsStyleClipPath {
#[derive(Debug, Copy)] #[derive(Debug, Copy)]
pub struct nsStyleClipPath_nsStyleStruct_h_unnamed_29 { pub struct nsStyleClipPath_nsStyleStruct_h_unnamed_29 {
pub mBasicShape: __BindgenUnionField<*mut nsStyleBasicShape>, pub mBasicShape: __BindgenUnionField<*mut nsStyleBasicShape>,
pub mURL: __BindgenUnionField<*mut nsIURI>, pub mURL: __BindgenUnionField<*mut FragmentOrURL>,
pub _bindgen_data_: u64, pub _bindgen_data_: u64,
} }
impl nsStyleClipPath_nsStyleStruct_h_unnamed_29 { } impl nsStyleClipPath_nsStyleStruct_h_unnamed_29 { }
@ -6412,7 +6484,7 @@ pub struct nsStyleFilter {
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy)] #[derive(Debug, Copy)]
pub struct nsStyleFilter_nsStyleStruct_h_unnamed_30 { pub struct nsStyleFilter_nsStyleStruct_h_unnamed_30 {
pub mURL: __BindgenUnionField<*mut nsIURI>, pub mURL: __BindgenUnionField<*mut FragmentOrURL>,
pub mDropShadow: __BindgenUnionField<*mut nsCSSShadowArray>, pub mDropShadow: __BindgenUnionField<*mut nsCSSShadowArray>,
pub _bindgen_data_: u64, pub _bindgen_data_: u64,
} }
@ -6474,3 +6546,20 @@ fn bindgen_test_layout_nsStyleEffects() {
assert_eq!(::std::mem::size_of::<nsStyleEffects>() , 40usize); assert_eq!(::std::mem::size_of::<nsStyleEffects>() , 40usize);
assert_eq!(::std::mem::align_of::<nsStyleEffects>() , 8usize); assert_eq!(::std::mem::align_of::<nsStyleEffects>() , 8usize);
} }
/**
* <div rustbindgen="true" replaces="nsSize">
*/
#[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::<nsSize>() , 8usize);
assert_eq!(::std::mem::align_of::<nsSize>() , 4usize);
}

View File

@ -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 MOZ_STRING_WITH_OBSOLETE_API: ::std::os::raw::c_uint = 1;
pub const NSID_LENGTH: ::std::os::raw::c_uint = 39; 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 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 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 DOM_USER_DATA: ::std::os::raw::c_uint = 1;
pub const SMIL_MAPPED_ATTR_ANIMVAL: ::std::os::raw::c_uint = 2; 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, NS_OK_NO_NAME_CLAUSE_HANDLED = 7864354,
} }
pub type nsrefcnt = MozRefCountType; 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<T, D> {
pub _phantom0: ::std::marker::PhantomData<T>,
pub _phantom1: ::std::marker::PhantomData<D>,
}
/**
* <div rustbindgen="true" replaces="UniquePtr">
*
* 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<T, Deleter> {
pub mPtr: *mut T,
pub _phantom0: ::std::marker::PhantomData<Deleter>,
}
/**
* 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<T> {
pub _phantom0: ::std::marker::PhantomData<T>,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct UniqueSelector<T> {
pub _phantom0: ::std::marker::PhantomData<T>,
}
/** /**
* typedefs for backwards compatibility * typedefs for backwards compatibility
*/ */
@ -2682,6 +2735,12 @@ impl ::std::clone::Clone for nsIExpandedPrincipal {
fn clone(&self) -> Self { *self } fn clone(&self) -> Self { *self }
} }
#[repr(C)] #[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)] #[derive(Debug, Copy)]
pub struct nsIURI { pub struct nsIURI {
pub _base: nsISupports, pub _base: nsISupports,
@ -2733,7 +2792,7 @@ impl ::std::clone::Clone for nsIRequest {
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy)] #[derive(Debug, Copy)]
pub struct EventStates { pub struct EventStates {
pub mStates: ::std::os::raw::c_ulonglong, pub mStates: ::std::os::raw::c_ulong,
} }
impl ::std::clone::Clone for EventStates { impl ::std::clone::Clone for EventStates {
fn clone(&self) -> Self { *self } fn clone(&self) -> Self { *self }
@ -2797,11 +2856,6 @@ pub enum nsNodeSupportsWeakRefTearoff { }
pub enum nsNodeWeakReference { } pub enum nsNodeWeakReference { }
pub enum nsDOMMutationObserver { } pub enum nsDOMMutationObserver { }
pub enum ServoNodeData { } pub enum ServoNodeData { }
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct DefaultDelete<> {
pub _phantom0: ::std::marker::PhantomData<ServoNodeData>,
}
pub enum EventListenerManager { } pub enum EventListenerManager { }
pub enum BoxQuadOptions { } pub enum BoxQuadOptions { }
pub enum ConvertCoordinateOptions { } pub enum ConvertCoordinateOptions { }
@ -2868,7 +2922,7 @@ fn bindgen_test_layout_nsMutationGuard() {
extern "C" { extern "C" {
#[link_name = "_ZN15nsMutationGuard11sGenerationE"] #[link_name = "_ZN15nsMutationGuard11sGenerationE"]
pub static mut nsMutationGuard_consts_sGeneration: pub static mut nsMutationGuard_consts_sGeneration:
::std::os::raw::c_ulonglong; ::std::os::raw::c_ulong;
} }
pub type Float = f32; pub type Float = f32;
#[repr(i8)] #[repr(i8)]
@ -3259,7 +3313,7 @@ pub type nscolor = u32;
#[repr(i8)] #[repr(i8)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum nsHexColorType { NoAlpha = 0, AllowAlpha = 1, } pub enum nsHexColorType { NoAlpha = 0, AllowAlpha = 1, }
pub enum nsStyledElementNotElementCSSInlineStyle { } pub enum nsStyledElement { }
pub enum MiscContainer { } pub enum MiscContainer { }
pub enum ServoDeclarationBlock { } pub enum ServoDeclarationBlock { }
pub enum Declaration { } pub enum Declaration { }
@ -3470,12 +3524,7 @@ fn bindgen_test_layout_ServoAttrSnapshot() {
*/ */
#[repr(i8)] #[repr(i8)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum ServoElementSnapshotFlags { pub enum ServoElementSnapshotFlags { State = 1, Attributes = 2, All = 3, }
State = 1,
Attributes = 2,
HTMLElementInHTMLDocument = 4,
All = 7,
}
/** /**
* This class holds all non-tree-structural state of an element that might be * This class holds all non-tree-structural state of an element that might be
* used for selector matching eventually. * used for selector matching eventually.
@ -3492,6 +3541,7 @@ pub struct ServoElementSnapshot {
pub mExplicitRestyleHint: nsRestyleHint, pub mExplicitRestyleHint: nsRestyleHint,
pub mExplicitChangeHint: nsChangeHint, pub mExplicitChangeHint: nsChangeHint,
pub mIsHTMLElementInHTMLDocument: bool, pub mIsHTMLElementInHTMLDocument: bool,
pub mIsInChromeDocument: bool,
} }
#[test] #[test]
fn bindgen_test_layout_ServoElementSnapshot() { fn bindgen_test_layout_ServoElementSnapshot() {
@ -5341,6 +5391,16 @@ pub enum nsStyleImageType {
eStyleImageType_Gradient = 2, eStyleImageType_Gradient = 2,
eStyleImageType_Element = 3, 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::<CachedBorderImageData>() , 24usize);
assert_eq!(::std::mem::align_of::<CachedBorderImageData>() , 8usize);
}
/** /**
* Represents a paintable image of one of the following types. * Represents a paintable image of one of the following types.
* (1) A real image loaded from an external source. * (1) A real image loaded from an external source.
@ -5353,10 +5413,11 @@ pub enum nsStyleImageType {
*/ */
#[repr(C)] #[repr(C)]
pub struct nsStyleImage { pub struct nsStyleImage {
pub mSubImages: u64, pub mCachedBIData: UniquePtr<CachedBorderImageData,
DefaultDelete<CachedBorderImageData>>,
pub mType: nsStyleImageType, pub mType: nsStyleImageType,
pub nsStyleImage_nsStyleStruct_h_unnamed_21: nsStyleImage_nsStyleStruct_h_unnamed_21, pub nsStyleImage_nsStyleStruct_h_unnamed_21: nsStyleImage_nsStyleStruct_h_unnamed_21,
pub mCropRect: nsAutoPtr<nsStyleSides>, pub mCropRect: UniquePtr<nsStyleSides, DefaultDelete<nsStyleSides>>,
} }
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy)] #[derive(Debug, Copy)]
@ -6238,6 +6299,17 @@ extern "C" {
#[link_name = "_ZN13nsStyleColumn15kMaxColumnCountE"] #[link_name = "_ZN13nsStyleColumn15kMaxColumnCountE"]
pub static nsStyleColumn_consts_kMaxColumnCount: ::std::os::raw::c_uint; pub static nsStyleColumn_consts_kMaxColumnCount: ::std::os::raw::c_uint;
} }
#[repr(C)]
#[derive(Debug)]
pub struct FragmentOrURL {
pub mURL: nsCOMPtr<nsIURI>,
pub mIsLocalRef: bool,
}
#[test]
fn bindgen_test_layout_FragmentOrURL() {
assert_eq!(::std::mem::size_of::<FragmentOrURL>() , 16usize);
assert_eq!(::std::mem::align_of::<FragmentOrURL>() , 8usize);
}
#[repr(u32)] #[repr(u32)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum nsStyleSVGPaintType { pub enum nsStyleSVGPaintType {
@ -6265,7 +6337,7 @@ pub struct nsStyleSVGPaint {
#[derive(Debug, Copy)] #[derive(Debug, Copy)]
pub struct nsStyleSVGPaint_nsStyleStruct_h_unnamed_27 { pub struct nsStyleSVGPaint_nsStyleStruct_h_unnamed_27 {
pub mColor: __BindgenUnionField<nscolor>, pub mColor: __BindgenUnionField<nscolor>,
pub mPaintServer: __BindgenUnionField<*mut nsIURI>, pub mPaintServer: __BindgenUnionField<*mut FragmentOrURL>,
pub _bindgen_data_: u64, pub _bindgen_data_: u64,
} }
impl nsStyleSVGPaint_nsStyleStruct_h_unnamed_27 { } impl nsStyleSVGPaint_nsStyleStruct_h_unnamed_27 { }
@ -6289,9 +6361,9 @@ fn bindgen_test_layout_nsStyleSVGPaint() {
pub struct nsStyleSVG { pub struct nsStyleSVG {
pub mFill: nsStyleSVGPaint, pub mFill: nsStyleSVGPaint,
pub mStroke: nsStyleSVGPaint, pub mStroke: nsStyleSVGPaint,
pub mMarkerEnd: nsCOMPtr<nsIURI>, pub mMarkerEnd: FragmentOrURL,
pub mMarkerMid: nsCOMPtr<nsIURI>, pub mMarkerMid: FragmentOrURL,
pub mMarkerStart: nsCOMPtr<nsIURI>, pub mMarkerStart: FragmentOrURL,
pub mStrokeDasharray: nsTArray<nsStyleCoord>, pub mStrokeDasharray: nsTArray<nsStyleCoord>,
pub mStrokeDashoffset: nsStyleCoord, pub mStrokeDashoffset: nsStyleCoord,
pub mStrokeWidth: nsStyleCoord, pub mStrokeWidth: nsStyleCoord,
@ -6322,7 +6394,7 @@ pub enum nsStyleSVG_nsStyleStruct_h_unnamed_28 {
} }
#[test] #[test]
fn bindgen_test_layout_nsStyleSVG() { fn bindgen_test_layout_nsStyleSVG() {
assert_eq!(::std::mem::size_of::<nsStyleSVG>() , 120usize); assert_eq!(::std::mem::size_of::<nsStyleSVG>() , 144usize);
assert_eq!(::std::mem::align_of::<nsStyleSVG>() , 8usize); assert_eq!(::std::mem::align_of::<nsStyleSVG>() , 8usize);
} }
#[repr(C)] #[repr(C)]
@ -6360,7 +6432,7 @@ pub struct nsStyleClipPath {
#[derive(Debug, Copy)] #[derive(Debug, Copy)]
pub struct nsStyleClipPath_nsStyleStruct_h_unnamed_29 { pub struct nsStyleClipPath_nsStyleStruct_h_unnamed_29 {
pub mBasicShape: __BindgenUnionField<*mut nsStyleBasicShape>, pub mBasicShape: __BindgenUnionField<*mut nsStyleBasicShape>,
pub mURL: __BindgenUnionField<*mut nsIURI>, pub mURL: __BindgenUnionField<*mut FragmentOrURL>,
pub _bindgen_data_: u64, pub _bindgen_data_: u64,
} }
impl nsStyleClipPath_nsStyleStruct_h_unnamed_29 { } impl nsStyleClipPath_nsStyleStruct_h_unnamed_29 { }
@ -6389,7 +6461,7 @@ pub struct nsStyleFilter {
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy)] #[derive(Debug, Copy)]
pub struct nsStyleFilter_nsStyleStruct_h_unnamed_30 { pub struct nsStyleFilter_nsStyleStruct_h_unnamed_30 {
pub mURL: __BindgenUnionField<*mut nsIURI>, pub mURL: __BindgenUnionField<*mut FragmentOrURL>,
pub mDropShadow: __BindgenUnionField<*mut nsCSSShadowArray>, pub mDropShadow: __BindgenUnionField<*mut nsCSSShadowArray>,
pub _bindgen_data_: u64, pub _bindgen_data_: u64,
} }
@ -6451,3 +6523,20 @@ fn bindgen_test_layout_nsStyleEffects() {
assert_eq!(::std::mem::size_of::<nsStyleEffects>() , 40usize); assert_eq!(::std::mem::size_of::<nsStyleEffects>() , 40usize);
assert_eq!(::std::mem::align_of::<nsStyleEffects>() , 8usize); assert_eq!(::std::mem::align_of::<nsStyleEffects>() , 8usize);
} }
/**
* <div rustbindgen="true" replaces="nsSize">
*/
#[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::<nsSize>() , 8usize);
assert_eq!(::std::mem::align_of::<nsSize>() , 4usize);
}

View File

@ -80,6 +80,7 @@ COMPILATION_TARGETS = {
"/Types.h", # <- Disallow UnionTypes.h "/Types.h", # <- Disallow UnionTypes.h
"/utility", # <- Disallow xutility "/utility", # <- Disallow xutility
"nsINode.h", # <- For `NodeFlags`. "nsINode.h", # <- For `NodeFlags`.
"UniquePtr.h"
], ],
"blacklist": [ "blacklist": [
"IsDestructibleFallbackImpl", "IsDestructibleFallback", "IsDestructibleFallbackImpl", "IsDestructibleFallback",
@ -90,13 +91,17 @@ COMPILATION_TARGETS = {
"FastAnimationEffectTimingProperties", "ComputedTimingProperties", "FastAnimationEffectTimingProperties", "ComputedTimingProperties",
"FastComputedTimingProperties", "FastComputedTimingProperties",
"nsINode", "nsINode",
"HasPointerType"
], ],
"opaque_types": [ "opaque_types": [
"nsIntMargin", "nsIntPoint", "nsIntRect", "nsCOMArray", "nsIntMargin", "nsIntPoint", "nsIntRect", "nsCOMArray",
"nsDependentString", "EntryStore", "gfxFontFeatureValueSet", "nsDependentString", "EntryStore", "gfxFontFeatureValueSet",
"imgRequestProxy", "imgRequestProxyStatic", "CounterStyleManager", "imgRequestProxy", "imgRequestProxyStatic", "CounterStyleManager",
"ImageValue", "URLValue", "URLValueData", "nsIPrincipal", "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. # Generation of the ffi bindings.
@ -128,7 +133,7 @@ COMPILATION_TARGETS = {
"nsStyleCoord::Calc", "nsRestyleHint", "ServoElementSnapshot", "nsStyleCoord::Calc", "nsRestyleHint", "ServoElementSnapshot",
"nsChangeHint", "SheetParsingMode", "nsMainThreadPtrHandle", "nsChangeHint", "SheetParsingMode", "nsMainThreadPtrHandle",
"nsMainThreadPtrHolder", "nscolor", "nsFont", "FontFamilyList", "nsMainThreadPtrHolder", "nscolor", "nsFont", "FontFamilyList",
"FontFamilyType", "nsIAtom", "FontFamilyType", "nsIAtom", "nsStyleContext"
], ],
"void_types": [ "void_types": [
"nsINode", "nsIDocument", "nsIPrincipal", "nsIURI", "nsINode", "nsIDocument", "nsIPrincipal", "nsIURI",

View File

@ -26,6 +26,7 @@ mod snapshot;
mod snapshot_helpers; mod snapshot_helpers;
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub mod glue; pub mod glue;
mod sanity_checks;
mod traversal; mod traversal;
mod wrapper; mod wrapper;

View File

@ -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());
}

View File

@ -8,7 +8,10 @@ use gecko_bindings::bindings;
use gecko_bindings::bindings::Gecko_ChildrenCount; use gecko_bindings::bindings::Gecko_ChildrenCount;
use gecko_bindings::bindings::Gecko_ClassOrClassList; use gecko_bindings::bindings::Gecko_ClassOrClassList;
use gecko_bindings::bindings::Gecko_GetNodeData; 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::ServoNodeData;
use gecko_bindings::bindings::{Gecko_CalcStyleDifference, Gecko_StoreStyleDifference};
use gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentElement}; use gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentElement};
use gecko_bindings::bindings::{Gecko_GetFirstChild, Gecko_GetFirstChildElement}; use gecko_bindings::bindings::{Gecko_GetFirstChild, Gecko_GetFirstChildElement};
use gecko_bindings::bindings::{Gecko_GetLastChild, Gecko_GetLastChildElement}; use gecko_bindings::bindings::{Gecko_GetLastChild, Gecko_GetLastChildElement};
@ -21,8 +24,8 @@ use gecko_bindings::bindings::{Gecko_IsLink, Gecko_IsRootElement, Gecko_IsTextNo
use gecko_bindings::bindings::{Gecko_IsUnvisitedLink, Gecko_IsVisitedLink}; use gecko_bindings::bindings::{Gecko_IsUnvisitedLink, Gecko_IsVisitedLink};
use gecko_bindings::bindings::{Gecko_LocalName, Gecko_Namespace, Gecko_NodeIsElement, Gecko_SetNodeData}; use gecko_bindings::bindings::{Gecko_LocalName, Gecko_Namespace, Gecko_NodeIsElement, Gecko_SetNodeData};
use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode}; 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::{NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO, NODE_IS_DIRTY_FOR_SERVO};
use gecko_bindings::structs::{nsIAtom, nsChangeHint, nsStyleContext};
use glue::GeckoDeclarationBlock; use glue::GeckoDeclarationBlock;
use libc::uintptr_t; use libc::uintptr_t;
use selectors::Element; use selectors::Element;
@ -40,6 +43,7 @@ use style::dom::{OpaqueNode, PresentationalHintsSynthetizer};
use style::dom::{TDocument, TElement, TNode, TRestyleDamage, UnsafeNode}; use style::dom::{TDocument, TElement, TNode, TRestyleDamage, UnsafeNode};
use style::element_state::ElementState; use style::element_state::ElementState;
use style::error_reporting::StdoutErrorReporter; use style::error_reporting::StdoutErrorReporter;
use style::gecko_glue::ArcHelpers;
use style::gecko_selector_impl::{GeckoSelectorImpl, NonTSPseudoClass}; use style::gecko_selector_impl::{GeckoSelectorImpl, NonTSPseudoClass};
use style::parser::ParserContextExtraData; use style::parser::ParserContextExtraData;
use style::properties::{ComputedValues, parse_style_attribute}; use style::properties::{ComputedValues, parse_style_attribute};
@ -91,14 +95,36 @@ impl<'ln> GeckoNode<'ln> {
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct DummyRestyleDamage; pub struct GeckoRestyleDamage(nsChangeHint);
impl TRestyleDamage for DummyRestyleDamage {
fn compute(_: Option<&Arc<ComputedValues>>, _: &ComputedValues) -> Self { DummyRestyleDamage } impl TRestyleDamage for GeckoRestyleDamage {
fn rebuild_and_reflow() -> Self { DummyRestyleDamage } type PreExistingComputedValues = nsStyleContext;
fn compute(source: Option<&nsStyleContext>,
new_style: &Arc<ComputedValues>) -> Self {
type Helpers = ArcHelpers<ServoComputedValues, ComputedValues>;
let context = match source {
Some(ctx) => ctx as *const nsStyleContext as *mut nsStyleContext,
None => return Self::rebuild_and_reflow(),
};
Helpers::borrow(new_style, |new_style| {
let hint = unsafe { Gecko_CalcStyleDifference(context, new_style) };
GeckoRestyleDamage(hint)
})
}
fn rebuild_and_reflow() -> Self {
GeckoRestyleDamage(nsChangeHint::nsChangeHint_ReconstructFrame)
}
} }
impl BitOr for DummyRestyleDamage {
impl BitOr for GeckoRestyleDamage {
type Output = Self; 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 +132,7 @@ impl BitOr for DummyRestyleDamage {
impl<'ln> TNode for GeckoNode<'ln> { impl<'ln> TNode for GeckoNode<'ln> {
type ConcreteDocument = GeckoDocument<'ln>; type ConcreteDocument = GeckoDocument<'ln>;
type ConcreteElement = GeckoElement<'ln>; type ConcreteElement = GeckoElement<'ln>;
type ConcreteRestyleDamage = DummyRestyleDamage; type ConcreteRestyleDamage = GeckoRestyleDamage;
fn to_unsafe(&self) -> UnsafeNode { fn to_unsafe(&self) -> UnsafeNode {
(self.node as usize, 0) (self.node as usize, 0)
@ -243,9 +269,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<GeckoNode<'ln>> { fn parent_node(&self) -> Option<GeckoNode<'ln>> {
unsafe { unsafe {
@ -277,6 +308,20 @@ impl<'ln> TNode for GeckoNode<'ln> {
} }
} }
fn existing_style_for_restyle_damage<'a>(&'a self,
current_cv: Option<&'a Arc<ComputedValues>>)
-> 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 { fn needs_dirty_on_viewport_size_changed(&self) -> bool {
// Gecko's node doesn't have the DIRTY_ON_VIEWPORT_SIZE_CHANGE flag, // 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 // so we force them to be dirtied on viewport size change, regardless if

View File

@ -158,6 +158,17 @@ class MachCommands(CommandBase):
return suite return suite
return None 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', @Command('test-unit',
description='Run unit tests', description='Run unit tests',
category='testing') category='testing')