Bug 927349 part 15 - Schedule a paint when a new pending animation is added; r=jwatt
authorBrian Birtles <birtles@gmail.com>
Mon, 22 Dec 2014 09:35:41 +0900
changeset 220810 da5d7b9bff8f11a62427a9a4507a131ea4a9e058
parent 220809 9ff976d369ff942753e52e63a200f404276be184
child 220811 6710df16f1e85a1ad1d3f7b1a858667920b54798
push id28000
push usercbook@mozilla.com
push dateMon, 22 Dec 2014 12:13:57 +0000
treeherdermozilla-central@c82d5fcdc416 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt
bugs927349
milestone37.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 927349 part 15 - Schedule a paint when a new pending animation is added; r=jwatt We would like to trigger animations from the point when the first frame of the animation is painted. However, some animations will never trigger a paint (e.g. animations with an empty keyframes rule). These animations should start start however. To ensure this, whenever an animation is newly pending we schedule a paint.
dom/animation/PendingPlayerTracker.cpp
dom/animation/PendingPlayerTracker.h
--- a/dom/animation/PendingPlayerTracker.cpp
+++ b/dom/animation/PendingPlayerTracker.cpp
@@ -1,30 +1,37 @@
 /* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
 /* 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/. */
 
 #include "PendingPlayerTracker.h"
 
 #include "mozilla/dom/AnimationTimeline.h"
+#include "nsIFrame.h"
+#include "nsIPresShell.h"
 
 using namespace mozilla;
 
 namespace mozilla {
 
 NS_IMPL_CYCLE_COLLECTION(PendingPlayerTracker, mPlayPendingSet, mDocument)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(PendingPlayerTracker, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(PendingPlayerTracker, Release)
 
 void
 PendingPlayerTracker::AddPlayPending(dom::AnimationPlayer& aPlayer)
 {
   mPlayPendingSet.PutEntry(&aPlayer);
+
+  // Schedule a paint. Otherwise animations that don't trigger a paint by
+  // themselves (e.g. CSS animations with an empty keyframes rule) won't
+  // start until something else paints.
+  EnsurePaintIsScheduled();
 }
 
 void
 PendingPlayerTracker::RemovePlayPending(dom::AnimationPlayer& aPlayer)
 {
   mPlayPendingSet.RemoveEntry(&aPlayer);
 }
 
@@ -61,9 +68,29 @@ StartPlayerAtTime(nsRefPtrHashKey<dom::A
 void
 PendingPlayerTracker::StartPendingPlayers(const TimeStamp& aReadyTime)
 {
   mPlayPendingSet.EnumerateEntries(StartPlayerAtTime,
                                    const_cast<TimeStamp*>(&aReadyTime));
   mPlayPendingSet.Clear();
 }
 
+void
+PendingPlayerTracker::EnsurePaintIsScheduled()
+{
+  if (!mDocument) {
+    return;
+  }
+
+  nsIPresShell* presShell = mDocument->GetShell();
+  if (!presShell) {
+    return;
+  }
+
+  nsIFrame* rootFrame = presShell->GetRootFrame();
+  if (!rootFrame) {
+    return;
+  }
+
+  rootFrame->SchedulePaint();
+}
+
 } // namespace mozilla
--- a/dom/animation/PendingPlayerTracker.h
+++ b/dom/animation/PendingPlayerTracker.h
@@ -6,16 +6,18 @@
 #ifndef mozilla_dom_PendingPlayerTracker_h
 #define mozilla_dom_PendingPlayerTracker_h
 
 #include "mozilla/dom/AnimationPlayer.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIDocument.h"
 #include "nsTHashtable.h"
 
+class nsIFrame;
+
 namespace mozilla {
 
 class PendingPlayerTracker MOZ_FINAL
 {
 public:
   explicit PendingPlayerTracker(nsIDocument* aDocument)
     : mDocument(aDocument)
   { }
@@ -29,16 +31,18 @@ public:
 
   // Causes any pending players to resume at |aReadyTime| by first
   // fast-forwarding their timeline to the corresponding time.
   void StartPendingPlayers(const TimeStamp& aReadyTime);
 
 private:
   ~PendingPlayerTracker() { }
 
+  void EnsurePaintIsScheduled();
+
   typedef nsTHashtable<nsRefPtrHashKey<dom::AnimationPlayer>>
     AnimationPlayerSet;
 
   AnimationPlayerSet mPlayPendingSet;
   nsCOMPtr<nsIDocument> mDocument;
 };
 
 } // namespace mozilla