diff options
author | Martin Robinson <mrobinson@igalia.com> | 2020-05-05 13:36:57 +0200 |
---|---|---|
committer | Martin Robinson <mrobinson@igalia.com> | 2020-05-05 20:08:44 +0200 |
commit | 3a74013abcec241d67d2685e52a031409dc59dd4 (patch) | |
tree | 0fc6791d087797120dd960aa0fb1e0a9a6ebce92 /components/script/dom | |
parent | b585ce5b1f181996b2f8109a4e045eb6f5b3e2a0 (diff) | |
download | servo-3a74013abcec241d67d2685e52a031409dc59dd4.tar.gz servo-3a74013abcec241d67d2685e52a031409dc59dd4.zip |
Start having animations conform to the HTML spec
This is a small step toward fixing #19242. The main idea is that the
clock for animations should advance as the event loop ticks. We
accomplish this by moving the clock from layout and naming it the
"animation timeline" which is the spec language. This should fix
flakiness with animations and transitions tests where a reflow could
move animations forward while script was running.
This change also starts to break out transition and animation events
into their own data structure, because it's quite likely that the next
step in fixing #19242 is to no longer send these events through a
channel.
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/document.rs | 21 | ||||
-rw-r--r-- | components/script/dom/window.rs | 53 |
2 files changed, 30 insertions, 44 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index eacd6a11745..5e40f433da5 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use crate::animation_timeline::AnimationTimeline; use crate::document_loader::{DocumentLoader, LoadType}; use crate::dom::attr::Attr; use crate::dom::beforeunloadevent::BeforeUnloadEvent; @@ -380,6 +381,9 @@ pub struct Document { csp_list: DomRefCell<Option<CspList>>, /// https://w3c.github.io/slection-api/#dfn-selection selection: MutNullableDom<Selection>, + /// A timeline for animations which is used for synchronizing animations. + /// https://drafts.csswg.org/web-animations/#timeline + animation_timeline: DomRefCell<AnimationTimeline>, } #[derive(JSTraceable, MallocSizeOf)] @@ -2904,6 +2908,11 @@ impl Document { dirty_webgl_contexts: DomRefCell::new(HashMap::new()), csp_list: DomRefCell::new(None), selection: MutNullableDom::new(None), + animation_timeline: if pref!(layout.animations.test.enabled) { + DomRefCell::new(AnimationTimeline::new_for_testing()) + } else { + DomRefCell::new(AnimationTimeline::new()) + }, } } @@ -3605,6 +3614,18 @@ impl Document { }) .collect() } + + pub fn advance_animation_timeline_for_testing(&self, delta: f64) { + self.animation_timeline.borrow_mut().advance_specific(delta); + } + + pub fn update_animation_timeline(&self) { + self.animation_timeline.borrow_mut().update(); + } + + pub fn current_animation_timeline_value(&self) -> f64 { + self.animation_timeline.borrow().current_value() + } } impl Element { diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 481586a71ae..414ef0f2e45 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -173,8 +173,7 @@ pub enum ReflowReason { IFrameLoadEvent, MissingExplicitReflow, ElementStateChanged, - TickAnimations, - AdvanceClock(i32), + PendingReflow, } #[dom_struct] @@ -1550,12 +1549,9 @@ impl Window { /// layout animation clock. pub fn advance_animation_clock(&self, delta: i32) { let pipeline_id = self.upcast::<GlobalScope>().pipeline_id(); - ScriptThread::restyle_animating_nodes_for_advancing_clock(&pipeline_id); - self.force_reflow( - ReflowGoal::TickAnimations, - ReflowReason::AdvanceClock(delta), - None, - ); + self.Document() + .advance_animation_timeline_for_testing(delta as f64 / 1000.); + ScriptThread::handle_tick_all_animations_for_testing(pipeline_id); } /// Reflows the page unconditionally if possible and not suppressed. This @@ -1632,11 +1628,6 @@ impl Window { document.flush_dirty_canvases(); } - let advance_clock_delta = match reason { - ReflowReason::AdvanceClock(delta) => Some(delta), - _ => None, - }; - // Send new document and relevant styles to layout. let needs_display = reflow_goal.needs_display(); let reflow = ScriptReflow { @@ -1651,7 +1642,7 @@ impl Window { script_join_chan: join_chan, dom_count: document.dom_count(), pending_restyles: document.drain_pending_restyles(), - advance_clock_delta, + animation_timeline_value: document.current_animation_timeline_value(), }; self.layout_chan @@ -2453,8 +2444,7 @@ fn should_move_clip_rect(clip_rect: UntypedRect<Au>, new_viewport: UntypedRect<f } fn debug_reflow_events(id: PipelineId, reflow_goal: &ReflowGoal, reason: &ReflowReason) { - let mut debug_msg = format!("**** pipeline={}", id); - debug_msg.push_str(match *reflow_goal { + let goal_string = match *reflow_goal { ReflowGoal::Full => "\tFull", ReflowGoal::TickAnimations => "\tTickAnimations", ReflowGoal::LayoutQuery(ref query_msg, _) => match query_msg { @@ -2471,34 +2461,9 @@ fn debug_reflow_events(id: PipelineId, reflow_goal: &ReflowGoal, reason: &Reflow &QueryMsg::ElementInnerTextQuery(_) => "\tElementInnerTextQuery", &QueryMsg::InnerWindowDimensionsQuery(_) => "\tInnerWindowDimensionsQuery", }, - }); - - debug_msg.push_str(match *reason { - ReflowReason::CachedPageNeededReflow => "\tCachedPageNeededReflow", - ReflowReason::RefreshTick => "\tRefreshTick", - ReflowReason::FirstLoad => "\tFirstLoad", - ReflowReason::KeyEvent => "\tKeyEvent", - ReflowReason::MouseEvent => "\tMouseEvent", - ReflowReason::Query => "\tQuery", - ReflowReason::Timer => "\tTimer", - ReflowReason::Viewport => "\tViewport", - ReflowReason::WindowResize => "\tWindowResize", - ReflowReason::DOMContentLoaded => "\tDOMContentLoaded", - ReflowReason::DocumentLoaded => "\tDocumentLoaded", - ReflowReason::StylesheetLoaded => "\tStylesheetLoaded", - ReflowReason::ImageLoaded => "\tImageLoaded", - ReflowReason::RequestAnimationFrame => "\tRequestAnimationFrame", - ReflowReason::WebFontLoaded => "\tWebFontLoaded", - ReflowReason::WorkletLoaded => "\tWorkletLoaded", - ReflowReason::FramedContentChanged => "\tFramedContentChanged", - ReflowReason::IFrameLoadEvent => "\tIFrameLoadEvent", - ReflowReason::MissingExplicitReflow => "\tMissingExplicitReflow", - ReflowReason::ElementStateChanged => "\tElementStateChanged", - ReflowReason::TickAnimations => "\tTickAnimations", - ReflowReason::AdvanceClock(..) => "\tAdvanceClock", - }); - - println!("{}", debug_msg); + }; + + println!("**** pipeline={}\t{}\t{:?}", id, goal_string, reason); } impl Window { |