Bug 1509466 - Pass frame request callbacks along with their handles to nsRefreshDriver; r=farre
☠☠ backed out by 9311a433ea1b ☠ ☠
authorBrian Birtles <birtles@gmail.com>
Mon, 25 Feb 2019 15:02:12 +0900
changeset 519567 de1481b9b6faab60a32f630fa50ec2a16db11773
parent 519566 d11fd5d6bda6aca0e7e5786a45471726dfdddb9a
child 519568 da0f977287bdc5fc72623f644953d9da00fbd38c
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfarre
bugs1509466
milestone67.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 1509466 - Pass frame request callbacks along with their handles to nsRefreshDriver; r=farre In the next patch in this series we want to compare the handle of frame callbacks we are about to run, with a set of canceled handles stored on the document. This patch makes us pass the handles along with the callbacks so we can do that. Incidentally doing this allows us to just swap array elements when building up the refresh driver's set of callbacks to run. That is hopefully a little more efficient than running the implicit conversion operator on each item and then appending to an array. Differential Revision: https://phabricator.services.mozilla.com/D20973
dom/base/Document.cpp
dom/base/Document.h
layout/base/nsRefreshDriver.cpp
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -1163,32 +1163,19 @@ void Document::SelectorCache::NotifyExpi
   // the stage 2 of mozalloc_handle_oom().
   // Once these objects are removed asynchronously, we should update the warning
   // added in mozalloc_handle_oom() as well.
   RemoveObject(aSelector);
   mTable.Remove(aSelector->mKey);
   delete aSelector;
 }
 
-struct Document::FrameRequest {
-  FrameRequest(FrameRequestCallback& aCallback, int32_t aHandle)
-      : mCallback(&aCallback), mHandle(aHandle) {}
-
-  // Conversion operator so that we can append these to a
-  // FrameRequestCallbackList
-  operator const RefPtr<FrameRequestCallback>&() const { return mCallback; }
-
-  // Comparator operators to allow RemoveElementSorted with an
-  // integer argument on arrays of FrameRequest
-  bool operator==(int32_t aHandle) const { return mHandle == aHandle; }
-  bool operator<(int32_t aHandle) const { return mHandle < aHandle; }
-
-  RefPtr<FrameRequestCallback> mCallback;
-  int32_t mHandle;
-};
+Document::FrameRequest::FrameRequest(FrameRequestCallback& aCallback,
+                                     int32_t aHandle)
+    : mCallback(&aCallback), mHandle(aHandle) {}
 
 // ==================================================================
 // =
 // ==================================================================
 Document::Document(const char* aContentType)
     : nsINode(nullptr),
       DocumentOrShadowRoot(*this),
       mReferrerPolicySet(false),
@@ -3668,19 +3655,19 @@ void Document::UpdateFrameRequestCallbac
     rd->ScheduleFrameRequestCallbacks(this);
   } else {
     rd->RevokeFrameRequestCallbacks(this);
   }
 
   mFrameRequestCallbacksScheduled = shouldBeScheduled;
 }
 
-void Document::TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks) {
-  aCallbacks.AppendElements(mFrameRequestCallbacks);
-  mFrameRequestCallbacks.Clear();
+void Document::TakeFrameRequestCallbacks(nsTArray<FrameRequest>& aCallbacks) {
+  MOZ_ASSERT(aCallbacks.IsEmpty());
+  aCallbacks.SwapElements(mFrameRequestCallbacks);
   // No need to manually remove ourselves from the refresh driver; it will
   // handle that part.  But we do have to update our state.
   mFrameRequestCallbacksScheduled = false;
 }
 
 bool Document::ShouldThrottleFrameRequests() {
   if (mStaticCloneCount > 0) {
     // Even if we're not visible, a static clone may be, so run at full speed.
--- a/dom/base/Document.h
+++ b/dom/base/Document.h
@@ -2917,26 +2917,37 @@ class Document : public nsINode,
 
   DocumentTimeline* Timeline();
   mozilla::LinkedList<DocumentTimeline>& Timelines() { return mTimelines; }
 
   void GetAnimations(nsTArray<RefPtr<Animation>>& aAnimations);
 
   SVGSVGElement* GetSVGRootElement() const;
 
+  struct FrameRequest {
+    FrameRequest(FrameRequestCallback& aCallback, int32_t aHandle);
+
+    // Comparator operators to allow RemoveElementSorted with an
+    // integer argument on arrays of FrameRequest
+    bool operator==(int32_t aHandle) const { return mHandle == aHandle; }
+    bool operator<(int32_t aHandle) const { return mHandle < aHandle; }
+
+    RefPtr<FrameRequestCallback> mCallback;
+    int32_t mHandle;
+  };
+
   nsresult ScheduleFrameRequestCallback(FrameRequestCallback& aCallback,
                                         int32_t* aHandle);
   void CancelFrameRequestCallback(int32_t aHandle);
 
-  typedef nsTArray<RefPtr<FrameRequestCallback>> FrameRequestCallbackList;
   /**
    * Put this document's frame request callbacks into the provided
    * list, and forget about them.
    */
-  void TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks);
+  void TakeFrameRequestCallbacks(nsTArray<FrameRequest>& aCallbacks);
 
   /**
    * @return true if this document's frame request callbacks should be
    * throttled. We throttle requestAnimationFrame for documents which aren't
    * visible (e.g. scrolled out of the viewport).
    */
   bool ShouldThrottleFrameRequests();
 
@@ -4375,18 +4386,16 @@ class Document : public nsINode,
   nsTArray<nsWeakPtr> mBlockedNodesByClassifier;
 
   // Weak reference to mScriptGlobalObject QI:d to nsPIDOMWindow,
   // updated on every set of mScriptGlobalObject.
   nsPIDOMWindowInner* mWindow;
 
   nsCOMPtr<nsIDocumentEncoder> mCachedEncoder;
 
-  struct FrameRequest;
-
   nsTArray<FrameRequest> mFrameRequestCallbacks;
 
   // This object allows us to evict ourself from the back/forward cache.  The
   // pointer is non-null iff we're currently in the bfcache.
   nsIBFCacheEntry* mBFCacheEntry;
 
   // Our base target.
   nsString mBaseTarget;
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -1477,17 +1477,17 @@ void nsRefreshDriver::DoTick() {
     Tick(VsyncId(), TimeStamp::Now());
   }
 }
 
 struct DocumentFrameCallbacks {
   explicit DocumentFrameCallbacks(Document* aDocument) : mDocument(aDocument) {}
 
   RefPtr<Document> mDocument;
-  Document::FrameRequestCallbackList mCallbacks;
+  nsTArray<Document::FrameRequest> mCallbacks;
 };
 
 static nsDocShell* GetDocShell(nsPresContext* aPresContext) {
   return static_cast<nsDocShell*>(aPresContext->GetDocShell());
 }
 
 static bool HasPendingAnimations(nsIPresShell* aShell) {
   Document* doc = aShell->GetDocument();
@@ -1669,17 +1669,17 @@ void nsRefreshDriver::RunFrameRequestCal
       if (innerWindow) {
         mozilla::dom::Performance* perf = innerWindow->GetPerformance();
         if (perf) {
           timeStamp = perf->GetDOMTiming()->TimeStampToDOMHighRes(aNowTime);
         }
         // else window is partially torn down already
       }
       for (auto& callback : docCallbacks.mCallbacks) {
-        callback->Call(timeStamp);
+        callback.mCallback->Call(timeStamp);
       }
     }
   }
 }
 
 struct RunnableWithDelay {
   nsCOMPtr<nsIRunnable> mRunnable;
   uint32_t mDelay;