Handle scroll-driven animations in AsyncCompositionManager draft
authorBotond Ballo <botond@mozilla.com>
Fri, 05 Aug 2016 15:28:26 -0400
changeset 397403 97e5fd61b2bdeb043d64b3aec983df02aea320f1
parent 397402 db6fb06d6d1da0de0ed0828eec2d90f7cb9e5286
child 397404 88a6d1da92ddadb7909f61035a57011c163e38a1
push id25288
push userbballo@mozilla.com
push dateFri, 05 Aug 2016 19:41:51 +0000
milestone50.0a1
Handle scroll-driven animations in AsyncCompositionManager MozReview-Commit-ID: 9fvxE7WFDHP
gfx/layers/composite/AsyncCompositionManager.cpp
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -638,32 +638,64 @@ FindAPZC(LayerMetricsWrapper aRoot, uint
 
 static bool
 SampleAnimations(Layer* aLayer, TimeStamp aPoint)
 {
   bool activeAnimations = false;
 
   ForEachNode<ForwardIterator>(
       aLayer,
-      [&activeAnimations, &aPoint] (Layer* layer)
+      [&activeAnimations, &aPoint, &aLayer] (Layer* layer)
       {
         AnimationArray& animations = layer->GetAnimations();
         InfallibleTArray<AnimData>& animationData = layer->GetAnimationData();
 
         // Process in order, since later animations override earlier ones.
         for (size_t i = 0, iEnd = animations.Length(); i < iEnd; ++i) {
           Animation& animation = animations[i];
           AnimData& animData = animationData[i];
 
           activeAnimations = true;
 
+          TimeStamp timelineTime = aPoint;
+          if (animation.scrollTimelineInfo().type() == MaybeScrollTimelineInfo::TScrollTimelineInfo) {
+            const ScrollTimelineInfo& info = animation.scrollTimelineInfo();
+            if (AsyncPanZoomController* apzc = FindAPZC(LayerMetricsWrapper(aLayer),
+                                                        LayersIdFor(layer),
+                                                        info.scrollFrame())) {
+              FrameMetrics metrics = apzc->GetFrameMetricsCopy();
+              CSSRect scrollRange = metrics.CalculateScrollRange();
+              CSSPoint scrollOffset = metrics.GetScrollOffset();
+              CSSCoord minScroll, maxScroll, currentScroll;
+              if (info.direction() == dom::ScrollDirection::Horizontal) {
+                minScroll = scrollRange.X();
+                maxScroll = scrollRange.XMost();
+                currentScroll = scrollOffset.x;
+              } else {
+                minScroll = scrollRange.Y();
+                maxScroll = scrollRange.YMost();
+                currentScroll = scrollOffset.y;
+              }
+              double scrollRangeLen = maxScroll - minScroll;
+              if (scrollRangeLen != 0 && !info.timeRange().IsZero()) {
+                // TODO: Is this right?
+                timelineTime = animation.startTime() +
+                    info.timeRange().MultDouble(currentScroll / scrollRangeLen);
+              } else {
+                continue;
+              }
+            } else {
+              continue;
+            }
+          }
+
           MOZ_ASSERT(!animation.startTime().IsNull(),
                      "Failed to resolve start time of pending animations");
           TimeDuration elapsedDuration =
-            (aPoint - animation.startTime()).MultDouble(animation.playbackRate());
+            (timelineTime - animation.startTime()).MultDouble(animation.playbackRate());
           // Skip animations that are yet to start.
           //
           // Currently, this should only happen when the refresh driver is under test
           // control and is made to produce a time in the past or is restored from
           // test control causing it to jump backwards in time.
           //
           // Since activeAnimations is true, this could mean we keep compositing
           // unnecessarily during the delay, but so long as this only happens while