mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
Introduce UpdateAnimationTasks to perform a bunch of animation's tasks in a SequentialTask.
The UpdateAnimationsTasks is a bitflags and each bit is generated from Gecko's UpdateAnimationsTasks (enum class) values for matching values between C++ and Rust. For this reason, the bitflags is annotated as (feature = "gecko"), as a result update_animations() which uses this bitflags also became gecko-only function.
This commit is contained in:
parent
0c843d4b7d
commit
4183b0dff2
9 changed files with 82 additions and 21 deletions
|
@ -451,10 +451,6 @@ impl<'le> TElement for ServoLayoutElement<'le> {
|
||||||
self.element.has_selector_flags(flags)
|
self.element.has_selector_flags(flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_animations(&self, _pseudo: Option<&PseudoElement>) {
|
|
||||||
panic!("this should be only called on gecko");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_animations(&self, _pseudo: Option<&PseudoElement>) -> bool {
|
fn has_animations(&self, _pseudo: Option<&PseudoElement>) -> bool {
|
||||||
panic!("this should be only called on gecko");
|
panic!("this should be only called on gecko");
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,7 +282,8 @@ mod bindings {
|
||||||
.raw_line("use data::ElementData;")
|
.raw_line("use data::ElementData;")
|
||||||
.hide_type("nsString")
|
.hide_type("nsString")
|
||||||
.bitfield_enum("nsChangeHint")
|
.bitfield_enum("nsChangeHint")
|
||||||
.bitfield_enum("nsRestyleHint");
|
.bitfield_enum("nsRestyleHint")
|
||||||
|
.constified_enum("UpdateAnimationsTasks");
|
||||||
let whitelist_vars = [
|
let whitelist_vars = [
|
||||||
"NS_THEME_.*",
|
"NS_THEME_.*",
|
||||||
"NODE_.*",
|
"NODE_.*",
|
||||||
|
@ -306,6 +307,7 @@ mod bindings {
|
||||||
"mozilla::TraversalRootBehavior",
|
"mozilla::TraversalRootBehavior",
|
||||||
"mozilla::StyleShapeRadius",
|
"mozilla::StyleShapeRadius",
|
||||||
"mozilla::StyleGrid.*",
|
"mozilla::StyleGrid.*",
|
||||||
|
"mozilla::UpdateAnimationsTasks",
|
||||||
"mozilla::LookAndFeel",
|
"mozilla::LookAndFeel",
|
||||||
".*ThreadSafe.*Holder",
|
".*ThreadSafe.*Holder",
|
||||||
"AnonymousContent",
|
"AnonymousContent",
|
||||||
|
@ -667,6 +669,7 @@ mod bindings {
|
||||||
"Loader",
|
"Loader",
|
||||||
"ServoStyleSheet",
|
"ServoStyleSheet",
|
||||||
"EffectCompositor_CascadeLevel",
|
"EffectCompositor_CascadeLevel",
|
||||||
|
"UpdateAnimationsTasks",
|
||||||
];
|
];
|
||||||
struct ArrayType {
|
struct ArrayType {
|
||||||
cpp_type: &'static str,
|
cpp_type: &'static str,
|
||||||
|
|
|
@ -12,9 +12,10 @@ use data::ElementData;
|
||||||
use dom::{OpaqueNode, TNode, TElement, SendElement};
|
use dom::{OpaqueNode, TNode, TElement, SendElement};
|
||||||
use error_reporting::ParseErrorReporter;
|
use error_reporting::ParseErrorReporter;
|
||||||
use euclid::Size2D;
|
use euclid::Size2D;
|
||||||
|
#[cfg(feature = "gecko")] use gecko_bindings::structs;
|
||||||
use matching::StyleSharingCandidateCache;
|
use matching::StyleSharingCandidateCache;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use selector_parser::PseudoElement;
|
#[cfg(feature = "gecko")] use selector_parser::PseudoElement;
|
||||||
use selectors::matching::ElementSelectorFlags;
|
use selectors::matching::ElementSelectorFlags;
|
||||||
use servo_config::opts;
|
use servo_config::opts;
|
||||||
use shared_lock::StylesheetGuards;
|
use shared_lock::StylesheetGuards;
|
||||||
|
@ -194,6 +195,22 @@ impl TraversalStatistics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
bitflags! {
|
||||||
|
/// Represents which tasks are performed in a SequentialTask of UpdateAnimations.
|
||||||
|
pub flags UpdateAnimationsTasks: u8 {
|
||||||
|
/// Update CSS Animations.
|
||||||
|
const CSS_ANIMATIONS = structs::UpdateAnimationsTasks_CSSAnimations,
|
||||||
|
/// Update CSS Transitions.
|
||||||
|
const CSS_TRANSITIONS = structs::UpdateAnimationsTasks_CSSTransitions,
|
||||||
|
/// Update effect properties.
|
||||||
|
const EFFECT_PROPERTIES = structs::UpdateAnimationsTasks_EffectProperties,
|
||||||
|
/// Update animation cacade results for animations running on the compositor.
|
||||||
|
const CASCADE_RESULTS = structs::UpdateAnimationsTasks_CascadeResults,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// A task to be run in sequential mode on the parent (non-worker) thread. This
|
/// A task to be run in sequential mode on the parent (non-worker) thread. This
|
||||||
/// is used by the style system to queue up work which is not safe to do during
|
/// is used by the style system to queue up work which is not safe to do during
|
||||||
/// the parallel traversal.
|
/// the parallel traversal.
|
||||||
|
@ -202,9 +219,10 @@ pub enum SequentialTask<E: TElement> {
|
||||||
/// element that we don't have exclusive access to (i.e. the parent).
|
/// element that we don't have exclusive access to (i.e. the parent).
|
||||||
SetSelectorFlags(SendElement<E>, ElementSelectorFlags),
|
SetSelectorFlags(SendElement<E>, ElementSelectorFlags),
|
||||||
|
|
||||||
/// Marks that we need to create/remove/update CSS animations after the
|
#[cfg(feature = "gecko")]
|
||||||
/// first traversal.
|
/// Marks that we need to update CSS animations, update effect properties of
|
||||||
UpdateAnimations(SendElement<E>, Option<PseudoElement>),
|
/// any type of animations after the normal traversal.
|
||||||
|
UpdateAnimations(SendElement<E>, Option<PseudoElement>, UpdateAnimationsTasks),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: TElement> SequentialTask<E> {
|
impl<E: TElement> SequentialTask<E> {
|
||||||
|
@ -216,8 +234,9 @@ impl<E: TElement> SequentialTask<E> {
|
||||||
SetSelectorFlags(el, flags) => {
|
SetSelectorFlags(el, flags) => {
|
||||||
unsafe { el.set_selector_flags(flags) };
|
unsafe { el.set_selector_flags(flags) };
|
||||||
}
|
}
|
||||||
UpdateAnimations(el, pseudo) => {
|
#[cfg(feature = "gecko")]
|
||||||
unsafe { el.update_animations(pseudo.as_ref()) };
|
UpdateAnimations(el, pseudo, tasks) => {
|
||||||
|
unsafe { el.update_animations(pseudo.as_ref(), tasks) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,10 +247,12 @@ impl<E: TElement> SequentialTask<E> {
|
||||||
SetSelectorFlags(unsafe { SendElement::new(el) }, flags)
|
SetSelectorFlags(unsafe { SendElement::new(el) }, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a task to update CSS Animations on a given (pseudo-)element.
|
#[cfg(feature = "gecko")]
|
||||||
pub fn update_animations(el: E, pseudo: Option<PseudoElement>) -> Self {
|
/// Creates a task to update various animation state on a given (pseudo-)element.
|
||||||
|
pub fn update_animations(el: E, pseudo: Option<PseudoElement>,
|
||||||
|
tasks: UpdateAnimationsTasks) -> Self {
|
||||||
use self::SequentialTask::*;
|
use self::SequentialTask::*;
|
||||||
UpdateAnimations(unsafe { SendElement::new(el) }, pseudo)
|
UpdateAnimations(unsafe { SendElement::new(el) }, pseudo, tasks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
use {Atom, Namespace, LocalName};
|
use {Atom, Namespace, LocalName};
|
||||||
use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
|
use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
|
||||||
|
#[cfg(feature = "gecko")] use context::UpdateAnimationsTasks;
|
||||||
use data::ElementData;
|
use data::ElementData;
|
||||||
use element_state::ElementState;
|
use element_state::ElementState;
|
||||||
use properties::{ComputedValues, PropertyDeclarationBlock};
|
use properties::{ComputedValues, PropertyDeclarationBlock};
|
||||||
|
@ -366,9 +367,10 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre
|
||||||
/// Returns true if the element has all the specified selector flags.
|
/// Returns true if the element has all the specified selector flags.
|
||||||
fn has_selector_flags(&self, flags: ElementSelectorFlags) -> bool;
|
fn has_selector_flags(&self, flags: ElementSelectorFlags) -> bool;
|
||||||
|
|
||||||
/// Creates a task to update CSS Animations on a given (pseudo-)element.
|
/// Creates a task to update various animation state on a given (pseudo-)element.
|
||||||
/// Note: Gecko only.
|
#[cfg(feature = "gecko")]
|
||||||
fn update_animations(&self, _pseudo: Option<&PseudoElement>);
|
fn update_animations(&self, _pseudo: Option<&PseudoElement>,
|
||||||
|
tasks: UpdateAnimationsTasks);
|
||||||
|
|
||||||
/// Returns true if the element has relevant animations. Relevant
|
/// Returns true if the element has relevant animations. Relevant
|
||||||
/// animations are those animations that are affecting the element's style
|
/// animations are those animations that are affecting the element's style
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
//! the separation between the style system implementation and everything else.
|
//! the separation between the style system implementation and everything else.
|
||||||
|
|
||||||
use atomic_refcell::AtomicRefCell;
|
use atomic_refcell::AtomicRefCell;
|
||||||
|
use context::UpdateAnimationsTasks;
|
||||||
use data::ElementData;
|
use data::ElementData;
|
||||||
use dom::{AnimationRules, LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode};
|
use dom::{AnimationRules, LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode};
|
||||||
use dom::{OpaqueNode, PresentationalHintsSynthetizer};
|
use dom::{OpaqueNode, PresentationalHintsSynthetizer};
|
||||||
|
@ -555,7 +556,8 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
(self.flags() & node_flags) == node_flags
|
(self.flags() & node_flags) == node_flags
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_animations(&self, pseudo: Option<&PseudoElement>) {
|
fn update_animations(&self, pseudo: Option<&PseudoElement>,
|
||||||
|
tasks: UpdateAnimationsTasks) {
|
||||||
// We have to update animations even if the element has no computed style
|
// We have to update animations even if the element has no computed style
|
||||||
// since it means the element is in a display:none subtree, we should destroy
|
// since it means the element is in a display:none subtree, we should destroy
|
||||||
// all CSS animations in display:none subtree.
|
// all CSS animations in display:none subtree.
|
||||||
|
@ -584,7 +586,8 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
unsafe {
|
unsafe {
|
||||||
Gecko_UpdateAnimations(self.0, atom_ptr,
|
Gecko_UpdateAnimations(self.0, atom_ptr,
|
||||||
computed_values_opt,
|
computed_values_opt,
|
||||||
parent_values_opt);
|
parent_values_opt,
|
||||||
|
tasks.bits());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -176,6 +176,7 @@ use gecko_bindings::structs::nsresult;
|
||||||
use gecko_bindings::structs::Loader;
|
use gecko_bindings::structs::Loader;
|
||||||
use gecko_bindings::structs::ServoStyleSheet;
|
use gecko_bindings::structs::ServoStyleSheet;
|
||||||
use gecko_bindings::structs::EffectCompositor_CascadeLevel;
|
use gecko_bindings::structs::EffectCompositor_CascadeLevel;
|
||||||
|
use gecko_bindings::structs::UpdateAnimationsTasks;
|
||||||
pub type nsTArrayBorrowed_uintptr_t<'a> = &'a mut ::gecko_bindings::structs::nsTArray<usize>;
|
pub type nsTArrayBorrowed_uintptr_t<'a> = &'a mut ::gecko_bindings::structs::nsTArray<usize>;
|
||||||
pub type ServoCssRulesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoCssRules>;
|
pub type ServoCssRulesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoCssRules>;
|
||||||
pub type ServoCssRulesBorrowed<'a> = &'a ServoCssRules;
|
pub type ServoCssRulesBorrowed<'a> = &'a ServoCssRules;
|
||||||
|
@ -610,7 +611,8 @@ extern "C" {
|
||||||
aComputedValues:
|
aComputedValues:
|
||||||
ServoComputedValuesBorrowedOrNull,
|
ServoComputedValuesBorrowedOrNull,
|
||||||
aParentComputedValues:
|
aParentComputedValues:
|
||||||
ServoComputedValuesBorrowedOrNull);
|
ServoComputedValuesBorrowedOrNull,
|
||||||
|
aTaskBits: UpdateAnimationsTasks);
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_ElementHasAnimations(aElement: RawGeckoElementBorrowed,
|
pub fn Gecko_ElementHasAnimations(aElement: RawGeckoElementBorrowed,
|
||||||
|
|
|
@ -6151,6 +6151,19 @@ pub mod root {
|
||||||
Normal = 0,
|
Normal = 0,
|
||||||
UnstyledChildrenOnly = 1,
|
UnstyledChildrenOnly = 1,
|
||||||
}
|
}
|
||||||
|
pub const UpdateAnimationsTasks_CSSAnimations:
|
||||||
|
root::mozilla::UpdateAnimationsTasks =
|
||||||
|
1;
|
||||||
|
pub const UpdateAnimationsTasks_CSSTransitions:
|
||||||
|
root::mozilla::UpdateAnimationsTasks =
|
||||||
|
2;
|
||||||
|
pub const UpdateAnimationsTasks_EffectProperties:
|
||||||
|
root::mozilla::UpdateAnimationsTasks =
|
||||||
|
4;
|
||||||
|
pub const UpdateAnimationsTasks_CascadeResults:
|
||||||
|
root::mozilla::UpdateAnimationsTasks =
|
||||||
|
8;
|
||||||
|
pub type UpdateAnimationsTasks = u8;
|
||||||
pub type CSSPseudoElementTypeBase = u8;
|
pub type CSSPseudoElementTypeBase = u8;
|
||||||
pub const CSSPseudoElementType_InheritingAnonBox:
|
pub const CSSPseudoElementType_InheritingAnonBox:
|
||||||
root::mozilla::CSSPseudoElementType =
|
root::mozilla::CSSPseudoElementType =
|
||||||
|
|
|
@ -6066,6 +6066,19 @@ pub mod root {
|
||||||
Normal = 0,
|
Normal = 0,
|
||||||
UnstyledChildrenOnly = 1,
|
UnstyledChildrenOnly = 1,
|
||||||
}
|
}
|
||||||
|
pub const UpdateAnimationsTasks_CSSAnimations:
|
||||||
|
root::mozilla::UpdateAnimationsTasks =
|
||||||
|
1;
|
||||||
|
pub const UpdateAnimationsTasks_CSSTransitions:
|
||||||
|
root::mozilla::UpdateAnimationsTasks =
|
||||||
|
2;
|
||||||
|
pub const UpdateAnimationsTasks_EffectProperties:
|
||||||
|
root::mozilla::UpdateAnimationsTasks =
|
||||||
|
4;
|
||||||
|
pub const UpdateAnimationsTasks_CascadeResults:
|
||||||
|
root::mozilla::UpdateAnimationsTasks =
|
||||||
|
8;
|
||||||
|
pub type UpdateAnimationsTasks = u8;
|
||||||
pub type CSSPseudoElementTypeBase = u8;
|
pub type CSSPseudoElementTypeBase = u8;
|
||||||
pub const CSSPseudoElementType_InheritingAnonBox:
|
pub const CSSPseudoElementType_InheritingAnonBox:
|
||||||
root::mozilla::CSSPseudoElementType =
|
root::mozilla::CSSPseudoElementType =
|
||||||
|
|
|
@ -638,11 +638,15 @@ trait PrivateMatchMethods: TElement {
|
||||||
new_values: &mut Arc<ComputedValues>,
|
new_values: &mut Arc<ComputedValues>,
|
||||||
pseudo: Option<&PseudoElement>,
|
pseudo: Option<&PseudoElement>,
|
||||||
_possibly_expired_animations: &mut Vec<PropertyAnimation>) {
|
_possibly_expired_animations: &mut Vec<PropertyAnimation>) {
|
||||||
|
use context::CSS_ANIMATIONS;
|
||||||
|
use context::UpdateAnimationsTasks;
|
||||||
|
|
||||||
let ref new_box_style = new_values.get_box();
|
let ref new_box_style = new_values.get_box();
|
||||||
let has_new_animation_style = new_box_style.animation_name_count() >= 1 &&
|
let has_new_animation_style = new_box_style.animation_name_count() >= 1 &&
|
||||||
new_box_style.animation_name_at(0).0.len() != 0;
|
new_box_style.animation_name_at(0).0.len() != 0;
|
||||||
let has_animations = self.has_css_animations(pseudo);
|
let has_animations = self.has_css_animations(pseudo);
|
||||||
|
|
||||||
|
let mut tasks = UpdateAnimationsTasks::empty();
|
||||||
let needs_update_animations =
|
let needs_update_animations =
|
||||||
old_values.as_ref().map_or(has_new_animation_style, |ref old| {
|
old_values.as_ref().map_or(has_new_animation_style, |ref old| {
|
||||||
let ref old_box_style = old.get_box();
|
let ref old_box_style = old.get_box();
|
||||||
|
@ -658,8 +662,12 @@ trait PrivateMatchMethods: TElement {
|
||||||
has_animations)
|
has_animations)
|
||||||
});
|
});
|
||||||
if needs_update_animations {
|
if needs_update_animations {
|
||||||
|
tasks.insert(CSS_ANIMATIONS);
|
||||||
|
}
|
||||||
|
if !tasks.is_empty() {
|
||||||
let task = SequentialTask::update_animations(self.as_node().as_element().unwrap(),
|
let task = SequentialTask::update_animations(self.as_node().as_element().unwrap(),
|
||||||
pseudo.cloned());
|
pseudo.cloned(),
|
||||||
|
tasks);
|
||||||
context.thread_local.tasks.push(task);
|
context.thread_local.tasks.push(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue