Bug 927349 part 1 - Add PendingPlayerTracker; r=jwatt
authorBrian Birtles <birtles@gmail.com>
Thu, 18 Dec 2014 08:42:41 +0900
changeset 220283 323f4574fd3146f08af271015bc85b3fe8b3cd39
parent 220282 745bffad22a660124f901ce12a0ebc0b5bad5ca2
child 220284 95eeca2c7e32eb2b3354afb66af27d5f8034e345
push id27983
push usercbook@mozilla.com
push dateThu, 18 Dec 2014 12:51:14 +0000
treeherdermozilla-central@9bb8b0b4daae [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 1 - Add PendingPlayerTracker; r=jwatt This patch adds a hashtable to nsDocument that stores all the animation players that are currently waiting to start. In the future it may also be used to store players that are waiting to pause which is why the methods are called AddPlayPending/RemovePlayPending instead of just AddPlayer/RemovePlayer.
dom/animation/PendingPlayerTracker.cpp
dom/animation/PendingPlayerTracker.h
dom/animation/moz.build
dom/base/nsDocument.cpp
dom/base/nsDocument.h
dom/base/nsIDocument.h
new file mode 100644
--- /dev/null
+++ b/dom/animation/PendingPlayerTracker.cpp
@@ -0,0 +1,35 @@
+/* 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"
+
+using namespace mozilla;
+
+namespace mozilla {
+
+NS_IMPL_CYCLE_COLLECTION(PendingPlayerTracker, mPlayPendingSet)
+
+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);
+}
+
+void
+PendingPlayerTracker::RemovePlayPending(dom::AnimationPlayer& aPlayer)
+{
+  mPlayPendingSet.RemoveEntry(&aPlayer);
+}
+
+bool
+PendingPlayerTracker::IsWaitingToPlay(dom::AnimationPlayer const& aPlayer) const
+{
+  return mPlayPendingSet.Contains(const_cast<dom::AnimationPlayer*>(&aPlayer));
+}
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/animation/PendingPlayerTracker.h
@@ -0,0 +1,36 @@
+/* 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/. */
+
+#ifndef mozilla_dom_PendingPlayerTracker_h
+#define mozilla_dom_PendingPlayerTracker_h
+
+#include "mozilla/dom/AnimationPlayer.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsTHashtable.h"
+
+namespace mozilla {
+
+class PendingPlayerTracker MOZ_FINAL
+{
+public:
+  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(PendingPlayerTracker)
+  NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(PendingPlayerTracker)
+
+  void AddPlayPending(dom::AnimationPlayer& aPlayer);
+  void RemovePlayPending(dom::AnimationPlayer& aPlayer);
+  bool IsWaitingToPlay(dom::AnimationPlayer const& aPlayer) const;
+
+private:
+  ~PendingPlayerTracker() { }
+
+  typedef nsTHashtable<nsRefPtrHashKey<dom::AnimationPlayer>>
+    AnimationPlayerSet;
+
+  AnimationPlayerSet mPlayPendingSet;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_dom_PendingPlayerTracker_h
--- a/dom/animation/moz.build
+++ b/dom/animation/moz.build
@@ -9,18 +9,23 @@ MOCHITEST_CHROME_MANIFESTS += ['test/chr
 
 EXPORTS.mozilla.dom += [
     'Animation.h',
     'AnimationEffect.h',
     'AnimationPlayer.h',
     'AnimationTimeline.h',
 ]
 
+EXPORTS.mozilla += [
+    'PendingPlayerTracker.h',
+]
+
 UNIFIED_SOURCES += [
     'Animation.cpp',
     'AnimationEffect.cpp',
     'AnimationPlayer.cpp',
     'AnimationTimeline.cpp',
+    'PendingPlayerTracker.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 FINAL_LIBRARY = 'xul'
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1990,16 +1990,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFirstBaseNodeWithHref)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMImplementation)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImageMaps)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOriginalDocument)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCachedEncoder)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStateObjectCached)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mUndoManager)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnimationTimeline)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingPlayerTracker)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTemplateContentsOwner)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildrenCollection)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRegistry)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnonymousContents)
 
   // Traverse all our nsCOMArrays.
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheets)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOnDemandBuiltInUASheets)
@@ -2073,16 +2074,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDisplayDocument)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mFirstBaseNodeWithHref)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMImplementation)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mImageMaps)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mOriginalDocument)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mCachedEncoder)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mUndoManager)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mAnimationTimeline)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mPendingPlayerTracker)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mTemplateContentsOwner)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mChildrenCollection)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mRegistry)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mMasterDocument)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mImportManager)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSubImportLinks)
 
   tmp->mParentDocument = nullptr;
@@ -7386,16 +7388,26 @@ nsDocument::GetAnimationController()
   // because they don't get OnPageShow / OnPageHide calls).
   if (!mIsShowing && !mIsBeingUsedAsImage) {
     mAnimationController->OnPageHide();
   }
 
   return mAnimationController;
 }
 
+PendingPlayerTracker*
+nsDocument::GetOrCreatePendingPlayerTracker()
+{
+  if (!mPendingPlayerTracker) {
+    mPendingPlayerTracker = new PendingPlayerTracker();
+  }
+
+  return mPendingPlayerTracker;
+}
+
 /**
  * Retrieve the "direction" property of the document.
  *
  * @lina 01/09/2001
  */
 NS_IMETHODIMP
 nsDocument::GetDir(nsAString& aDirection)
 {
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -54,16 +54,17 @@
 #include "nsILoadContext.h"
 #include "nsIProgressEventSink.h"
 #include "nsISecurityEventSink.h"
 #include "nsIChannelEventSink.h"
 #include "imgIRequest.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/MemoryReporting.h"
+#include "mozilla/PendingPlayerTracker.h"
 #include "mozilla/dom/DOMImplementation.h"
 #include "mozilla/dom/StyleSheetList.h"
 #include "nsDataHashtable.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Attributes.h"
 #include "nsIDOMXPathEvaluator.h"
 #include "jsfriendapi.h"
 #include "ImportManager.h"
@@ -1042,16 +1043,25 @@ public:
     EnumerateExternalResources(nsSubDocEnumFunc aCallback, void* aData);
 
   nsTArray<nsCString> mHostObjectURIs;
 
   // Returns our (lazily-initialized) animation controller.
   // If HasAnimationController is true, this is guaranteed to return non-null.
   nsSMILAnimationController* GetAnimationController() MOZ_OVERRIDE;
 
+  virtual mozilla::PendingPlayerTracker*
+  GetPendingPlayerTracker() MOZ_FINAL
+  {
+    return mPendingPlayerTracker;
+  }
+
+  virtual mozilla::PendingPlayerTracker*
+  GetOrCreatePendingPlayerTracker() MOZ_OVERRIDE;
+
   void SetImagesNeedAnimating(bool aAnimating) MOZ_OVERRIDE;
 
   virtual void SuppressEventHandling(SuppressionType aWhat,
                                      uint32_t aIncrease) MOZ_OVERRIDE;
 
   virtual void UnsuppressEventHandlingAndFireEvents(SuppressionType aWhat,
                                                     bool aFireEvents) MOZ_OVERRIDE;
 
@@ -1506,16 +1516,20 @@ protected:
 
   nsCOMArray<nsIStyleSheet> mStyleSheets;
   nsCOMArray<nsIStyleSheet> mOnDemandBuiltInUASheets;
   nsCOMArray<nsIStyleSheet> mAdditionalSheets[SheetTypeCount];
 
   // Array of observers
   nsTObserverArray<nsIDocumentObserver*> mObservers;
 
+  // Tracker for animation players that are waiting to start.
+  // nullptr until GetOrCreatePendingPlayerTracker is called.
+  nsRefPtr<mozilla::PendingPlayerTracker> mPendingPlayerTracker;
+
   // Weak reference to the scope object (aka the script global object)
   // that, unlike mScriptGlobalObject, is never unset once set. This
   // is a weak reference to avoid leaks due to circular references.
   nsWeakPtr mScopeObject;
 
   // Stack of full-screen elements. When we request full-screen we push the
   // full-screen element onto this stack, and when we cancel full-screen we
   // pop one off this stack, restoring the previous full-screen state
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -81,16 +81,17 @@ class nsDOMCaretPosition;
 class nsViewportInfo;
 class nsIGlobalObject;
 struct nsCSSSelectorList;
 
 namespace mozilla {
 class CSSStyleSheet;
 class ErrorResult;
 class EventStates;
+class PendingPlayerTracker;
 class SVGAttrAnimationRuleProcessor;
 
 namespace css {
 class Loader;
 class ImageLoader;
 } // namespace css
 
 namespace dom {
@@ -1817,16 +1818,27 @@ public:
   // will have a non-null return value.
   bool HasAnimationController()  { return !!mAnimationController; }
 
   // Getter for this document's SMIL Animation Controller. Performs lazy
   // initialization, if this document supports animation and if
   // mAnimationController isn't yet initialized.
   virtual nsSMILAnimationController* GetAnimationController() = 0;
 
+  // Gets the tracker for animation players that are waiting to start.
+  // Returns nullptr if there is no pending player tracker for this document
+  // which will be the case if there have never been any CSS animations or
+  // transitions on elements in the document.
+  virtual mozilla::PendingPlayerTracker* GetPendingPlayerTracker() = 0;
+
+  // Gets the tracker for animation players that are waiting to start and
+  // creates it if it doesn't already exist. As a result, the return value
+  // will never be nullptr.
+  virtual mozilla::PendingPlayerTracker* GetOrCreatePendingPlayerTracker() = 0;
+
   // Makes the images on this document capable of having their animation
   // active or suspended. An Image will animate as long as at least one of its
   // owning Documents needs it to animate; otherwise it can suspend.
   virtual void SetImagesNeedAnimating(bool aAnimating) = 0;
 
   enum SuppressionType {
     eAnimationsOnly = 0x1,