Bug 553075: Don't register for periodic SMIL sample callbacks until we've got some animations registered. r=roc
authorDaniel Holbert <dholbert@cs.stanford.edu>
Sun, 21 Mar 2010 12:22:36 -0700
changeset 39687 1d16de84e49cc62ba4e51d67039dd4484281ce30
parent 39686 1633e6077d77df73bb8236fa267b8a735707b24d
child 39688 dc9d6b2a856198412cae9877200e5837962af406
push id12340
push userdholbert@mozilla.com
push dateSun, 21 Mar 2010 19:25:56 +0000
treeherdermozilla-central@dc9d6b2a8561 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs553075
milestone1.9.3a4pre
Bug 553075: Don't register for periodic SMIL sample callbacks until we've got some animations registered. r=roc
content/smil/nsSMILAnimationController.cpp
content/smil/nsSMILAnimationController.h
--- a/content/smil/nsSMILAnimationController.cpp
+++ b/content/smil/nsSMILAnimationController.cpp
@@ -76,16 +76,17 @@ GetRefreshDriverForDoc(nsIDocument* aDoc
 }
 
 
 //----------------------------------------------------------------------
 // ctors, dtors, factory methods
 
 nsSMILAnimationController::nsSMILAnimationController()
   : mResampleNeeded(PR_FALSE),
+    mDeferredStartSampling(PR_FALSE),
     mDocument(nsnull)
 {
   mAnimationElementTable.Init();
   mChildContainerTable.Init();
 }
 
 nsSMILAnimationController::~nsSMILAnimationController()
 {
@@ -145,17 +146,21 @@ void
 nsSMILAnimationController::Resume(PRUint32 aType)
 {
   PRBool wasPaused = (mPauseState != 0);
 
   nsSMILTimeContainer::Resume(aType);
 
   if (wasPaused && !mPauseState && mChildContainerTable.Count()) {
     Sample(); // Run the first sample manually
-    StartSampling(GetRefreshDriverForDoc(mDocument));
+    if (mAnimationElementTable.Count()) {
+      StartSampling(GetRefreshDriverForDoc(mDocument));
+    } else {
+      mDeferredStartSampling = PR_TRUE;
+    }
   }
 }
 
 nsSMILTime
 nsSMILAnimationController::GetParentTime() const
 {
   // Our parent time is wallclock time
   return PR_Now() / PR_USEC_PER_MSEC;
@@ -180,16 +185,24 @@ nsSMILAnimationController::WillRefresh(m
 //----------------------------------------------------------------------
 // Animation element registration methods:
 
 void
 nsSMILAnimationController::RegisterAnimationElement(
                                   nsISMILAnimationElement* aAnimationElement)
 {
   mAnimationElementTable.PutEntry(aAnimationElement);
+  if (mDeferredStartSampling) {
+    // mAnimationElementTable was empty until we just inserted its first element
+    NS_ABORT_IF_FALSE(mAnimationElementTable.Count() == 1,
+                      "we shouldn't have deferred sampling if we already had "
+                      "animations registered");
+    mDeferredStartSampling = PR_FALSE;
+    StartSampling(GetRefreshDriverForDoc(mDocument));
+  }
 }
 
 void
 nsSMILAnimationController::UnregisterAnimationElement(
                                   nsISMILAnimationElement* aAnimationElement)
 {
   mAnimationElementTable.RemoveEntry(aAnimationElement);
 }
@@ -690,17 +703,21 @@ nsSMILAnimationController::GetTargetIden
 nsresult
 nsSMILAnimationController::AddChild(nsSMILTimeContainer& aChild)
 {
   TimeContainerPtrKey* key = mChildContainerTable.PutEntry(&aChild);
   NS_ENSURE_TRUE(key,NS_ERROR_OUT_OF_MEMORY);
 
   if (!mPauseState && mChildContainerTable.Count() == 1) {
     Sample(); // Run the first sample manually
-    StartSampling(GetRefreshDriverForDoc(mDocument));
+    if (mAnimationElementTable.Count()) {
+      StartSampling(GetRefreshDriverForDoc(mDocument));
+    } else {
+      mDeferredStartSampling = PR_TRUE;
+    }
   }
 
   return NS_OK;
 }
 
 void
 nsSMILAnimationController::RemoveChild(nsSMILTimeContainer& aChild)
 {
--- a/content/smil/nsSMILAnimationController.h
+++ b/content/smil/nsSMILAnimationController.h
@@ -178,16 +178,17 @@ protected:
   nsAutoRefCnt mRefCnt;
   NS_DECL_OWNINGTHREAD
 
   static const PRUint32      kTimerInterval;
   nsCOMPtr<nsITimer>         mTimer;
   AnimationElementHashtable  mAnimationElementTable;
   TimeContainerHashtable     mChildContainerTable;
   PRPackedBool               mResampleNeeded;
+  PRPackedBool               mDeferredStartSampling;
 
   // Store raw ptr to mDocument.  It owns the controller, so controller
   // shouldn't outlive it
   nsIDocument* mDocument;
 
   // Contains compositors used in our last sample.  We keep this around
   // so we can detect when an element/attribute used to be animated,
   // but isn't anymore for some reason. (e.g. if its <animate> element is