@@ -2361,66 +2361,26 @@ void nsRefreshDriver::UpdateAnimationsAndSendEvents() {
2361
2361
}
2362
2362
}
2363
2363
2364
- void nsRefreshDriver::RunVideoAndFrameRequestCallbacks (TimeStamp aNowTime) {
2365
- if (!mNeedToRunFrameRequestCallbacks ) {
2366
- return ;
2367
- }
2368
- mNeedToRunFrameRequestCallbacks = false ;
2369
- const bool tickThrottledFrameRequests = [&] {
2370
- if (mThrottled ) {
2371
- // We always tick throttled frame requests if the entire refresh driver is
2372
- // throttled, because in that situation throttled frame requests tick at
2373
- // the same frequency as non-throttled frame requests.
2374
- return true ;
2375
- }
2376
- if (aNowTime >= mNextThrottledFrameRequestTick ) {
2377
- mNextThrottledFrameRequestTick =
2378
- aNowTime + mThrottledFrameRequestInterval ;
2379
- return true ;
2380
- }
2381
- return false ;
2382
- }();
2383
-
2384
- if (NS_WARN_IF(!mPresContext )) {
2385
- return ;
2386
- }
2387
- // Grab all of our documents that can fire frame request callbacks up front.
2388
- AutoTArray<RefPtr<Document>, 8 > docs;
2389
- auto ShouldCollect = [](const Document* aDoc) {
2390
- return aDoc->ShouldFireFrameRequestCallbacks ();
2391
- };
2392
- if (ShouldCollect (mPresContext ->Document ())) {
2393
- docs.AppendElement (mPresContext ->Document ());
2394
- }
2395
- mPresContext ->Document ()->CollectDescendantDocuments (docs, ShouldCollect);
2396
-
2397
- // First check for and run video frame callbacks. These can trigger new frame
2398
- // request callbacks that we need to handle in the following pass.
2364
+ void nsRefreshDriver::RunVideoFrameCallbacks (
2365
+ const nsTArray<RefPtr<Document>>& aDocs, TimeStamp aNowTime) {
2366
+ // For each fully active Document in docs, for each associated video element
2367
+ // for that Document, run the video frame request callbacks passing now as the
2368
+ // timestamp.
2399
2369
Maybe<TimeStamp> nextTickHint;
2400
- for (Document* doc : docs) {
2401
- if (!tickThrottledFrameRequests && doc->ShouldThrottleFrameRequests ()) {
2402
- // Skip throttled docs if it's not time to un-throttle them yet.
2403
- // FIXME(emilio): It's a bit subtle to just set this to true here, but
2404
- // matches pre-existing behavior for throttled docs. It seems at least we
2405
- // should EnsureTimerStarted too? But that kinda defeats the throttling, a
2406
- // little bit? For now, preserve behavior.
2407
- mNeedToRunFrameRequestCallbacks = true ;
2408
- continue ;
2409
- }
2370
+ for (Document* doc : aDocs) {
2410
2371
nsTArray<RefPtr<HTMLVideoElement>> videoElms;
2411
2372
doc->TakeVideoFrameRequestCallbacks (videoElms);
2412
2373
if (videoElms.IsEmpty ()) {
2413
2374
continue ;
2414
2375
}
2415
- if (!nextTickHint) {
2416
- nextTickHint = GetNextTickHint ();
2417
- }
2418
- AUTO_PROFILER_TRACING_MARKER_INNERWINDOWID (
2419
- " Paint" , " requestVideoFrame callbacks" , GRAPHICS, doc->InnerWindowID ());
2376
+
2420
2377
DOMHighResTimeStamp timeStamp = 0 ;
2421
2378
DOMHighResTimeStamp nextTickTimeStamp = 0 ;
2422
- if (nsPIDOMWindowInner * innerWindow = doc->GetInnerWindow ()) {
2379
+ if (auto * innerWindow = doc->GetInnerWindow ()) {
2423
2380
if (Performance* perf = innerWindow->GetPerformance ()) {
2381
+ if (!nextTickHint) {
2382
+ nextTickHint = GetNextTickHint ();
2383
+ }
2424
2384
timeStamp = perf->TimeStampToDOMHighResForRendering (aNowTime);
2425
2385
nextTickTimeStamp =
2426
2386
nextTickHint
@@ -2429,6 +2389,9 @@ void nsRefreshDriver::RunVideoAndFrameRequestCallbacks(TimeStamp aNowTime) {
2429
2389
}
2430
2390
// else window is partially torn down already
2431
2391
}
2392
+
2393
+ AUTO_PROFILER_TRACING_MARKER_INNERWINDOWID (
2394
+ " Paint" , " requestVideoFrame callbacks" , GRAPHICS, doc->InnerWindowID ());
2432
2395
for (const auto & videoElm : videoElms) {
2433
2396
nsTArray<VideoFrameRequest> callbacks;
2434
2397
VideoFrameCallbackMetadata metadata;
@@ -2465,40 +2428,37 @@ void nsRefreshDriver::RunVideoAndFrameRequestCallbacks(TimeStamp aNowTime) {
2465
2428
}
2466
2429
}
2467
2430
}
2431
+ }
2468
2432
2469
- // Next check for and run frame request callbacks.
2470
- for (Document* doc : docs) {
2471
- if (!tickThrottledFrameRequests && doc->ShouldThrottleFrameRequests ()) {
2472
- // Skip throttled docs if it's not time to un-throttle them yet.
2473
- MOZ_ASSERT (mNeedToRunFrameRequestCallbacks );
2474
- continue ;
2475
- }
2476
- AutoTArray<FrameRequest, 8 > callbacks;
2433
+ void nsRefreshDriver::RunFrameRequestCallbacks (
2434
+ const nsTArray<RefPtr<Document>>& aDocs, TimeStamp aNowTime) {
2435
+ for (Document* doc : aDocs) {
2436
+ nsTArray<FrameRequest> callbacks;
2477
2437
doc->TakeFrameRequestCallbacks (callbacks);
2478
2438
if (callbacks.IsEmpty ()) {
2479
2439
continue ;
2480
2440
}
2481
- AUTO_PROFILER_TRACING_MARKER_INNERWINDOWID (
2482
- " Paint" , " requestAnimationFrame callbacks" , GRAPHICS,
2483
- doc->InnerWindowID ());
2484
- TimeStamp startTime = TimeStamp::Now ();
2485
- nsCOMPtr<nsIGlobalObject> global;
2441
+
2486
2442
DOMHighResTimeStamp timeStamp = 0 ;
2487
- if (nsPIDOMWindowInner* innerWindow = doc->GetInnerWindow ()) {
2443
+ RefPtr innerWindow = nsGlobalWindowInner::Cast (doc->GetInnerWindow ());
2444
+ if (innerWindow) {
2488
2445
if (Performance* perf = innerWindow->GetPerformance ()) {
2489
2446
timeStamp = perf->TimeStampToDOMHighResForRendering (aNowTime);
2490
2447
}
2491
- global = nsGlobalWindowInner::Cast (innerWindow);
2492
2448
// else window is partially torn down already
2493
2449
}
2494
2450
2451
+ AUTO_PROFILER_TRACING_MARKER_INNERWINDOWID (
2452
+ " Paint" , " requestAnimationFrame callbacks" , GRAPHICS,
2453
+ doc->InnerWindowID ());
2454
+ const TimeStamp startTime = TimeStamp::Now ();
2495
2455
for (const auto & callback : callbacks) {
2496
2456
if (doc->IsCanceledFrameRequestCallback (callback.mHandle )) {
2497
2457
continue ;
2498
2458
}
2499
2459
2500
2460
CallbackDebuggerNotificationGuard guard (
2501
- global , DebuggerNotificationType::RequestAnimationFrameCallback);
2461
+ innerWindow , DebuggerNotificationType::RequestAnimationFrameCallback);
2502
2462
2503
2463
// MOZ_KnownLive is OK, because the stack array frameRequestCallbacks
2504
2464
// keeps callback alive and the mCallback strong reference can't be
@@ -2517,6 +2477,67 @@ void nsRefreshDriver::RunVideoAndFrameRequestCallbacks(TimeStamp aNowTime) {
2517
2477
}
2518
2478
}
2519
2479
2480
+ void nsRefreshDriver::RunVideoAndFrameRequestCallbacks (TimeStamp aNowTime) {
2481
+ if (!mNeedToRunFrameRequestCallbacks ) {
2482
+ return ;
2483
+ }
2484
+ mNeedToRunFrameRequestCallbacks = false ;
2485
+ const bool tickThrottledFrameRequests = [&] {
2486
+ if (mThrottled ) {
2487
+ // We always tick throttled frame requests if the entire refresh driver is
2488
+ // throttled, because in that situation throttled frame requests tick at
2489
+ // the same frequency as non-throttled frame requests.
2490
+ return true ;
2491
+ }
2492
+ if (aNowTime >= mNextThrottledFrameRequestTick ) {
2493
+ mNextThrottledFrameRequestTick =
2494
+ aNowTime + mThrottledFrameRequestInterval ;
2495
+ return true ;
2496
+ }
2497
+ return false ;
2498
+ }();
2499
+
2500
+ if (NS_WARN_IF(!mPresContext )) {
2501
+ return ;
2502
+ }
2503
+ // Grab all of our documents that can fire frame request callbacks up front.
2504
+ AutoTArray<RefPtr<Document>, 8 > docs;
2505
+ auto ShouldCollect = [](const Document* aDoc) {
2506
+ // TODO(emilio): Consider removing HasFrameRequestCallbacks() to deal with
2507
+ // callbacks posted from other documents more per spec?
2508
+ //
2509
+ // If we do that we also need to tweak the throttling code to not set
2510
+ // mNeedToRunFrameRequestCallbacks unnecessarily... Check what other engines
2511
+ // do too.
2512
+ return aDoc->HasFrameRequestCallbacks () &&
2513
+ aDoc->ShouldFireFrameRequestCallbacks ();
2514
+ };
2515
+ if (ShouldCollect (mPresContext ->Document ())) {
2516
+ docs.AppendElement (mPresContext ->Document ());
2517
+ }
2518
+ mPresContext ->Document ()->CollectDescendantDocuments (docs, ShouldCollect);
2519
+ // Skip throttled docs if it's not time to un-throttle them yet.
2520
+ if (!tickThrottledFrameRequests) {
2521
+ const size_t sizeBefore = docs.Length ();
2522
+ docs.RemoveElementsBy (
2523
+ [](Document* aDoc) { return aDoc->ShouldThrottleFrameRequests (); });
2524
+ if (sizeBefore != docs.Length ()) {
2525
+ // FIXME(emilio): It's a bit subtle to just set this to true here, but
2526
+ // matches pre-existing behavior for throttled docs. It seems at least we
2527
+ // should EnsureTimerStarted too? But that kinda defeats the throttling, a
2528
+ // little bit? For now, preserve behavior.
2529
+ mNeedToRunFrameRequestCallbacks = true ;
2530
+ }
2531
+ }
2532
+
2533
+ if (docs.IsEmpty ()) {
2534
+ return ;
2535
+ }
2536
+
2537
+ RunVideoFrameCallbacks (docs, aNowTime);
2538
+ RunFrameRequestCallbacks (docs, aNowTime);
2539
+ }
2540
+
2520
2541
static StaticAutoPtr<AutoTArray<RefPtr<Task>, 8 >> sPendingIdleTasks ;
2521
2542
2522
2543
void nsRefreshDriver::DispatchIdleTaskAfterTickUnlessExists (Task* aTask) {
@@ -2734,9 +2755,22 @@ void nsRefreshDriver::Tick(VsyncId aId, TimeStamp aNowTime,
2734
2755
// Step 12. For each doc of docs, run the fullscreen steps for doc.
2735
2756
RunFullscreenSteps ();
2736
2757
2737
- // Step 14. For each doc of docs, run the video frame callbacks and animation
2738
- // frame callbacks for doc.
2758
+ // TODO: Step 13. For each doc of docs, if the user agent detects that the
2759
+ // backing storage associated with a CanvasRenderingContext2D or an
2760
+ // OffscreenCanvasRenderingContext2D, context, has been lost, then it must run
2761
+ // the context lost steps for each such context.
2762
+
2763
+ // Step 13.5. (https://wicg.github.io/video-rvfc/#video-rvfc-procedures):
2764
+ //
2765
+ // For each fully active Document in docs, for each associated video element
2766
+ // for that Document, run the video frame request callbacks passing now as
2767
+ // the timestamp.
2768
+ //
2769
+ // Step 14. For each doc of docs, run the animation frame callbacks for doc,
2770
+ // passing in the relative high resolution time given frameTimestamp and doc's
2771
+ // relevant global object as the timestamp.
2739
2772
RunVideoAndFrameRequestCallbacks (aNowTime);
2773
+
2740
2774
MaybeIncreaseMeasuredTicksSinceLoading ();
2741
2775
2742
2776
// Step 17. For each doc of docs, if the focused area of doc is not a
0 commit comments