Changeset 260800 in webkit
- Timestamp:
- Apr 27, 2020 5:22:49 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r260797 r260800 1 2020-04-27 Said Abou-Hallawa <sabouhallawa@apple.com> 2 3 Timestamps should be the same for all rendering update steps 4 https://bugs.webkit.org/show_bug.cgi?id=207153 5 6 Reviewed by Simon Fraser. 7 8 * animations/animation-callback-timestamp-expected.txt: 9 * animations/animation-callback-timestamp.html: 10 Ensure the rAF callback timestamp is less than Performance.now(). 11 12 * animations/animation-multiple-callbacks-timestamp-expected.txt: 13 * animations/animation-multiple-callbacks-timestamp.html: 14 Ensure the rAF callbacks receive the same timestamps. 15 16 * intersection-observer/intersection-observer-callback-timestamp-expected.txt: Added. 17 * intersection-observer/intersection-observer-callback-timestamp.html: Added. 18 A new test to ensure the IntersectionObsever and the rAF callbacks receive the same timestamps. 19 20 * platform/ios-wk2/TestExpectations: 21 * platform/mac-wk1/TestExpectations: 22 1 23 2020-04-27 Ryan Haddad <ryanhaddad@apple.com> 2 24 -
trunk/LayoutTests/animations/animation-callback-timestamp-expected.txt
r202399 r260800 1 PASS All the differences between requestAnimationFrame() callback timestamps and Performance.now() were within 3ms. 1 Test performance.now() is at least as the timestamp the rAF callback. 2 3 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". 4 5 6 PASS Math.round(window.performance.now()) is >= Math.round(timestamp1) 7 PASS Math.round(window.performance.now()) is >= Math.round(timestamp1) 8 PASS Math.round(window.performance.now()) is >= Math.round(timestamp1) 9 PASS Math.round(window.performance.now()) is >= Math.round(timestamp1) 10 PASS Math.round(window.performance.now()) is >= Math.round(timestamp1) 11 PASS Math.round(window.performance.now()) is >= Math.round(timestamp1) 12 PASS Math.round(window.performance.now()) is >= Math.round(timestamp1) 13 PASS Math.round(window.performance.now()) is >= Math.round(timestamp1) 14 PASS Math.round(window.performance.now()) is >= Math.round(timestamp1) 15 PASS Math.round(window.performance.now()) is >= Math.round(timestamp1) 2 16 PASS successfullyParsed is true 3 17 -
trunk/LayoutTests/animations/animation-callback-timestamp.html
r236541 r260800 6 6 <body> 7 7 <script> 8 var timestamp1 = 0; 8 9 var currentFrame = 0; 9 var failed = false;10 const MaxFrames = 10; 10 11 11 function finishTest()12 {13 if (failed)14 testFailed("Some of the requestAnimationFrame() callback timestamps were larger than Performance.now() by more than 3ms.");15 else16 testPassed("All the differences between requestAnimationFrame() callback timestamps and Performance.now() were within 3ms.")17 finishJSTest();18 }19 20 12 function doAnimation(timestamp) 21 13 { 22 const Tolerance = 3;23 const WarmupFrames = 5;14 timestamp1 = timestamp; 15 shouldBeGreaterThanOrEqual("Math.round(window.performance.now())", "Math.round(timestamp1)"); 24 16 25 var performanceNow = window.performance.now(); 26 if (++currentFrame > WarmupFrames && Math.abs(timestamp - performanceNow) >= Tolerance) { 27 debug("requestAnimationFrame() timestamp = " + timestamp + ", window.performance.now() = " + performanceNow); 28 failed = true; 17 if (++currentFrame == MaxFrames) { 18 finishJSTest(); 19 return; 29 20 } 30 21 31 const MaxFrames = 25; 32 if (currentFrame == MaxFrames) 33 finishTest(); 34 else 35 requestAnimationFrame(doAnimation); 22 requestAnimationFrame(doAnimation); 36 23 } 37 24 38 25 window.jsTestIsAsync = true; 26 27 description("Test performance.now() is at least as the timestamp the rAF callback."); 39 28 requestAnimationFrame(doAnimation); 40 29 </script> -
trunk/LayoutTests/animations/animation-multiple-callbacks-timestamp-expected.txt
r202399 r260800 1 PASS All the multiple requestAnimationFrame() callbacks, which were fired at the same time, received the same timestamp. 1 Test the timestamps of all the rAF callbacks are the same. 2 3 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". 4 5 6 PASS Math.round(timestamp1) is Math.round(timestamp2) 7 PASS Math.round(timestamp1) is Math.round(timestamp2) 8 PASS Math.round(timestamp1) is Math.round(timestamp2) 9 PASS Math.round(timestamp1) is Math.round(timestamp2) 10 PASS Math.round(timestamp1) is Math.round(timestamp2) 11 PASS Math.round(timestamp1) is Math.round(timestamp2) 12 PASS Math.round(timestamp1) is Math.round(timestamp2) 13 PASS Math.round(timestamp1) is Math.round(timestamp2) 14 PASS Math.round(timestamp1) is Math.round(timestamp2) 15 PASS Math.round(timestamp1) is Math.round(timestamp2) 2 16 PASS successfullyParsed is true 3 17 -
trunk/LayoutTests/animations/animation-multiple-callbacks-timestamp.html
r244182 r260800 6 6 <body> 7 7 <script> 8 var timestamp1 = 0; 9 var timestamp2 = 0; 8 10 var currentFrame = 0; 9 var timestamp1 = 0; 10 var failed = false; 11 12 function finishTest() 13 { 14 if (failed) 15 testFailed("Some of the multiple requestAnimationFrame() callbacks, which were fired at the same time, received different timestamps."); 16 else 17 testPassed("All the multiple requestAnimationFrame() callbacks, which were fired at the same time, received the same timestamp."); 18 finishJSTest(); 19 } 11 const MaxFrames = 10; 20 12 21 13 function doAnimation1(timestamp) 22 14 { 15 if (++currentFrame > MaxFrames) { 16 finishJSTest(); 17 return; 18 } 19 23 20 timestamp1 = timestamp; 24 25 const MaxFrames = 25; 26 if (currentFrame == MaxFrames) 27 finishTest(); 28 else { 29 requestAnimationFrame(doAnimation1); 30 requestAnimationFrame(doAnimation2); 31 } 21 requestAnimationFrame(doAnimation1); 22 requestAnimationFrame(doAnimation2); 32 23 } 33 24 34 25 function doAnimation2(timestamp) 35 26 { 36 const WarmupFrames = 5; 37 if (++currentFrame > WarmupFrames && timestamp != timestamp1) { 38 testFailed("timestamp = " + timestamp + ", timestamp1 = " + timestamp1 + ", window.performance.now() = " + window.performance.now()); 39 failed = true; 40 } 27 timestamp2 = timestamp; 28 shouldBe("Math.round(timestamp1)", "Math.round(timestamp2)"); 41 29 } 42 30 43 31 window.jsTestIsAsync = true; 32 33 description("Test the timestamps of all the rAF callbacks are the same."); 44 34 requestAnimationFrame(doAnimation1); 35 requestAnimationFrame(doAnimation2); 45 36 </script> 46 37 <script src="../resources/js-test-post.js"></script> -
trunk/LayoutTests/platform/ios-wk2/TestExpectations
r260767 r260800 1325 1325 1326 1326 webkit.org/b/205309 scrollingcoordinator/ios/scroll-position-after-reattach.html [ ImageOnlyFailure ] 1327 1328 webkit.org/b/207153 animations/animation-callback-timestamp.html [ Pass Failure ]1329 1327 1330 1328 webkit.org/b/207156 [ Release ] http/tests/websocket/tests/hybi/workers/close.html [ Pass Failure ] -
trunk/LayoutTests/platform/mac-wk1/TestExpectations
r260471 r260800 902 902 webkit.org/b/207560 media/airplay-target-availability.html [ Pass Failure ] 903 903 904 webkit.org/b/207153 [ Debug ] animations/animation-callback-timestamp.html [ Pass Failure ]905 906 904 webkit.org/b/207568 inspector/page/overrideUserAgent.html [ Pass Failure ] 907 905 -
trunk/Source/WebCore/ChangeLog
r260789 r260800 1 2020-04-27 Said Abou-Hallawa <sabouhallawa@apple.com> 2 3 Timestamps should be the same for all rendering update steps 4 https://bugs.webkit.org/show_bug.cgi?id=207153 5 6 Reviewed by Simon Fraser. 7 8 The HTML 5 event loop sepcs states that timestamps should be the same for 9 all rendering update steps. 10 11 Specs link (step 9): 12 https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model 13 14 This patch also fixes some issues in IntersectionObserver. 15 16 Test: intersection-observer/intersection-observer-callback-timestamp.html 17 18 * dom/Document.cpp: 19 (WebCore::Document::updateIntersectionObservations): 20 (WebCore::Document::notifyIntersectionObserversTimerFired): Deleted. 21 * dom/Document.h: 22 -- Handle the case when two floats are areEssentiallyEqual(). 23 -- Execute the IntersectionObserver immediately and do not wait until the 24 next CFRunLoop event since this does not implement the specs. 25 26 * page/DOMWindow.cpp: 27 (WebCore::DOMWindow::freezeNowTimestamp): 28 (WebCore::DOMWindow::unfreezeNowTimestamp): 29 (WebCore::DOMWindow::frozenNowTimestamp const): 30 * page/DOMWindow.h: 31 Provide a frozen now() timestamp in seconds to be used internally only. 32 33 * page/IntersectionObserver.cpp: 34 (WebCore::IntersectionObserver::nowTimestamp const): 35 Use the frozenNowTimestamp(). 36 37 * page/Page.cpp: 38 (WebCore::Page::updateRendering): 39 Freeze the timestamps while serving the rendering update steps. 40 1 41 2020-04-27 Dean Jackson <dino@apple.com> 2 42 -
trunk/Source/WebCore/dom/Document.cpp
r260774 r260800 562 562 #endif 563 563 #if ENABLE(INTERSECTION_OBSERVER) 564 , m_intersectionObserversNotifyTimer(*this, &Document::notifyIntersectionObserversTimerFired)565 564 , m_intersectionObserversInitialUpdateTimer(*this, &Document::scheduleTimedRenderingUpdate) 566 565 #endif … … 7615 7614 return; 7616 7615 7617 m_intersectionObserversInitialUpdateTimer.stop();7618 7619 7616 bool needsLayout = frameView->layoutContext().isLayoutPending() || (renderView() && renderView()->needsLayout()); 7620 7617 if (needsLayout || hasPendingStyleRecalc()) 7621 7618 return; 7619 7620 Vector<WeakPtr<IntersectionObserver>> intersectionObserversWithPendingNotifications; 7622 7621 7623 7622 for (const auto& observer : m_intersectionObservers) { … … 7647 7646 intersectionRatio = 1; 7648 7647 7649 auto& thresholds = observer->thresholds(); 7650 while (thresholdIndex < thresholds.size() && thresholds[thresholdIndex] <= intersectionRatio) 7648 for (auto threshold : observer->thresholds()) { 7649 if (!(threshold <= intersectionRatio || WTF::areEssentiallyEqual<float>(threshold, intersectionRatio))) 7650 break; 7651 7651 ++thresholdIndex; 7652 } 7652 7653 } 7653 7654 } … … 7690 7691 } 7691 7692 if (needNotify) 7692 m_intersectionObserversWithPendingNotifications.append(makeWeakPtr(observer.get())); 7693 } 7694 7695 if (m_intersectionObserversWithPendingNotifications.size()) 7696 m_intersectionObserversNotifyTimer.startOneShot(0_s); 7697 } 7698 7699 void Document::notifyIntersectionObserversTimerFired() 7700 { 7701 for (const auto& observer : m_intersectionObserversWithPendingNotifications) { 7693 intersectionObserversWithPendingNotifications.append(makeWeakPtr(observer.get())); 7694 } 7695 7696 for (const auto& observer : intersectionObserversWithPendingNotifications) { 7702 7697 if (observer) 7703 7698 observer->notify(); 7704 7699 } 7705 m_intersectionObserversWithPendingNotifications.clear();7706 7700 } 7707 7701 -
trunk/Source/WebCore/dom/Document.h
r260736 r260800 1669 1669 bool isNavigationBlockedByThirdPartyIFrameRedirectBlocking(Frame& targetFrame, const URL& destinationURL); 1670 1670 1671 #if ENABLE(INTERSECTION_OBSERVER)1672 void notifyIntersectionObserversTimerFired();1673 #endif1674 1675 1671 #if USE(QUICK_LOOK) 1676 1672 bool shouldEnforceQuickLookSandbox() const; … … 1845 1841 Vector<WeakPtr<IntersectionObserver>> m_intersectionObservers; 1846 1842 Vector<WeakPtr<IntersectionObserver>> m_intersectionObserversWithPendingNotifications; 1847 Timer m_intersectionObserversNotifyTimer;1848 1843 Timer m_intersectionObserversInitialUpdateTimer; 1849 1844 // This is only non-null when this document is an explicit root. -
trunk/Source/WebCore/page/DOMWindow.cpp
r260736 r260800 740 740 } 741 741 742 void DOMWindow::freezeNowTimestamp() 743 { 744 m_frozenNowTimestamp = nowTimestamp(); 745 } 746 747 void DOMWindow::unfreezeNowTimestamp() 748 { 749 m_frozenNowTimestamp = WTF::nullopt; 750 } 751 752 ReducedResolutionSeconds DOMWindow::frozenNowTimestamp() const 753 { 754 return m_frozenNowTimestamp.valueOr(nowTimestamp()); 755 } 756 742 757 Location& DOMWindow::location() 743 758 { -
trunk/Source/WebCore/page/DOMWindow.h
r260736 r260800 352 352 Performance& performance() const; 353 353 WEBCORE_EXPORT ReducedResolutionSeconds nowTimestamp() const; 354 void freezeNowTimestamp(); 355 void unfreezeNowTimestamp(); 356 ReducedResolutionSeconds frozenNowTimestamp() const; 354 357 355 358 #if PLATFORM(IOS_FAMILY) … … 471 474 mutable RefPtr<Performance> m_performance; 472 475 476 Optional<ReducedResolutionSeconds> m_frozenNowTimestamp; 477 473 478 // For the purpose of tracking user activation, each Window W has a last activation timestamp. This is a number indicating the last time W got 474 479 // an activation notification. It corresponds to a DOMHighResTimeStamp value except for two cases: positive infinity indicates that W has never -
trunk/Source/WebCore/page/IntersectionObserver.cpp
r260736 r260800 257 257 auto& document = downcast<Document>(*context); 258 258 if (auto* window = document.domWindow()) 259 return window-> nowTimestamp();259 return window->frozenNowTimestamp(); 260 260 261 261 return WTF::nullopt; -
trunk/Source/WebCore/page/Page.cpp
r260774 r260800 1342 1342 layoutIfNeeded(); 1343 1343 1344 // Timestamps should not change while serving the rendering update steps. 1345 Vector<WeakPtr<Document>> initialDocuments; 1346 forEachDocument([&initialDocuments] (Document& document) { 1347 document.domWindow()->freezeNowTimestamp(); 1348 initialDocuments.append(makeWeakPtr(&document)); 1349 }); 1350 1344 1351 // Flush autofocus candidates 1345 1352 … … 1359 1366 if (!document.domWindow()) 1360 1367 return; 1361 auto timestamp = document.domWindow()-> nowTimestamp();1368 auto timestamp = document.domWindow()->frozenNowTimestamp(); 1362 1369 if (auto* timelinesController = document.timelinesController()) 1363 1370 timelinesController->updateAnimationsAndSendEvents(timestamp); … … 1386 1393 } 1387 1394 }); 1395 1396 for (auto& document : initialDocuments) { 1397 if (document) 1398 document->domWindow()->unfreezeNowTimestamp(); 1399 } 1388 1400 1389 1401 layoutIfNeeded();
Note: See TracChangeset
for help on using the changeset viewer.