Title: [268075] trunk/Source
Revision
268075
Author
simon.fra...@apple.com
Date
2020-10-06 14:33:42 -0700 (Tue, 06 Oct 2020)

Log Message

Redundant rendering updates can be scheduled from inside Page::updateRendering()
https://bugs.webkit.org/show_bug.cgi?id=216726

Reviewed by Tim Horton.

Source/WebCore:

The basic model for scheduling rendering updates is that code that needs to trigger an
update just calls Page::schedule[Timed]RenderingUpdate(). However, if
Page::updateRendering() is already on the stack, and the work to be scheduled will happen
later in the current update, we don't have to schedule a new one.

To fix this Page::updateRendering() and related functions track which steps remain
in the current update, and callers of schedule[Timed]RenderingUpdate() pass the update steps
for the work they need to trigger. If the requested steps are included in the remaining steps
no new update needs to be scheduled. Note that requesting a step while that step is being executed
has to schedule an upate (e.g. requestAnimationFrame inside its own callback has to schedule).

At the end of an update, if there are any unfulfilled steps, then we schedule a new update.

Add a log channel for EventLoop and and log from various places.

In my brief testing, this reduces the number of calls to Page::updateRendering() by 10-25%
on some real pages, which could be a significant power saving.

* animation/DocumentTimeline.cpp:
(WebCore::DocumentTimeline::scheduleAnimationResolution):
* display/DisplayLayerController.cpp:
(WebCore::Display::LayerController::scheduleRenderingUpdate):
* dom/Document.cpp:
(WebCore::Document::setNeedsDOMWindowResizeEvent):
(WebCore::Document::setNeedsVisualViewportResize):
(WebCore::Document::addPendingScrollEventTarget):
(WebCore::Document::setNeedsVisualViewportScrollEvent):
(WebCore::Document::serviceRequestAnimationFrameCallbacks):
(WebCore::Document::intersectionObserversInitialUpdateTimerFired):
(WebCore::Document::scheduleRenderingUpdate):
(WebCore::Document::scheduleInitialIntersectionObservationUpdate):
(WebCore::Document::updateResizeObservations):
(WebCore::Document::updateAnimationsAndSendEvents):
* dom/Document.h:
* dom/ScriptedAnimationController.cpp:
(WebCore::ScriptedAnimationController::scheduleAnimation):
* page/EventHandler.cpp:
(WebCore::EventHandler::scheduleCursorUpdate):
* page/FrameView.cpp:
(WebCore::FrameView::setViewExposedRect):
* page/Page.cpp:
(WebCore::Page::updateStyleAfterChangeInEnvironment):
(WebCore::Page::scheduleRenderingUpdate):
(WebCore::Page::computeUnfulfilledRenderingSteps):
(WebCore::Page::triggerRenderingUpdateForTesting):
(WebCore::Page::updateRendering):
(WebCore::Page::isolatedUpdateRendering):
(WebCore::Page::doAfterUpdateRendering):
(WebCore::Page::finalizeRenderingUpdate):
(WebCore::Page::renderingUpdateCompleted):
(WebCore::Page::accessibilitySettingsDidChange):
(WebCore::Page::appearanceDidChange):
(WebCore::operator<<):
* page/Page.h:
* page/PageOverlayController.cpp:
(WebCore::PageOverlayController::didChangeViewExposedRect):
(WebCore::PageOverlayController::notifyFlushRequired):
* page/RenderingUpdateScheduler.cpp:
(WebCore::RenderingUpdateScheduler::scheduleAnimation):
(WebCore::RenderingUpdateScheduler::scheduleRenderingUpdate):
(WebCore::RenderingUpdateScheduler::startTimer):
(WebCore::RenderingUpdateScheduler::displayRefreshFired):
* page/RenderingUpdateScheduler.h:
* page/ResizeObserver.cpp:
(WebCore::ResizeObserver::observe):
* page/WheelEventTestMonitor.cpp:
(WebCore::WheelEventTestMonitor::setTestCallbackAndStartMonitoring):
(WebCore::WheelEventTestMonitor::scheduleCallbackCheck):
* page/mac/ServicesOverlayController.mm:
(WebCore::ServicesOverlayController::Highlight::notifyFlushRequired):
* page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::AsyncScrollingCoordinator::setEventTrackingRegionsDirty):
* page/scrolling/mac/ScrollingCoordinatorMac.mm:
(WebCore::ScrollingCoordinatorMac::scheduleTreeStateCommit):
* platform/Logging.cpp:
(WebCore::initializeLogChannelsIfNecessary):
* platform/Logging.h:
* rendering/RenderElement.cpp:
(WebCore::RenderElement::scheduleRenderingUpdateForImage):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::notifyFlushRequired):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::scheduleRenderingUpdate):
* rendering/RenderLayerCompositor.h:

Source/WebKit:

Schedule for layer flush.

* WebProcess/WebPage/CoordinatedGraphics/LayerTreeHostTextureMapper.cpp:
(WebKit::LayerTreeHost::layerFlushTimerFired):

Source/WebKitLegacy/mac:

Provide the flags.

* WebView/WebView.mm:
(-[WebView _scheduleRenderingUpdateForPendingTileCacheRepaint]):

Source/WTF:

Make it possible to dump Vectors with inline capacity.

* wtf/text/TextStream.h:
(WTF::operator<<):

Modified Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (268074 => 268075)


--- trunk/Source/WTF/ChangeLog	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WTF/ChangeLog	2020-10-06 21:33:42 UTC (rev 268075)
@@ -1,3 +1,15 @@
+2020-10-06  Simon Fraser  <simon.fra...@apple.com>
+
+        Redundant rendering updates can be scheduled from inside Page::updateRendering()
+        https://bugs.webkit.org/show_bug.cgi?id=216726
+
+        Reviewed by Tim Horton.
+
+        Make it possible to dump Vectors with inline capacity.
+
+        * wtf/text/TextStream.h:
+        (WTF::operator<<):
+
 2020-10-06  Youenn Fablet  <you...@apple.com>
 
         Enable video capture in WebProcess by default on MacOS

Modified: trunk/Source/WTF/wtf/text/TextStream.h (268074 => 268075)


--- trunk/Source/WTF/wtf/text/TextStream.h	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WTF/wtf/text/TextStream.h	2020-10-06 21:33:42 UTC (rev 268075)
@@ -212,8 +212,8 @@
     return ts << "unset";
 }
 
-template<typename Item>
-TextStream& operator<<(TextStream& ts, const Vector<Item>& vector)
+template<typename ItemType, size_t inlineCapacity>
+TextStream& operator<<(TextStream& ts, const Vector<ItemType, inlineCapacity>& vector)
 {
     ts << "[";
 

Modified: trunk/Source/WebCore/ChangeLog (268074 => 268075)


--- trunk/Source/WebCore/ChangeLog	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/ChangeLog	2020-10-06 21:33:42 UTC (rev 268075)
@@ -1,3 +1,95 @@
+2020-10-06  Simon Fraser  <simon.fra...@apple.com>
+
+        Redundant rendering updates can be scheduled from inside Page::updateRendering()
+        https://bugs.webkit.org/show_bug.cgi?id=216726
+
+        Reviewed by Tim Horton.
+
+        The basic model for scheduling rendering updates is that code that needs to trigger an
+        update just calls Page::schedule[Timed]RenderingUpdate(). However, if
+        Page::updateRendering() is already on the stack, and the work to be scheduled will happen
+        later in the current update, we don't have to schedule a new one.
+
+        To fix this Page::updateRendering() and related functions track which steps remain
+        in the current update, and callers of schedule[Timed]RenderingUpdate() pass the update steps
+        for the work they need to trigger. If the requested steps are included in the remaining steps
+        no new update needs to be scheduled. Note that requesting a step while that step is being executed
+        has to schedule an upate (e.g. requestAnimationFrame inside its own callback has to schedule).
+        
+        At the end of an update, if there are any unfulfilled steps, then we schedule a new update.
+
+        Add a log channel for EventLoop and and log from various places.
+
+        In my brief testing, this reduces the number of calls to Page::updateRendering() by 10-25%
+        on some real pages, which could be a significant power saving.
+
+        * animation/DocumentTimeline.cpp:
+        (WebCore::DocumentTimeline::scheduleAnimationResolution):
+        * display/DisplayLayerController.cpp:
+        (WebCore::Display::LayerController::scheduleRenderingUpdate):
+        * dom/Document.cpp:
+        (WebCore::Document::setNeedsDOMWindowResizeEvent):
+        (WebCore::Document::setNeedsVisualViewportResize):
+        (WebCore::Document::addPendingScrollEventTarget):
+        (WebCore::Document::setNeedsVisualViewportScrollEvent):
+        (WebCore::Document::serviceRequestAnimationFrameCallbacks):
+        (WebCore::Document::intersectionObserversInitialUpdateTimerFired):
+        (WebCore::Document::scheduleRenderingUpdate):
+        (WebCore::Document::scheduleInitialIntersectionObservationUpdate):
+        (WebCore::Document::updateResizeObservations):
+        (WebCore::Document::updateAnimationsAndSendEvents):
+        * dom/Document.h:
+        * dom/ScriptedAnimationController.cpp:
+        (WebCore::ScriptedAnimationController::scheduleAnimation):
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::scheduleCursorUpdate):
+        * page/FrameView.cpp:
+        (WebCore::FrameView::setViewExposedRect):
+        * page/Page.cpp:
+        (WebCore::Page::updateStyleAfterChangeInEnvironment):
+        (WebCore::Page::scheduleRenderingUpdate):
+        (WebCore::Page::computeUnfulfilledRenderingSteps):
+        (WebCore::Page::triggerRenderingUpdateForTesting):
+        (WebCore::Page::updateRendering):
+        (WebCore::Page::isolatedUpdateRendering):
+        (WebCore::Page::doAfterUpdateRendering):
+        (WebCore::Page::finalizeRenderingUpdate):
+        (WebCore::Page::renderingUpdateCompleted):
+        (WebCore::Page::accessibilitySettingsDidChange):
+        (WebCore::Page::appearanceDidChange):
+        (WebCore::operator<<):
+        * page/Page.h:
+        * page/PageOverlayController.cpp:
+        (WebCore::PageOverlayController::didChangeViewExposedRect):
+        (WebCore::PageOverlayController::notifyFlushRequired):
+        * page/RenderingUpdateScheduler.cpp:
+        (WebCore::RenderingUpdateScheduler::scheduleAnimation):
+        (WebCore::RenderingUpdateScheduler::scheduleRenderingUpdate):
+        (WebCore::RenderingUpdateScheduler::startTimer):
+        (WebCore::RenderingUpdateScheduler::displayRefreshFired):
+        * page/RenderingUpdateScheduler.h:
+        * page/ResizeObserver.cpp:
+        (WebCore::ResizeObserver::observe):
+        * page/WheelEventTestMonitor.cpp:
+        (WebCore::WheelEventTestMonitor::setTestCallbackAndStartMonitoring):
+        (WebCore::WheelEventTestMonitor::scheduleCallbackCheck):
+        * page/mac/ServicesOverlayController.mm:
+        (WebCore::ServicesOverlayController::Highlight::notifyFlushRequired):
+        * page/scrolling/AsyncScrollingCoordinator.cpp:
+        (WebCore::AsyncScrollingCoordinator::setEventTrackingRegionsDirty):
+        * page/scrolling/mac/ScrollingCoordinatorMac.mm:
+        (WebCore::ScrollingCoordinatorMac::scheduleTreeStateCommit):
+        * platform/Logging.cpp:
+        (WebCore::initializeLogChannelsIfNecessary):
+        * platform/Logging.h:
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::scheduleRenderingUpdateForImage):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::notifyFlushRequired):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::scheduleRenderingUpdate):
+        * rendering/RenderLayerCompositor.h:
+
 2020-10-06  Wenson Hsieh  <wenson_hs...@apple.com>
 
         Rename MediaPlayerPrivateRemoteIdentifier to MediaPlayerIdentifier

Modified: trunk/Source/WebCore/animation/DocumentTimeline.cpp (268074 => 268075)


--- trunk/Source/WebCore/animation/DocumentTimeline.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/animation/DocumentTimeline.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -166,7 +166,7 @@
     if (!shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState())
         return;
 
-    m_document->page()->scheduleRenderingUpdate();
+    m_document->page()->scheduleRenderingUpdate(RenderingUpdateStep::Animations);
     m_animationResolutionScheduled = true;
 }
 

Modified: trunk/Source/WebCore/display/DisplayLayerController.cpp (268074 => 268075)


--- trunk/Source/WebCore/display/DisplayLayerController.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/display/DisplayLayerController.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -125,7 +125,7 @@
     if (!page)
         return;
 
-    page->scheduleRenderingUpdate();
+    page->scheduleRenderingUpdate(RenderingUpdateStep::LayerFlush);
 }
 
 void LayerController::ensureRootLayer(FloatSize viewSize, FloatSize contentSize)

Modified: trunk/Source/WebCore/dom/Document.cpp (268074 => 268075)


--- trunk/Source/WebCore/dom/Document.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/dom/Document.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -560,7 +560,7 @@
     , m_fullscreenManager { makeUniqueRef<FullscreenManager>(*this) }
 #endif
 #if ENABLE(INTERSECTION_OBSERVER)
-    , m_intersectionObserversInitialUpdateTimer(*this, &Document::scheduleRenderingUpdate)
+    , m_intersectionObserversInitialUpdateTimer(*this, &Document::intersectionObserversInitialUpdateTimerFired)
 #endif
     , m_loadEventDelayTimer(*this, &Document::loadEventDelayTimerFired)
 #if PLATFORM(IOS_FAMILY) && ENABLE(DEVICE_ORIENTATION)
@@ -4077,13 +4077,13 @@
 void Document::setNeedsDOMWindowResizeEvent()
 {
     m_needsDOMWindowResizeEvent = true;
-    scheduleRenderingUpdate();
+    scheduleRenderingUpdate(RenderingUpdateStep::Resize);
 }
 
 void Document::setNeedsVisualViewportResize()
 {
     m_needsVisualViewportResizeEvent = true;
-    scheduleRenderingUpdate();
+    scheduleRenderingUpdate(RenderingUpdateStep::Resize);
 }
 
 // https://drafts.csswg.org/cssom-view/#run-the-resize-steps
@@ -4113,7 +4113,7 @@
         return;
 
     if (targets.isEmpty())
-        scheduleRenderingUpdate();
+        scheduleRenderingUpdate(RenderingUpdateStep::Scroll);
 
     targets.append(target);
 }
@@ -4121,7 +4121,7 @@
 void Document::setNeedsVisualViewportScrollEvent()
 {
     if (!m_needsVisualViewportScrollEvent)
-        scheduleRenderingUpdate();
+        scheduleRenderingUpdate(RenderingUpdateStep::Scroll);
     m_needsVisualViewportScrollEvent = true;
 }
 
@@ -6437,10 +6437,10 @@
         m_scriptedAnimationController->resume();
 }
 
-void Document::serviceRequestAnimationFrameCallbacks(ReducedResolutionSeconds timestamp)
+void Document::serviceRequestAnimationFrameCallbacks()
 {
-    if (m_scriptedAnimationController)
-        m_scriptedAnimationController->serviceRequestAnimationFrameCallbacks(timestamp);
+    if (m_scriptedAnimationController && domWindow())
+        m_scriptedAnimationController->serviceRequestAnimationFrameCallbacks(domWindow()->frozenNowTimestamp());
 }
 
 void Document::windowScreenDidChange(PlatformDisplayID displayID)
@@ -7533,13 +7533,23 @@
     m_dynamicMediaQueryDependentImages.remove(element);
 }
 
-void Document::scheduleRenderingUpdate()
+#if ENABLE(INTERSECTION_OBSERVER)
+void Document::intersectionObserversInitialUpdateTimerFired()
 {
+    scheduleRenderingUpdate(RenderingUpdateStep::IntersectionObservations);
+}
+#endif
+
+void Document::scheduleRenderingUpdate(OptionSet<RenderingUpdateStep> requestedSteps)
+{
 #if ENABLE(INTERSECTION_OBSERVER)
-    m_intersectionObserversInitialUpdateTimer.stop();
+    if (m_intersectionObserversInitialUpdateTimer.isActive()) {
+        m_intersectionObserversInitialUpdateTimer.stop();
+        requestedSteps.add(RenderingUpdateStep::IntersectionObservations);
+    }
 #endif
     if (auto page = this->page())
-        page->scheduleRenderingUpdate();
+        page->scheduleRenderingUpdate(requestedSteps);
 }
 
 #if ENABLE(INTERSECTION_OBSERVER)
@@ -7764,7 +7774,7 @@
 void Document::scheduleInitialIntersectionObservationUpdate()
 {
     if (m_readyState == Complete)
-        scheduleRenderingUpdate();
+        scheduleRenderingUpdate(RenderingUpdateStep::IntersectionObservations);
     else if (!m_intersectionObserversInitialUpdateTimer.isActive())
         m_intersectionObserversInitialUpdateTimer.startOneShot(intersectionObserversInitialUpdateDelay);
 }
@@ -7856,7 +7866,7 @@
         getParserLocation(url, line, column);
         reportException("ResizeObserver loop completed with undelivered notifications.", line, column, url, nullptr, nullptr);
         // Starting a new schedule the next round of notify.
-        scheduleRenderingUpdate();
+        scheduleRenderingUpdate(RenderingUpdateStep::ResizeObservations);
     }
 }
 
@@ -8140,6 +8150,16 @@
     return *m_timelinesController.get();
 }
 
+void Document::updateAnimationsAndSendEvents()
+{
+    auto domWindow = this->domWindow();
+    if (!domWindow)
+        return;
+
+    if (auto* timelinesController = this->timelinesController())
+        timelinesController->updateAnimationsAndSendEvents(domWindow->frozenNowTimestamp());
+}
+
 DocumentTimeline& Document::timeline()
 {
     if (!m_timeline)

Modified: trunk/Source/WebCore/dom/Document.h (268074 => 268075)


--- trunk/Source/WebCore/dom/Document.h	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/dom/Document.h	2020-10-06 21:33:42 UTC (rev 268075)
@@ -239,6 +239,7 @@
 
 enum class RouteSharingPolicy : uint8_t;
 enum class ShouldOpenExternalURLsPolicy : uint8_t;
+enum class RenderingUpdateStep : uint16_t;
 
 using PlatformDisplayID = uint32_t;
 
@@ -1069,7 +1070,7 @@
     void suspendScriptedAnimationControllerCallbacks();
     void resumeScriptedAnimationControllerCallbacks();
 
-    void serviceRequestAnimationFrameCallbacks(ReducedResolutionSeconds);
+    void serviceRequestAnimationFrameCallbacks();
 
     void windowScreenDidChange(PlatformDisplayID);
 
@@ -1395,7 +1396,7 @@
     void addDynamicMediaQueryDependentImage(HTMLImageElement&);
     void removeDynamicMediaQueryDependentImage(HTMLImageElement&);
 
-    void scheduleRenderingUpdate();
+    void scheduleRenderingUpdate(OptionSet<RenderingUpdateStep>);
 
 #if ENABLE(INTERSECTION_OBSERVER)
     void addIntersectionObserver(IntersectionObserver&);
@@ -1485,6 +1486,7 @@
 
     WEBCORE_EXPORT void setConsoleMessageListener(RefPtr<StringCallback>&&); // For testing.
 
+    void updateAnimationsAndSendEvents();
     WEBCORE_EXPORT DocumentTimeline& timeline();
     DocumentTimeline* existingTimeline() const { return m_timeline.get(); }
     Vector<RefPtr<WebAnimation>> getAnimations();
@@ -1647,6 +1649,8 @@
 
     void moveNodeIteratorsToNewDocumentSlowCase(Node&, Document&);
 
+    void intersectionObserversInitialUpdateTimerFired();
+
     void loadEventDelayTimerFired();
 
     void pendingTasksTimerFired();

Modified: trunk/Source/WebCore/dom/ScriptedAnimationController.cpp (268074 => 268075)


--- trunk/Source/WebCore/dom/ScriptedAnimationController.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/dom/ScriptedAnimationController.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -181,7 +181,7 @@
         return;
 
     if (auto* page = this->page())
-        page->scheduleRenderingUpdate();
+        page->scheduleRenderingUpdate(RenderingUpdateStep::AnimationFrameCallbacks);
 }
 
 }

Modified: trunk/Source/WebCore/page/EventHandler.cpp (268074 => 268075)


--- trunk/Source/WebCore/page/EventHandler.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -3153,7 +3153,7 @@
         return;
 
     m_hasScheduledCursorUpdate = true;
-    page->scheduleRenderingUpdate();
+    page->scheduleRenderingUpdate(RenderingUpdateStep::CursorUpdate);
 }
 
 void EventHandler::dispatchFakeMouseMoveEventSoon()

Modified: trunk/Source/WebCore/page/FrameView.cpp (268074 => 268075)


--- trunk/Source/WebCore/page/FrameView.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/page/FrameView.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -5435,7 +5435,7 @@
     }
 
     if (auto* page = frame().page()) {
-        page->scheduleRenderingUpdate();
+        page->scheduleRenderingUpdate(RenderingUpdateStep::LayerFlush);
         page->pageOverlayController().didChangeViewExposedRect();
     }
 }

Modified: trunk/Source/WebCore/page/Page.cpp (268074 => 268075)


--- trunk/Source/WebCore/page/Page.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/page/Page.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -144,6 +144,7 @@
 #include <wtf/SystemTracing.h>
 #include <wtf/text/Base64.h>
 #include <wtf/text/StringHash.h>
+#include <wtf/text/TextStream.h>
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
 #include "HTMLVideoElement.h"
@@ -596,7 +597,7 @@
             styleResolver->invalidateMatchedDeclarationsCache();
         document.scheduleFullStyleRebuild();
         document.styleScope().didChangeStyleSheetEnvironment();
-        document.scheduleRenderingUpdate();
+        document.scheduleRenderingUpdate(RenderingUpdateStep::MediaQueryEvaluation);
     });
 }
 
@@ -1406,15 +1407,30 @@
         view->updateLayoutAndStyleIfNeededRecursive();
 }
 
-void Page::scheduleRenderingUpdate()
+void Page::scheduleRenderingUpdate(OptionSet<RenderingUpdateStep> requestedSteps)
 {
-    if (chrome().client().scheduleRenderingUpdate())
+    LOG_WITH_STREAM(EventLoop, stream << "Page " << this << " scheduleTimedRenderingUpdate() - requestedSteps " << requestedSteps << " remaining steps " << m_renderingUpdateRemainingSteps);
+    if (m_renderingUpdateRemainingSteps.isEmpty()) {
+        if (chrome().client().scheduleRenderingUpdate())
+            return;
+        renderingUpdateScheduler().scheduleRenderingUpdate();
         return;
-    renderingUpdateScheduler().scheduleRenderingUpdate();
+    }
+    computeUnfulfilledRenderingSteps(requestedSteps);
 }
 
+void Page::computeUnfulfilledRenderingSteps(OptionSet<RenderingUpdateStep> requestedSteps)
+{
+    // m_renderingUpdateRemainingSteps only has more than one entry for the re-entrant rendering update triggered by testing.
+    // For scheduling, we only care about the value of the first entry.
+    auto remainingSteps = m_renderingUpdateRemainingSteps[0];
+    auto stepsForNextUpdate = requestedSteps - remainingSteps;
+    m_unfulfilledRequestedSteps.add(stepsForNextUpdate);
+}
+
 void Page::triggerRenderingUpdateForTesting()
 {
+    LOG_WITH_STREAM(EventLoop, stream << "Page " << this << " triggerRenderingUpdateForTesting()");
     renderingUpdateScheduler().triggerRenderingUpdateForTesting();
 }
 
@@ -1432,12 +1448,18 @@
 // https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering
 void Page::updateRendering()
 {
-    m_updateRenderingPhaseStack.append(RenderingUpdatePhase::InUpdateRendering);
+    LOG(EventLoop, "Page %p updateRendering() - re-entering %d", this, !m_renderingUpdateRemainingSteps.isEmpty());
 
+    if (m_renderingUpdateRemainingSteps.isEmpty())
+        m_unfulfilledRequestedSteps = { };
+
+    m_renderingUpdateRemainingSteps.append(allRenderingUpdateSteps);
+
     // This function is not reentrant, e.g. a rAF callback may trigger a forces repaint in testing.
-    // This is why we track updateRenderingPhase as a stack.
-    if (m_updateRenderingPhaseStack.size() > 1) {
+    // This is why we track m_renderingUpdateRemainingSteps as a stack.
+    if (m_renderingUpdateRemainingSteps.size() > 1) {
         layoutIfNeeded();
+        m_renderingUpdateRemainingSteps.last().remove(updateRenderingSteps);
         return;
     }
 
@@ -1461,45 +1483,51 @@
         initialDocuments.append(makeWeakPtr(&document));
     });
 
-    // Flush autofocus candidates
+    auto runProcessingStep = [&](RenderingUpdateStep step, const WTF::Function<void(Document&)>& perDocumentFunction) {
+        m_renderingUpdateRemainingSteps.last().remove(step);
+        forEachDocument(perDocumentFunction);
+    };
 
-    forEachDocument([] (Document& document) {
+    // FIXME: Flush autofocus candidates.
+
+    runProcessingStep(RenderingUpdateStep::Resize, [] (Document& document) {
         document.runResizeSteps();
     });
 
-    forEachDocument([] (Document& document) {
+    runProcessingStep(RenderingUpdateStep::Scroll, [] (Document& document) {
         document.runScrollSteps();
     });
 
-    forEachDocument([] (Document& document) {
+    runProcessingStep(RenderingUpdateStep::MediaQueryEvaluation, [] (Document& document) {
         document.evaluateMediaQueriesAndReportChanges();        
     });
 
-    forEachDocument([] (Document& document) {
-        if (!document.domWindow())
-            return;
-        auto timestamp = document.domWindow()->frozenNowTimestamp();
-        if (auto* timelinesController = document.timelinesController())
-            timelinesController->updateAnimationsAndSendEvents(timestamp);
-        // FIXME: Run the fullscreen steps.
-        document.serviceRequestAnimationFrameCallbacks(timestamp);
+    runProcessingStep(RenderingUpdateStep::Animations, [] (Document& document) {
+        document.updateAnimationsAndSendEvents();
     });
 
+    // FIXME: Run the fullscreen steps.
+    m_renderingUpdateRemainingSteps.last().remove(RenderingUpdateStep::Fullscreen);
+
+    runProcessingStep(RenderingUpdateStep::AnimationFrameCallbacks, [] (Document& document) {
+        document.serviceRequestAnimationFrameCallbacks();
+    });
+
     layoutIfNeeded();
 
 #if ENABLE(INTERSECTION_OBSERVER)
-    forEachDocument([] (Document& document) {
+    runProcessingStep(RenderingUpdateStep::IntersectionObservations, [] (Document& document) {
         document.updateIntersectionObservations();
     });
 #endif
 
 #if ENABLE(RESIZE_OBSERVER)
-    forEachDocument([&] (Document& document) {
+    runProcessingStep(RenderingUpdateStep::ResizeObservations, [&] (Document& document) {
         document.updateResizeObservations(*this);
     });
 #endif
 
-    forEachDocument([] (Document& document) {
+    runProcessingStep(RenderingUpdateStep::Images, [] (Document& document) {
         for (auto& image : document.cachedResourceLoader().allCachedSVGImages()) {
             if (auto* page = image->internalPage())
                 page->isolatedUpdateRendering();
@@ -1506,13 +1534,13 @@
         }
     });
 
-    ASSERT(m_updateRenderingPhaseStack.last() == RenderingUpdatePhase::InUpdateRendering);
-
     for (auto& document : initialDocuments) {
         if (document && document->domWindow())
             document->domWindow()->unfreezeNowTimestamp();
     }
 
+    m_renderingUpdateRemainingSteps.last().remove(RenderingUpdateStep::WheelEventMonitorCallbacks);
+
     if (UNLIKELY(isMonitoringWheelEvents()))
         wheelEventTestMonitor()->checkShouldFireCallbacks();
 
@@ -1524,20 +1552,17 @@
 
     if (!isSVGImagePage)
         tracePoint(RenderingUpdateEnd);
-
-    ASSERT(m_updateRenderingPhaseStack.last() == RenderingUpdatePhase::InUpdateRendering);
 }
 
 void Page::isolatedUpdateRendering()
 {
+    LOG(EventLoop, "Page %p isolatedUpdateRendering()", this);
     updateRendering();
-    m_updateRenderingPhaseStack.removeLast();
+    renderingUpdateCompleted();
 }
 
 void Page::doAfterUpdateRendering()
 {
-    ASSERT(m_updateRenderingPhaseStack.last() == RenderingUpdatePhase::InUpdateRendering);
-
     // Code here should do once-per-frame work that needs to be done before painting, and requires
     // layout to be up-to-date. It should not run script, trigger layout, or dirty layout.
 
@@ -1550,7 +1575,12 @@
     }
 #endif
 
-    forEachDocument([] (Document& document) {
+    auto runProcessingStep = [&](RenderingUpdateStep step, const WTF::Function<void(Document&)>& perDocumentFunction) {
+        m_renderingUpdateRemainingSteps.last().remove(step);
+        forEachDocument(perDocumentFunction);
+    };
+
+    runProcessingStep(RenderingUpdateStep::CursorUpdate, [] (Document& document) {
         if (auto* frame = document.frame())
             frame->eventHandler().updateCursorIfNeeded();
     });
@@ -1569,6 +1599,8 @@
     });
 #endif
 
+    m_renderingUpdateRemainingSteps.last().remove(RenderingUpdateStep::EventRegionUpdate);
+
 #if ENABLE(IOS_TOUCH_EVENTS)
     // updateTouchEventRegions() needs to be called only on the top document.
     if (RefPtr<Document> document = mainFrame().document())
@@ -1591,13 +1623,11 @@
         ASSERT(!frameView || !frameView->needsLayout());
     }
 #endif
-
-    ASSERT(m_updateRenderingPhaseStack.last() == RenderingUpdatePhase::InUpdateRendering);
 }
 
 void Page::finalizeRenderingUpdate(OptionSet<FinalizeRenderingUpdateFlags> flags)
 {
-    ASSERT(m_updateRenderingPhaseStack.last() == RenderingUpdatePhase::InUpdateRendering);
+    LOG(EventLoop, "Page %p finalizeRenderingUpdate()", this);
 
     auto* view = mainFrame().view();
     if (!view)
@@ -1606,25 +1636,38 @@
     if (flags.contains(FinalizeRenderingUpdateFlags::InvalidateImagesWithAsyncDecodes))
         view->invalidateImagesWithAsyncDecodes();
 
-    m_updateRenderingPhaseStack.last() = RenderingUpdatePhase::LayerFlushing;
+    m_renderingUpdateRemainingSteps.last().remove(RenderingUpdateStep::LayerFlush);
 
     view->flushCompositingStateIncludingSubframes();
 
-    m_updateRenderingPhaseStack.last() = RenderingUpdatePhase::PostLayerFlush;
+#if ENABLE(ASYNC_SCROLLING)
+    m_renderingUpdateRemainingSteps.last().remove(RenderingUpdateStep::ScrollingTreeUpdate);
 
-#if ENABLE(ASYNC_SCROLLING)
     if (auto* scrollingCoordinator = this->scrollingCoordinator()) {
         scrollingCoordinator->commitTreeStateIfNeeded();
         if (flags.contains(FinalizeRenderingUpdateFlags::ApplyScrollingTreeLayerPositions))
             scrollingCoordinator->applyScrollingTreeLayerPositions();
-            
+
         scrollingCoordinator->didCompleteRenderingUpdate();
     }
 #endif
 
-    m_updateRenderingPhaseStack.removeLast();
+    ASSERT(m_renderingUpdateRemainingSteps.last().isEmpty());
+    renderingUpdateCompleted();
 }
 
+void Page::renderingUpdateCompleted()
+{
+    m_renderingUpdateRemainingSteps.removeLast();
+
+    LOG_WITH_STREAM(EventLoop, stream << "Page " << this << " renderingUpdateCompleted() - steps " << m_renderingUpdateRemainingSteps << " unfulfilled steps " << m_unfulfilledRequestedSteps);
+
+    if (m_unfulfilledRequestedSteps) {
+        renderingUpdateScheduler().scheduleRenderingUpdate();
+        m_unfulfilledRequestedSteps = { };
+    }
+}
+
 void Page::suspendScriptedAnimations()
 {
     m_scriptedAnimationsSuspended = true;
@@ -2926,7 +2969,7 @@
     forEachDocument([] (auto& document) {
         document.styleScope().evaluateMediaQueriesForAccessibilitySettingsChange();
         document.updateElementsAffectedByMediaQueries();
-        document.scheduleRenderingUpdate();
+        document.scheduleRenderingUpdate(RenderingUpdateStep::MediaQueryEvaluation);
     });
 }
 
@@ -2936,7 +2979,7 @@
         document.styleScope().didChangeStyleSheetEnvironment();
         document.styleScope().evaluateMediaQueriesForAppearanceChange();
         document.updateElementsAffectedByMediaQueries();
-        document.scheduleRenderingUpdate();
+        document.scheduleRenderingUpdate(RenderingUpdateStep::MediaQueryEvaluation);
     });
 }
 
@@ -3301,4 +3344,29 @@
     m_userStyleSheetsPendingInjection.clear();
 }
 
+WTF::TextStream& operator<<(WTF::TextStream& ts, RenderingUpdateStep step)
+{
+    switch (step) {
+    case RenderingUpdateStep::Resize: ts << "Resize"; break;
+    case RenderingUpdateStep::Scroll: ts << "Scroll"; break;
+    case RenderingUpdateStep::MediaQueryEvaluation: ts << "MediaQueryEvaluation"; break;
+    case RenderingUpdateStep::Animations: ts << "Animations"; break;
+    case RenderingUpdateStep::Fullscreen: ts << "Fullscreen"; break;
+    case RenderingUpdateStep::AnimationFrameCallbacks: ts << "AnimationFrameCallbacks"; break;
+#if ENABLE(INTERSECTION_OBSERVER)
+    case RenderingUpdateStep::IntersectionObservations: ts << "IntersectionObservations"; break;
+#endif
+#if ENABLE(RESIZE_OBSERVER)
+    case RenderingUpdateStep::ResizeObservations: ts << "ResizeObservations"; break;
+#endif
+    case RenderingUpdateStep::Images: ts << "Images"; break;
+    case RenderingUpdateStep::WheelEventMonitorCallbacks: ts << "WheelEventMonitorCallbacks"; break;
+    case RenderingUpdateStep::CursorUpdate: ts << "CursorUpdate"; break;
+    case RenderingUpdateStep::EventRegionUpdate: ts << "EventRegionUpdate"; break;
+    case RenderingUpdateStep::LayerFlush: ts << "LayerFlush"; break;
+    case RenderingUpdateStep::ScrollingTreeUpdate: ts << "ScrollingTreeUpdate"; break;
+    }
+    return ts;
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/page/Page.h (268074 => 268075)


--- trunk/Source/WebCore/page/Page.h	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/page/Page.h	2020-10-06 21:33:42 UTC (rev 268075)
@@ -74,6 +74,10 @@
 class Debugger;
 }
 
+namespace WTF {
+class TextStream;
+}
+
 namespace WebCore {
 
 namespace IDBClient {
@@ -169,6 +173,52 @@
     InvalidateImagesWithAsyncDecodes    = 1 << 1,
 };
 
+enum class RenderingUpdateStep : uint16_t {
+    Resize                          = 1 << 0,
+    Scroll                          = 1 << 1,
+    MediaQueryEvaluation            = 1 << 2,
+    Animations                      = 1 << 3,
+    Fullscreen                      = 1 << 4,
+    AnimationFrameCallbacks         = 1 << 5,
+#if ENABLE(INTERSECTION_OBSERVER)
+    IntersectionObservations        = 1 << 6,
+#endif
+#if ENABLE(RESIZE_OBSERVER)
+    ResizeObservations              = 1 << 7,
+#endif
+    Images                          = 1 << 8,
+    WheelEventMonitorCallbacks      = 1 << 9,
+    CursorUpdate                    = 1 << 10,
+    EventRegionUpdate               = 1 << 11,
+    LayerFlush                      = 1 << 12,
+    ScrollingTreeUpdate             = 1 << 13,
+};
+
+constexpr OptionSet<RenderingUpdateStep> updateRenderingSteps = {
+    RenderingUpdateStep::Resize,
+    RenderingUpdateStep::Scroll,
+    RenderingUpdateStep::MediaQueryEvaluation,
+    RenderingUpdateStep::Animations,
+    RenderingUpdateStep::Fullscreen,
+    RenderingUpdateStep::AnimationFrameCallbacks,
+#if ENABLE(INTERSECTION_OBSERVER)
+    RenderingUpdateStep::IntersectionObservations,
+#endif
+#if ENABLE(RESIZE_OBSERVER)
+    RenderingUpdateStep::ResizeObservations,
+#endif
+    RenderingUpdateStep::Images,
+    RenderingUpdateStep::WheelEventMonitorCallbacks,
+    RenderingUpdateStep::CursorUpdate,
+    RenderingUpdateStep::EventRegionUpdate,
+};
+
+constexpr auto allRenderingUpdateSteps = updateRenderingSteps | OptionSet<RenderingUpdateStep> {
+    RenderingUpdateStep::LayerFlush,
+    RenderingUpdateStep::ScrollingTreeUpdate,
+};
+
+
 class Page : public Supplementable<Page>, public CanMakeWeakPtr<Page> {
     WTF_MAKE_NONCOPYABLE(Page);
     WTF_MAKE_FAST_ALLOCATED;
@@ -489,7 +539,7 @@
     WEBCORE_EXPORT void finalizeRenderingUpdate(OptionSet<FinalizeRenderingUpdateFlags>);
 
     // Schedule a rerndering update that coordinates with display refresh.
-    WEBCORE_EXPORT void scheduleRenderingUpdate();
+    WEBCORE_EXPORT void scheduleRenderingUpdate(OptionSet<RenderingUpdateStep> requestedSteps);
     // Trigger a rendering update in the current runloop. Only used for testing.
     void triggerRenderingUpdateForTesting();
 
@@ -771,13 +821,6 @@
     MonotonicTime lastRenderingUpdateTimestamp() const { return m_lastRenderingUpdateTimestamp; }
 
 private:
-    enum class RenderingUpdatePhase : uint8_t {
-        Outside,
-        InUpdateRendering,
-        LayerFlushing,
-        PostLayerFlush
-    };
-
     struct Navigation {
         RegistrableDomain domain;
         FrameLoadType type;
@@ -813,6 +856,8 @@
     void domTimerAlignmentIntervalIncreaseTimerFired();
 
     void doAfterUpdateRendering();
+    void renderingUpdateCompleted();
+    void computeUnfulfilledRenderingSteps(OptionSet<RenderingUpdateStep>);
 
     RenderingUpdateScheduler& renderingUpdateScheduler();
 
@@ -1022,8 +1067,9 @@
     bool m_isEditableRegionEnabled { false };
 #endif
 
-    Vector<RenderingUpdatePhase, 2> m_updateRenderingPhaseStack;
-
+    Vector<OptionSet<RenderingUpdateStep>, 2> m_renderingUpdateRemainingSteps;
+    OptionSet<RenderingUpdateStep> m_unfulfilledRequestedSteps;
+    
     UserInterfaceLayoutDirection m_userInterfaceLayoutDirection { UserInterfaceLayoutDirection::LTR };
     
     // For testing.
@@ -1085,4 +1131,6 @@
     return *m_group;
 }
 
+WTF::TextStream& operator<<(WTF::TextStream&, RenderingUpdateStep);
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/page/PageOverlayController.cpp (268074 => 268075)


--- trunk/Source/WebCore/page/PageOverlayController.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/page/PageOverlayController.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -318,7 +318,7 @@
 
 void PageOverlayController::didChangeViewExposedRect()
 {
-    m_page.scheduleRenderingUpdate();
+    m_page.scheduleRenderingUpdate(RenderingUpdateStep::LayerFlush);
 }
 
 void PageOverlayController::didScrollFrame(Frame& frame)
@@ -412,7 +412,7 @@
 
 void PageOverlayController::notifyFlushRequired(const GraphicsLayer*)
 {
-    m_page.scheduleRenderingUpdate();
+    m_page.scheduleRenderingUpdate(RenderingUpdateStep::LayerFlush);
 }
 
 void PageOverlayController::didChangeOverlayFrame(PageOverlay& overlay)

Modified: trunk/Source/WebCore/page/RenderingUpdateScheduler.cpp (268074 => 268075)


--- trunk/Source/WebCore/page/RenderingUpdateScheduler.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/page/RenderingUpdateScheduler.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -29,8 +29,10 @@
 #include "Chrome.h"
 #include "ChromeClient.h"
 #include "DisplayRefreshMonitorManager.h"
+#include "Logging.h"
 #include "Page.h"
 #include <wtf/SystemTracing.h>
+#include <wtf/text/TextStream.h>
 
 namespace WebCore {
 
@@ -58,7 +60,11 @@
         return false;
 #endif
     setPreferredFramesPerSecond(preferredFramesPerSecond);
-    return DisplayRefreshMonitorManager::sharedManager().scheduleAnimation(*this);
+    auto result = DisplayRefreshMonitorManager::sharedManager().scheduleAnimation(*this);
+
+    LOG_WITH_STREAM(EventLoop, stream << "RenderingUpdateScheduler for page " << &m_page << " scheduleAnimation(" << preferredFramesPerSecond << "fps) - scheduled " << result);
+
+    return result;
 }
 
 void RenderingUpdateScheduler::adjustRenderingUpdateFrequency()
@@ -77,6 +83,8 @@
 
 void RenderingUpdateScheduler::scheduleRenderingUpdate()
 {
+    LOG_WITH_STREAM(EventLoop, stream << "RenderingUpdateScheduler for page " << &m_page << " scheduleTimedRenderingUpdate() - already scheduled " << isScheduled() << " page visible " << m_page.isVisible());
+
     if (isScheduled())
         return;
 
@@ -106,6 +114,8 @@
     
 void RenderingUpdateScheduler::startTimer(Seconds delay)
 {
+    LOG_WITH_STREAM(EventLoop, stream << "RenderingUpdateScheduler for page " << &m_page << " startTimer(" << delay << ")");
+
     ASSERT(!isScheduled());
     m_refreshTimer = makeUnique<Timer>(*this, &RenderingUpdateScheduler::displayRefreshFired);
     m_refreshTimer->startOneShot(delay);
@@ -133,6 +143,8 @@
 
 void RenderingUpdateScheduler::displayRefreshFired()
 {
+    LOG_WITH_STREAM(EventLoop, stream << "RenderingUpdateScheduler for page " << &m_page << " displayRefreshFired()");
+
     tracePoint(TriggerRenderingUpdate);
 
     clearScheduled();

Modified: trunk/Source/WebCore/page/RenderingUpdateScheduler.h (268074 => 268075)


--- trunk/Source/WebCore/page/RenderingUpdateScheduler.h	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/page/RenderingUpdateScheduler.h	2020-10-06 21:33:42 UTC (rev 268075)
@@ -65,9 +65,9 @@
     void triggerRenderingUpdate();
 
     Page& m_page;
-    bool m_scheduled { false };
     std::unique_ptr<Timer> m_refreshTimer;
     FramesPerSecond m_preferredFramesPerSecond { FullSpeedFramesPerSecond };
+    bool m_scheduled { false };
 };
 
 }

Modified: trunk/Source/WebCore/page/ResizeObserver.cpp (268074 => 268075)


--- trunk/Source/WebCore/page/ResizeObserver.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/page/ResizeObserver.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -74,7 +74,7 @@
 
     if (m_document) {
         m_document->addResizeObserver(*this);
-        m_document->scheduleRenderingUpdate();
+        m_document->scheduleRenderingUpdate(RenderingUpdateStep::ResizeObservations);
     }
 }
 

Modified: trunk/Source/WebCore/page/WheelEventTestMonitor.cpp (268074 => 268075)


--- trunk/Source/WebCore/page/WheelEventTestMonitor.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/page/WheelEventTestMonitor.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -72,7 +72,7 @@
     UNUSED_PARAM(expectMomentumEnd);
 #endif
 
-    m_page.scheduleRenderingUpdate();
+    m_page.scheduleRenderingUpdate(RenderingUpdateStep::WheelEventMonitorCallbacks);
 
     LOG_WITH_STREAM(WheelEventTestMonitor, stream << "  WheelEventTestMonitor::setTestCallbackAndStartMonitoring - expect end/cancel " << expectWheelEndOrCancel << ", expect momentum end " << expectMomentumEnd);
 }
@@ -121,13 +121,13 @@
 void WheelEventTestMonitor::scheduleCallbackCheck()
 {
     if (isMainThread()) {
-        m_page.scheduleRenderingUpdate();
+        m_page.scheduleRenderingUpdate(RenderingUpdateStep::WheelEventMonitorCallbacks);
         return;
     }
 
     RunLoop::main().dispatch([weakPage = makeWeakPtr(m_page)] {
         if (weakPage)
-            weakPage->scheduleRenderingUpdate();
+            weakPage->scheduleRenderingUpdate(RenderingUpdateStep::WheelEventMonitorCallbacks);
     });
 }
 

Modified: trunk/Source/WebCore/page/linux/ResourceUsageOverlayLinux.cpp (268074 => 268075)


--- trunk/Source/WebCore/page/linux/ResourceUsageOverlayLinux.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/page/linux/ResourceUsageOverlayLinux.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -124,7 +124,7 @@
 
     void notifyFlushRequired(const GraphicsLayer*) override
     {
-        m_overlay.overlay().page()->scheduleRenderingUpdate();
+        m_overlay.overlay().page()->scheduleRenderingUpdate(RenderingUpdateStep::LayerFlush);
     }
 
     ResourceUsageOverlay& m_overlay;

Modified: trunk/Source/WebCore/page/mac/ServicesOverlayController.mm (268074 => 268075)


--- trunk/Source/WebCore/page/mac/ServicesOverlayController.mm	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/page/mac/ServicesOverlayController.mm	2020-10-06 21:33:42 UTC (rev 268075)
@@ -121,7 +121,7 @@
     if (!m_controller)
         return;
 
-    m_controller->page().scheduleRenderingUpdate();
+    m_controller->page().scheduleRenderingUpdate(RenderingUpdateStep::LayerFlush);
 }
 
 void ServicesOverlayController::Highlight::paintContents(const GraphicsLayer*, GraphicsContext& graphicsContext, const FloatRect&, GraphicsLayerPaintBehavior)

Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp (268074 => 268075)


--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -123,6 +123,7 @@
 {
     m_eventTrackingRegionsDirty = true;
     // We have to schedule a commit, but the computed non-fast region may not have actually changed.
+    // FIXME: This needs to disambiguate between event regions in the scrolling tree, and those in GraphicsLayers.
     scheduleTreeStateCommit();
 }
 

Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm (268074 => 268075)


--- trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm	2020-10-06 21:33:42 UTC (rev 268075)
@@ -95,7 +95,8 @@
 
 void ScrollingCoordinatorMac::scheduleTreeStateCommit()
 {
-    m_page->scheduleRenderingUpdate();
+    // FIXME: This one needs work.
+    m_page->scheduleRenderingUpdate(RenderingUpdateStep::ScrollingTreeUpdate);
 }
 
 void ScrollingCoordinatorMac::commitTreeStateIfNeeded()

Modified: trunk/Source/WebCore/platform/Logging.cpp (268074 => 268075)


--- trunk/Source/WebCore/platform/Logging.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/platform/Logging.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -90,6 +90,7 @@
 
     String enabledChannelsString = logChannelString ? logChannelString.value() : logLevelString();
     WTFInitializeLogChannelStatesFromString(logChannels, logChannelCount, enabledChannelsString.utf8().data());
+//    LogEventLoop.state = WTFLogChannelState::On;
 }
 
 WTFLogChannel* getLogChannel(const String& name)

Modified: trunk/Source/WebCore/platform/Logging.h (268074 => 268075)


--- trunk/Source/WebCore/platform/Logging.h	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/platform/Logging.h	2020-10-06 21:33:42 UTC (rev 268075)
@@ -56,6 +56,7 @@
     M(Editing) \
     M(EME) \
     M(Events) \
+    M(EventLoop) \
     M(EventRegions) \
     M(FileAPI) \
     M(Filters) \

Modified: trunk/Source/WebCore/rendering/RenderElement.cpp (268074 => 268075)


--- trunk/Source/WebCore/rendering/RenderElement.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/rendering/RenderElement.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -1406,7 +1406,7 @@
 void RenderElement::scheduleRenderingUpdateForImage(CachedImage&)
 {
     if (auto* page = document().page())
-        page->scheduleRenderingUpdate();
+        page->scheduleRenderingUpdate(RenderingUpdateStep::Images);
 }
 
 bool RenderElement::repaintForPausedImageAnimationsIfNeeded(const IntRect& visibleRect, CachedImage& cachedImage)

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (268074 => 268075)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -3648,11 +3648,12 @@
 {
 }
 
-void RenderLayerBacking::notifyFlushRequired(const GraphicsLayer*)
+void RenderLayerBacking::notifyFlushRequired(const GraphicsLayer* layer)
 {
     if (renderer().renderTreeBeingDestroyed())
         return;
-    compositor().scheduleRenderingUpdate();
+
+    compositor().notifyFlushRequired(layer);
 }
 
 void RenderLayerBacking::notifyFlushBeforeDisplayRefresh(const GraphicsLayer* layer)

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (268074 => 268075)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -526,7 +526,7 @@
 {
     ASSERT(!m_flushingLayers);
 
-    page().scheduleRenderingUpdate();
+    page().scheduleRenderingUpdate(RenderingUpdateStep::LayerFlush);
 }
 
 FloatRect RenderLayerCompositor::visibleRectForLayerFlushing() const

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.h (268074 => 268075)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2020-10-06 21:33:42 UTC (rev 268075)
@@ -178,7 +178,7 @@
 
     // GraphicsLayers buffer state, which gets pushed to the underlying platform layers
     // at specific times.
-    void scheduleRenderingUpdate();
+    void notifyFlushRequired(const GraphicsLayer*) override;
     void flushPendingLayerChanges(bool isFlushRoot = true);
 
     // Called when the GraphicsLayer for the given RenderLayer has flushed changes inside of flushPendingLayerChanges().
@@ -396,7 +396,6 @@
     bool updateCompositingPolicy();
     
     // GraphicsLayerClient implementation
-    void notifyFlushRequired(const GraphicsLayer*) override;
     void paintContents(const GraphicsLayer*, GraphicsContext&, const FloatRect&, GraphicsLayerPaintBehavior) override;
     void customPositionForVisibleRectComputation(const GraphicsLayer*, FloatPoint&) const override;
     bool isTrackingRepaints() const override { return m_isTrackingRepaints; }
@@ -454,6 +453,8 @@
 
     bool needsCompositingForContentOrOverlays() const;
 
+    void scheduleRenderingUpdate();
+
     void ensureRootLayer();
     void destroyRootLayer();
 

Modified: trunk/Source/WebKit/ChangeLog (268074 => 268075)


--- trunk/Source/WebKit/ChangeLog	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebKit/ChangeLog	2020-10-06 21:33:42 UTC (rev 268075)
@@ -1,3 +1,15 @@
+2020-10-06  Simon Fraser  <simon.fra...@apple.com>
+
+        Redundant rendering updates can be scheduled from inside Page::updateRendering()
+        https://bugs.webkit.org/show_bug.cgi?id=216726
+
+        Reviewed by Tim Horton.
+
+        Schedule for layer flush.
+
+        * WebProcess/WebPage/CoordinatedGraphics/LayerTreeHostTextureMapper.cpp:
+        (WebKit::LayerTreeHost::layerFlushTimerFired):
+
 2020-10-06  Alex Christensen  <achristen...@webkit.org>
 
         Use sendWithAsyncReply to evaluate _javascript_ in a WebPage

Modified: trunk/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHostTextureMapper.cpp (268074 => 268075)


--- trunk/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHostTextureMapper.cpp	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHostTextureMapper.cpp	2020-10-06 21:33:42 UTC (rev 268075)
@@ -97,7 +97,7 @@
 
     // In case an animation is running, we should flush again soon.
     if (downcast<GraphicsLayerTextureMapper>(m_rootLayer.get())->layer().descendantsOrSelfHaveRunningAnimations())
-        m_webPage.corePage()->scheduleRenderingUpdate();
+        m_webPage.corePage()->scheduleRenderingUpdate(RenderingUpdateStep::LayerFlush);
 }
 
 LayerTreeHost::LayerTreeHost(WebPage& webPage)

Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (268074 => 268075)


--- trunk/Source/WebKitLegacy/mac/ChangeLog	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog	2020-10-06 21:33:42 UTC (rev 268075)
@@ -1,3 +1,15 @@
+2020-10-06  Simon Fraser  <simon.fra...@apple.com>
+
+        Redundant rendering updates can be scheduled from inside Page::updateRendering()
+        https://bugs.webkit.org/show_bug.cgi?id=216726
+
+        Reviewed by Tim Horton.
+
+        Provide the flags.
+
+        * WebView/WebView.mm:
+        (-[WebView _scheduleRenderingUpdateForPendingTileCacheRepaint]):
+
 2020-10-05  Simon Fraser  <simon.fra...@apple.com>
 
         Use the "triggerRenderingUpdate" terminology in ChromeClient

Modified: trunk/Source/WebKitLegacy/mac/WebView/WebView.mm (268074 => 268075)


--- trunk/Source/WebKitLegacy/mac/WebView/WebView.mm	2020-10-06 21:21:44 UTC (rev 268074)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebView.mm	2020-10-06 21:33:42 UTC (rev 268075)
@@ -9082,7 +9082,7 @@
 - (void)_scheduleRenderingUpdateForPendingTileCacheRepaint
 {
     if (auto* page = _private->page)
-        page->scheduleRenderingUpdate();
+        page->scheduleRenderingUpdate(WebCore::RenderingUpdateStep::LayerFlush);
 }
 #endif
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to