Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 91ff6a3

Browse files
committed
Bug 753453. Add a way for us to pass a high-res timestamp to requestAnimationFrame callbacks. r=roc
1 parent 6f8e994 commit 91ff6a3

7 files changed

Lines changed: 89 additions & 32 deletions

File tree

content/base/public/nsIDocument.h

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class DOMImplementation;
9494
class Element;
9595
struct ElementRegistrationOptions;
9696
class EventTarget;
97+
class FrameRequestCallback;
9798
class GlobalObject;
9899
class HTMLBodyElement;
99100
class Link;
@@ -1772,11 +1773,14 @@ class nsIDocument : public nsINode
17721773

17731774
virtual already_AddRefed<mozilla::dom::UndoManager> GetUndoManager() = 0;
17741775

1775-
nsresult ScheduleFrameRequestCallback(nsIFrameRequestCallback* aCallback,
1776+
typedef mozilla::dom::CallbackObjectHolder<
1777+
mozilla::dom::FrameRequestCallback,
1778+
nsIFrameRequestCallback> FrameRequestCallbackHolder;
1779+
nsresult ScheduleFrameRequestCallback(const FrameRequestCallbackHolder& aCallback,
17761780
int32_t *aHandle);
17771781
void CancelFrameRequestCallback(int32_t aHandle);
17781782

1779-
typedef nsTArray< nsCOMPtr<nsIFrameRequestCallback> > FrameRequestCallbackList;
1783+
typedef nsTArray<FrameRequestCallbackHolder> FrameRequestCallbackList;
17801784
/**
17811785
* Put this document's frame request callbacks into the provided
17821786
* list, and forget about them.
@@ -2369,29 +2373,7 @@ class nsIDocument : public nsINode
23692373

23702374
nsCOMPtr<nsIDocumentEncoder> mCachedEncoder;
23712375

2372-
struct FrameRequest {
2373-
FrameRequest(nsIFrameRequestCallback* aCallback,
2374-
int32_t aHandle) :
2375-
mCallback(aCallback),
2376-
mHandle(aHandle)
2377-
{}
2378-
2379-
// Conversion operator so that we can append these to a
2380-
// FrameRequestCallbackList
2381-
operator nsIFrameRequestCallback* const () const { return mCallback; }
2382-
2383-
// Comparator operators to allow RemoveElementSorted with an
2384-
// integer argument on arrays of FrameRequest
2385-
bool operator==(int32_t aHandle) const {
2386-
return mHandle == aHandle;
2387-
}
2388-
bool operator<(int32_t aHandle) const {
2389-
return mHandle < aHandle;
2390-
}
2391-
2392-
nsCOMPtr<nsIFrameRequestCallback> mCallback;
2393-
int32_t mHandle;
2394-
};
2376+
struct FrameRequest;
23952377

23962378
nsTArray<FrameRequest> mFrameRequestCallbacks;
23972379

content/base/src/nsDocument.cpp

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,35 @@ nsDOMStyleSheetSetList::GetSets(nsTArray<nsString>& aStyleSets)
13021302
return NS_OK;
13031303
}
13041304

1305+
// ==================================================================
1306+
1307+
struct nsIDocument::FrameRequest
1308+
{
1309+
FrameRequest(const FrameRequestCallbackHolder& aCallback,
1310+
int32_t aHandle) :
1311+
mCallback(aCallback),
1312+
mHandle(aHandle)
1313+
{}
1314+
1315+
// Conversion operator so that we can append these to a
1316+
// FrameRequestCallbackList
1317+
operator const FrameRequestCallbackHolder& () const {
1318+
return mCallback;
1319+
}
1320+
1321+
// Comparator operators to allow RemoveElementSorted with an
1322+
// integer argument on arrays of FrameRequest
1323+
bool operator==(int32_t aHandle) const {
1324+
return mHandle == aHandle;
1325+
}
1326+
bool operator<(int32_t aHandle) const {
1327+
return mHandle < aHandle;
1328+
}
1329+
1330+
FrameRequestCallbackHolder mCallback;
1331+
int32_t mHandle;
1332+
};
1333+
13051334
// ==================================================================
13061335
// =
13071336
// ==================================================================
@@ -1720,7 +1749,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
17201749

17211750
for (uint32_t i = 0; i < tmp->mFrameRequestCallbacks.Length(); ++i) {
17221751
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mFrameRequestCallbacks[i]");
1723-
cb.NoteXPCOMChild(tmp->mFrameRequestCallbacks[i]);
1752+
cb.NoteXPCOMChild(tmp->mFrameRequestCallbacks[i].mCallback.GetISupports());
17241753
}
17251754

17261755
// Traverse animation components
@@ -8736,7 +8765,7 @@ nsIDocument::CreateStaticClone(nsISupports* aCloneContainer)
87368765
}
87378766

87388767
nsresult
8739-
nsIDocument::ScheduleFrameRequestCallback(nsIFrameRequestCallback* aCallback,
8768+
nsIDocument::ScheduleFrameRequestCallback(const FrameRequestCallbackHolder& aCallback,
87408769
int32_t *aHandle)
87418770
{
87428771
if (mFrameRequestCallbackCounter == INT32_MAX) {

dom/base/nsGlobalWindow.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4341,7 +4341,8 @@ nsGlobalWindow::MozRequestAnimationFrame(nsIFrameRequestCallback* aCallback,
43414341
if (mJSObject)
43424342
js::NotifyAnimationActivity(mJSObject);
43434343

4344-
return mDoc->ScheduleFrameRequestCallback(aCallback, aHandle);
4344+
nsIDocument::FrameRequestCallbackHolder holder(aCallback);
4345+
return mDoc->ScheduleFrameRequestCallback(holder, aHandle);
43454346
}
43464347

43474348
NS_IMETHODIMP

dom/webidl/DummyBinding.webidl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ interface DummyInterface {
1919
void funcHttpConnDict(optional HttpConnDict arg);
2020
void funcWebSocketDict(optional WebSocketDict arg);
2121
void funcDNSCacheDict(optional DNSCacheDict arg);
22+
void frameRequestCallback(FrameRequestCallback arg);
2223
};
2324

2425
interface DummyInterfaceWorkers {

dom/webidl/WebIDL.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ webidl_files = \
308308
URLUtils.webidl \
309309
USSDReceivedEvent.webidl \
310310
VideoStreamTrack.webidl \
311+
Window.webidl \
311312
XMLDocument.webidl \
312313
XMLHttpRequest.webidl \
313314
XMLHttpRequestEventTarget.webidl \

dom/webidl/Window.webidl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2+
/* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
4+
* You can obtain one at http://mozilla.org/MPL/2.0/.
5+
*
6+
* The origin of this IDL file is:
7+
* https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/RequestAnimationFrame/Overview.html
8+
*/
9+
10+
callback FrameRequestCallback = void (DOMHighResTimeStamp time);

layout/base/nsRefreshDriver.cpp

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
#include "nsViewManager.h"
4343
#include "GeckoProfiler.h"
4444
#include "nsNPAPIPluginInstance.h"
45+
#include "nsPerformance.h"
46+
#include "mozilla/dom/WindowBinding.h"
4547

4648
using mozilla::TimeStamp;
4749
using mozilla::TimeDuration;
@@ -816,6 +818,15 @@ nsRefreshDriver::DoTick()
816818
}
817819
}
818820

821+
struct DocumentFrameCallbacks {
822+
DocumentFrameCallbacks(nsIDocument* aDocument) :
823+
mDocument(aDocument)
824+
{}
825+
826+
nsCOMPtr<nsIDocument> mDocument;
827+
nsIDocument::FrameRequestCallbackList mCallbacks;
828+
};
829+
819830
void
820831
nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
821832
{
@@ -873,19 +884,41 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
873884

874885
if (i == 0) {
875886
// Grab all of our frame request callbacks up front.
876-
nsIDocument::FrameRequestCallbackList frameRequestCallbacks;
887+
nsTArray<DocumentFrameCallbacks>
888+
frameRequestCallbacks(mFrameRequestCallbackDocs.Length());
877889
for (uint32_t i = 0; i < mFrameRequestCallbackDocs.Length(); ++i) {
890+
frameRequestCallbacks.AppendElement(mFrameRequestCallbackDocs[i]);
878891
mFrameRequestCallbackDocs[i]->
879-
TakeFrameRequestCallbacks(frameRequestCallbacks);
892+
TakeFrameRequestCallbacks(frameRequestCallbacks.LastElement().mCallbacks);
880893
}
881894
// OK, now reset mFrameRequestCallbackDocs so they can be
882895
// readded as needed.
883896
mFrameRequestCallbackDocs.Clear();
884897

885898
int64_t eventTime = aNowEpoch / PR_USEC_PER_MSEC;
886899
for (uint32_t i = 0; i < frameRequestCallbacks.Length(); ++i) {
887-
nsAutoMicroTask mt;
888-
frameRequestCallbacks[i]->Sample(eventTime);
900+
const DocumentFrameCallbacks& docCallbacks = frameRequestCallbacks[i];
901+
DOMHighResTimeStamp timeStamp;
902+
// XXXbz Bug 863140: GetInnerWindow can return the outer
903+
// window in some cases.
904+
nsPIDOMWindow* innerWindow = docCallbacks.mDocument->GetInnerWindow();
905+
if (innerWindow && innerWindow->IsInnerWindow()) {
906+
timeStamp = innerWindow->GetPerformance()->GetDOMTiming()->
907+
TimeStampToDOMHighRes(aNowTime);
908+
} else {
909+
timeStamp = 0;
910+
}
911+
for (uint32_t j = 0; j < docCallbacks.mCallbacks.Length(); ++j) {
912+
const nsIDocument::FrameRequestCallbackHolder& holder =
913+
docCallbacks.mCallbacks[j];
914+
nsAutoMicroTask mt;
915+
if (holder.HasWebIDLCallback()) {
916+
ErrorResult ignored;
917+
holder.GetWebIDLCallback()->Call(timeStamp, ignored);
918+
} else {
919+
holder.GetXPCOMCallback()->Sample(eventTime);
920+
}
921+
}
889922
}
890923

891924
// This is the Flush_Style case.

0 commit comments

Comments
 (0)