Changeset 215259 in webkit


Ignore:
Timestamp:
Apr 11, 2017 11:50:50 PM (7 years ago)
Author:
zandobersek@gmail.com
Message:

[GTK] Use the DisplayRefreshMonitor facilities
https://bugs.webkit.org/show_bug.cgi?id=170599

Reviewed by Carlos Garcia Campos.

Source/WebCore:

  • CMakeLists.txt: Add missing files to the build.
  • platform/graphics/DisplayRefreshMonitor.cpp: Build fixes.

(WebCore::DisplayRefreshMonitor::createDefaultDisplayRefreshMonitor):

  • platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp:

(WebCore::CoordinatedGraphicsLayer::updatePlatformLayer): Mark the
platform layer as updated in the layer's CoordinatedGraphicsState.

  • platform/graphics/texmap/coordinated/CoordinatedGraphicsState.h:

Source/WebKit2:

ThreadedCompositor gains a DisplayRefreshMonitor member that it can use
to better coordinate display refresh callbacks on the main thread. Still,
because currently the GTK+ port doesn't have a reliable way of notifying
the ThreadedCompositor of a vsync event, a timer targeting 60FPS is used
in order to keep the updates at a reasonable rate. When the timer is fired,
the ThreadedCompositor decides how to proceed based on state changes that
might have occurred during composition or whether there's any display
refresh callbacks that require handling on the main thread.

CompositingRunLoop now stores its state in an atomic variable that's then
inspected whenever a new update is scheduled or completed. When scheduled,
if there's no update in progress, a new update is requested through the
timer. If there's already an update in progress, a new update is marked
as pending after the current one completes. In that case, when the update
is completed, a new update is requested through the timer.

ThreadedDisplayRefreshMonitor is used to coordinate updates between the
main and the composition thread whenever the CoordinatedGraphics state
demands it, or whenever there are clients registered to that monitor that
require an update (e.g. a requestAnimationFrame() callback). After the
update on the composition thread is finished, and the DisplayRefreshMonitor
object requires an update, a callback at the same priority as the layer
flush timer is scheduled on the main thread. In that callback we handle
any clients registered for this DisplayRefreshMonitor before proceeding
to handle any changes to the CoordinatedGraphics scene. In case the
DisplayRefreshMonitor clients or the layer flushes already queued up
any changes to the state, we immediately ask the ThreadedCompositor for
an update.

  • PlatformGTK.cmake:
  • Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp:

(WebKit::CoordinatedGraphicsScene::updateViewport):
(WebKit::CoordinatedGraphicsScene::commitSceneState):

  • Shared/CoordinatedGraphics/CoordinatedGraphicsScene.h:
  • Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp:

(WebKit::CompositingRunLoop::CompositingRunLoop):
(WebKit::CompositingRunLoop::isActive):
(WebKit::CompositingRunLoop::scheduleUpdate):
(WebKit::CompositingRunLoop::stopUpdates):
(WebKit::CompositingRunLoop::updateCompleted):
(WebKit::CompositingRunLoop::updateTimerFired):
(WebKit::CompositingRunLoop::isCurrent):
(WebKit::CompositingRunLoop::startUpdateTimer): Deleted.
(WebKit::CompositingRunLoop::stopUpdateTimer): Deleted.

  • Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.h:

(): Deleted.

  • Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp:

(WebKit::m_displayRefreshMonitor):
(WebKit::ThreadedCompositor::invalidate):
(WebKit::ThreadedCompositor::setNativeSurfaceHandleForCompositing):
(WebKit::ThreadedCompositor::updateViewport):
(WebKit::ThreadedCompositor::scheduleDisplayImmediately):
(WebKit::ThreadedCompositor::renderLayerTree):
(WebKit::ThreadedCompositor::sceneUpdateFinished):
(WebKit::ThreadedCompositor::updateSceneState):
(WebKit::ThreadedCompositor::displayRefreshMonitor):
(WebKit::ThreadedCompositor::renderNextFrameIfNeeded):
(WebKit::ThreadedCompositor::completeCoordinatedUpdateIfNeeded):
(WebKit::ThreadedCompositor::coordinateUpdateCompletionWithClient):
(WebKit::ThreadedCompositor::performFrameCompletion):

  • Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h:
  • Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.cpp: Added.

(WebKit::ThreadedDisplayRefreshMonitor::ThreadedDisplayRefreshMonitor):
(WebKit::ThreadedDisplayRefreshMonitor::requestRefreshCallback):
(WebKit::ThreadedDisplayRefreshMonitor::requiresDisplayRefreshCallback):
(WebKit::ThreadedDisplayRefreshMonitor::dispatchDisplayRefreshCallback):
(WebKit::ThreadedDisplayRefreshMonitor::invalidate):
(WebKit::ThreadedDisplayRefreshMonitor::displayRefreshCallback):

  • Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.h: Copied from Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.h.
  • WebProcess/WebPage/AcceleratedDrawingArea.cpp:

(WebKit::AcceleratedDrawingArea::createDisplayRefreshMonitor):

  • WebProcess/WebPage/AcceleratedDrawingArea.h:
  • WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.cpp:

(WebKit::ThreadedCoordinatedLayerTreeHost::createDisplayRefreshMonitor):

  • WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h:
  • WebProcess/WebPage/LayerTreeHost.h:

(WebKit::LayerTreeHost::createDisplayRefreshMonitor):

Source/WTF:

  • wtf/Platform.h: Enable USE_REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR for the GTK+ port.
  • wtf/glib/RunLoopSourcePriority.h: Add the DisplayRefreshMonitorTimer entry that

matches the value of LayerFlushTimer.

Location:
trunk/Source
Files:
2 added
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r215241 r215259  
     12017-04-11  Zan Dobersek  <zdobersek@igalia.com>
     2
     3        [GTK] Use the DisplayRefreshMonitor facilities
     4        https://bugs.webkit.org/show_bug.cgi?id=170599
     5
     6        Reviewed by Carlos Garcia Campos.
     7
     8        * wtf/Platform.h: Enable USE_REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR for the GTK+ port.
     9        * wtf/glib/RunLoopSourcePriority.h: Add the DisplayRefreshMonitorTimer entry that
     10        matches the value of LayerFlushTimer.
     11
    1122017-04-11  Yusuke Suzuki  <utatane.tea@gmail.com>
    213
  • trunk/Source/WTF/wtf/Platform.h

    r215220 r215259  
    10491049#endif
    10501050
    1051 #if PLATFORM(COCOA)
     1051#if PLATFORM(COCOA) || PLATFORM(GTK)
    10521052#define USE_REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR 1
    10531053#endif
  • trunk/Source/WTF/wtf/glib/RunLoopSourcePriority.h

    r215088 r215259  
    6565    LayerFlushTimer = -100,
    6666
     67    // DisplayRefreshMonitor timer, should have the same value as the LayerFlushTimer.
     68    DisplayRefreshMonitorTimer = -100,
     69
    6770    // Rendering timer in the main thread when accelerated compositing is not used.
    6871    NonAcceleratedDrawingTimer = 100
  • trunk/Source/WebCore/CMakeLists.txt

    r215131 r215259  
    22542254    platform/graphics/ComplexTextController.cpp
    22552255    platform/graphics/CrossfadeGeneratedImage.cpp
     2256    platform/graphics/DisplayRefreshMonitor.cpp
    22562257    platform/graphics/DisplayRefreshMonitorClient.cpp
     2258    platform/graphics/DisplayRefreshMonitorManager.cpp
    22572259    platform/graphics/ExtendedColor.cpp
    22582260    platform/graphics/FloatPoint.cpp
  • trunk/Source/WebCore/ChangeLog

    r215254 r215259  
     12017-04-11  Zan Dobersek  <zdobersek@igalia.com>
     2
     3        [GTK] Use the DisplayRefreshMonitor facilities
     4        https://bugs.webkit.org/show_bug.cgi?id=170599
     5
     6        Reviewed by Carlos Garcia Campos.
     7
     8        * CMakeLists.txt: Add missing files to the build.
     9        * platform/graphics/DisplayRefreshMonitor.cpp: Build fixes.
     10        (WebCore::DisplayRefreshMonitor::createDefaultDisplayRefreshMonitor):
     11        * platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp:
     12        (WebCore::CoordinatedGraphicsLayer::updatePlatformLayer): Mark the
     13        platform layer as updated in the layer's CoordinatedGraphicsState.
     14        * platform/graphics/texmap/coordinated/CoordinatedGraphicsState.h:
     15
    1162017-04-11  Antoine Quint  <graouts@apple.com>
    217
  • trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp

    r202399 r215259  
    3434#if PLATFORM(IOS)
    3535#include "DisplayRefreshMonitorIOS.h"
    36 #else
     36#elif PLATFORM(MAC)
    3737#include "DisplayRefreshMonitorMac.h"
    3838#endif
     
    4848    return DisplayRefreshMonitorIOS::create(displayID);
    4949#endif
     50    UNUSED_PARAM(displayID);
    5051    return nullptr;
    5152}
  • trunk/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp

    r215160 r215259  
    715715
    716716    m_shouldUpdatePlatformLayer = false;
     717    m_layerState.platformLayerUpdated = true;
    717718    if (m_platformLayer)
    718719        m_platformLayer->swapBuffersIfNeeded();
  • trunk/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsState.h

    r213989 r215259  
    8787            bool repaintCountChanged : 1;
    8888            bool platformLayerChanged: 1;
     89            bool platformLayerUpdated: 1;
    8990            bool platformLayerShouldSwapBuffers: 1;
    9091            bool isScrollableChanged: 1;
  • trunk/Source/WebKit2/ChangeLog

    r215255 r215259  
     12017-04-11  Zan Dobersek  <zdobersek@igalia.com>
     2
     3        [GTK] Use the DisplayRefreshMonitor facilities
     4        https://bugs.webkit.org/show_bug.cgi?id=170599
     5
     6        Reviewed by Carlos Garcia Campos.
     7
     8        ThreadedCompositor gains a DisplayRefreshMonitor member that it can use
     9        to better coordinate display refresh callbacks on the main thread. Still,
     10        because currently the GTK+ port doesn't have a reliable way of notifying
     11        the ThreadedCompositor of a vsync event, a timer targeting 60FPS is used
     12        in order to keep the updates at a reasonable rate. When the timer is fired,
     13        the ThreadedCompositor decides how to proceed based on state changes that
     14        might have occurred during composition or whether there's any display
     15        refresh callbacks that require handling on the main thread.
     16
     17        CompositingRunLoop now stores its state in an atomic variable that's then
     18        inspected whenever a new update is scheduled or completed. When scheduled,
     19        if there's no update in progress, a new update is requested through the
     20        timer. If there's already an update in progress, a new update is marked
     21        as pending after the current one completes. In that case, when the update
     22        is completed, a new update is requested through the timer.
     23
     24        ThreadedDisplayRefreshMonitor is used to coordinate updates between the
     25        main and the composition thread whenever the CoordinatedGraphics state
     26        demands it, or whenever there are clients registered to that monitor that
     27        require an update (e.g. a requestAnimationFrame() callback). After the
     28        update on the composition thread is finished, and the DisplayRefreshMonitor
     29        object requires an update, a callback at the same priority as the layer
     30        flush timer is scheduled on the main thread. In that callback we handle
     31        any clients registered for this DisplayRefreshMonitor before proceeding
     32        to handle any changes to the CoordinatedGraphics scene. In case the
     33        DisplayRefreshMonitor clients or the layer flushes already queued up
     34        any changes to the state, we immediately ask the ThreadedCompositor for
     35        an update.
     36
     37        * PlatformGTK.cmake:
     38        * Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp:
     39        (WebKit::CoordinatedGraphicsScene::updateViewport):
     40        (WebKit::CoordinatedGraphicsScene::commitSceneState):
     41        * Shared/CoordinatedGraphics/CoordinatedGraphicsScene.h:
     42        * Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp:
     43        (WebKit::CompositingRunLoop::CompositingRunLoop):
     44        (WebKit::CompositingRunLoop::isActive):
     45        (WebKit::CompositingRunLoop::scheduleUpdate):
     46        (WebKit::CompositingRunLoop::stopUpdates):
     47        (WebKit::CompositingRunLoop::updateCompleted):
     48        (WebKit::CompositingRunLoop::updateTimerFired):
     49        (WebKit::CompositingRunLoop::isCurrent):
     50        (WebKit::CompositingRunLoop::startUpdateTimer): Deleted.
     51        (WebKit::CompositingRunLoop::stopUpdateTimer): Deleted.
     52        * Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.h:
     53        (): Deleted.
     54        * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp:
     55        (WebKit::m_displayRefreshMonitor):
     56        (WebKit::ThreadedCompositor::invalidate):
     57        (WebKit::ThreadedCompositor::setNativeSurfaceHandleForCompositing):
     58        (WebKit::ThreadedCompositor::updateViewport):
     59        (WebKit::ThreadedCompositor::scheduleDisplayImmediately):
     60        (WebKit::ThreadedCompositor::renderLayerTree):
     61        (WebKit::ThreadedCompositor::sceneUpdateFinished):
     62        (WebKit::ThreadedCompositor::updateSceneState):
     63        (WebKit::ThreadedCompositor::displayRefreshMonitor):
     64        (WebKit::ThreadedCompositor::renderNextFrameIfNeeded):
     65        (WebKit::ThreadedCompositor::completeCoordinatedUpdateIfNeeded):
     66        (WebKit::ThreadedCompositor::coordinateUpdateCompletionWithClient):
     67        (WebKit::ThreadedCompositor::performFrameCompletion):
     68        * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h:
     69        * Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.cpp: Added.
     70        (WebKit::ThreadedDisplayRefreshMonitor::ThreadedDisplayRefreshMonitor):
     71        (WebKit::ThreadedDisplayRefreshMonitor::requestRefreshCallback):
     72        (WebKit::ThreadedDisplayRefreshMonitor::requiresDisplayRefreshCallback):
     73        (WebKit::ThreadedDisplayRefreshMonitor::dispatchDisplayRefreshCallback):
     74        (WebKit::ThreadedDisplayRefreshMonitor::invalidate):
     75        (WebKit::ThreadedDisplayRefreshMonitor::displayRefreshCallback):
     76        * Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.h: Copied from Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.h.
     77        * WebProcess/WebPage/AcceleratedDrawingArea.cpp:
     78        (WebKit::AcceleratedDrawingArea::createDisplayRefreshMonitor):
     79        * WebProcess/WebPage/AcceleratedDrawingArea.h:
     80        * WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.cpp:
     81        (WebKit::ThreadedCoordinatedLayerTreeHost::createDisplayRefreshMonitor):
     82        * WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h:
     83        * WebProcess/WebPage/LayerTreeHost.h:
     84        (WebKit::LayerTreeHost::createDisplayRefreshMonitor):
     85
    1862017-04-11  Alex Christensen  <achristensen@webkit.org>
    287
  • trunk/Source/WebKit2/PlatformGTK.cmake

    r214934 r215259  
    6666    Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp
    6767    Shared/CoordinatedGraphics/threadedcompositor/ThreadSafeCoordinatedSurface.cpp
     68    Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.cpp
    6869    Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp
    6970
  • trunk/Source/WebKit2/Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp

    r213035 r215259  
    128128void CoordinatedGraphicsScene::updateViewport()
    129129{
    130     if (!m_client)
    131         return;
    132     dispatchOnClientRunLoop([this] {
    133         if (m_client)
    134             m_client->updateViewport();
    135     });
     130    if (m_client)
     131        m_client->updateViewport();
    136132}
    137133
     
    548544    commitPendingBackingStoreOperations();
    549545    removeReleasedImageBackingsIfNeeded();
    550 
    551     // The pending tiles state is on its way for the screen, tell the web process to render the next one.
    552     renderNextFrame();
    553546}
    554547
  • trunk/Source/WebKit2/Shared/CoordinatedGraphics/CoordinatedGraphicsScene.h

    r213035 r215259  
    8181
    8282    void commitSceneState(const WebCore::CoordinatedGraphicsState&);
     83    void renderNextFrame();
    8384
    8485    void setViewBackgroundColor(const WebCore::Color& color) { m_viewBackgroundColor = color; }
     
    124125    void dispatchOnClientRunLoop(Function<void()>&&);
    125126    void updateViewport();
    126     void renderNextFrame();
    127127
    128128    void createLayer(WebCore::CoordinatedLayerID);
  • trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp

    r215173 r215259  
    113113    , m_updateFunction(WTFMove(updateFunction))
    114114{
     115    m_updateState.store(UpdateState::Completed);
     116
    115117#if USE(GLIB_EVENT_LOOP)
    116118    m_updateTimer.setPriority(RunLoopSourcePriority::CompositingThreadUpdateTimer);
     
    145147}
    146148
    147 void CompositingRunLoop::startUpdateTimer(UpdateTiming timing)
     149bool CompositingRunLoop::isActive()
    148150{
    149     if (m_updateTimer.isActive())
     151    return m_updateState.load() != UpdateState::Completed;
     152}
     153
     154void CompositingRunLoop::scheduleUpdate()
     155{
     156    if (m_updateState.compareExchangeStrong(UpdateState::Completed, UpdateState::InProgress) == UpdateState::Completed) {
     157        m_updateTimer.startOneShot(0);
     158        return;
     159    }
     160
     161    if (m_updateState.compareExchangeStrong(UpdateState::InProgress, UpdateState::PendingAfterCompletion) == UpdateState::InProgress)
     162        return;
     163}
     164
     165void CompositingRunLoop::stopUpdates()
     166{
     167    m_updateTimer.stop();
     168    m_updateState.store(UpdateState::Completed);
     169}
     170
     171void CompositingRunLoop::updateCompleted()
     172{
     173    if (m_updateState.compareExchangeStrong(UpdateState::InProgress, UpdateState::Completed) == UpdateState::InProgress)
    150174        return;
    151175
    152     const static double targetFPS = 60;
    153     double nextUpdateTime = 0;
    154     if (timing == WaitUntilNextFrame)
    155         nextUpdateTime = std::max((1 / targetFPS) - (monotonicallyIncreasingTime() - m_lastUpdateTime), 0.0);
     176    if (m_updateState.compareExchangeStrong(UpdateState::PendingAfterCompletion, UpdateState::InProgress) == UpdateState::PendingAfterCompletion) {
     177        m_updateTimer.startOneShot(0);
     178        return;
     179    }
    156180
    157     m_updateTimer.startOneShot(1_s * nextUpdateTime);
    158 }
    159 
    160 void CompositingRunLoop::stopUpdateTimer()
    161 {
    162     m_updateTimer.stop();
     181    ASSERT_NOT_REACHED();
    163182}
    164183
     
    166185{
    167186    m_updateFunction();
    168     m_lastUpdateTime = monotonicallyIncreasingTime();
    169187}
    170188
  • trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.h

    r203721 r215259  
    2929#if USE(COORDINATED_GRAPHICS_THREADED)
    3030
     31#include <wtf/Atomics.h>
    3132#include <wtf/Condition.h>
    3233#include <wtf/FastMalloc.h>
     
    4243    WTF_MAKE_FAST_ALLOCATED;
    4344public:
    44     enum UpdateTiming {
    45         Immediate,
    46         WaitUntilNextFrame,
    47     };
    48 
    4945    CompositingRunLoop(std::function<void ()>&&);
    5046    ~CompositingRunLoop();
     
    5349    void performTaskSync(Function<void ()>&&);
    5450
    55     void startUpdateTimer(UpdateTiming = Immediate);
    56     void stopUpdateTimer();
     51    bool isActive();
     52    void scheduleUpdate();
     53    void stopUpdates();
     54
     55    void updateCompleted();
     56
     57#ifndef NDEBUG
     58    bool isCurrent();
     59#endif
    5760
    5861private:
     62    enum class UpdateState {
     63        Completed,
     64        InProgress,
     65        PendingAfterCompletion,
     66    };
     67
    5968    void updateTimerFired();
    6069
    6170    RunLoop::Timer<CompositingRunLoop> m_updateTimer;
     71#ifndef NDEBUG
     72    RunLoop& m_runLoop;
     73#endif
    6274    std::function<void ()> m_updateFunction;
     75    Atomic<UpdateState> m_updateState;
    6376    Lock m_dispatchSyncConditionMutex;
    6477    Condition m_dispatchSyncCondition;
    65 
    66     double m_lastUpdateTime { 0 };
    6778};
    6879
  • trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp

    r211281 r215259  
    3030
    3131#include "CompositingRunLoop.h"
     32#include "ThreadedDisplayRefreshMonitor.h"
    3233#include <WebCore/PlatformDisplay.h>
    3334#include <WebCore/TransformationMatrix.h>
     
    5758    , m_needsResize(!viewportSize.isEmpty())
    5859    , m_compositingRunLoop(std::make_unique<CompositingRunLoop>([this] { renderLayerTree(); }))
    59 {
     60#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
     61    , m_displayRefreshMonitor(ThreadedDisplayRefreshMonitor::create(*this))
     62#endif
     63{
     64    m_clientRendersNextFrame.store(false);
     65    m_coordinateUpdateCompletionWithClient.store(false);
     66
    6067    m_compositingRunLoop->performTaskSync([this, protectedThis = makeRef(*this)] {
    6168        m_scene = adoptRef(new CoordinatedGraphicsScene(this));
     
    9097{
    9198    m_scene->detach();
    92     m_compositingRunLoop->stopUpdateTimer();
     99    m_compositingRunLoop->stopUpdates();
    93100    m_compositingRunLoop->performTaskSync([this, protectedThis = makeRef(*this)] {
    94101        m_scene->purgeGLResources();
     
    96103        m_scene = nullptr;
    97104    });
     105#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
     106    m_displayRefreshMonitor->invalidate();
     107#endif
    98108    m_compositingRunLoop = nullptr;
    99109}
     
    101111void ThreadedCompositor::setNativeSurfaceHandleForCompositing(uint64_t handle)
    102112{
    103     m_compositingRunLoop->stopUpdateTimer();
     113    m_compositingRunLoop->stopUpdates();
    104114    m_compositingRunLoop->performTaskSync([this, protectedThis = makeRef(*this), handle] {
    105115        // A new native handle can't be set without destroying the previous one first if any.
     
    120130    m_compositingRunLoop->performTask([this, protectedThis = makeRef(*this), scale] {
    121131        m_scaleFactor = scale;
    122         scheduleDisplayImmediately();
     132        m_compositingRunLoop->scheduleUpdate();
    123133    });
    124134}
     
    129139        m_scrollPosition = scrollPosition;
    130140        m_scaleFactor = scale;
    131         scheduleDisplayImmediately();
     141        m_compositingRunLoop->scheduleUpdate();
    132142    });
    133143}
     
    139149        m_scaleFactor = scale;
    140150        m_needsResize = true;
    141         scheduleDisplayImmediately();
     151        m_compositingRunLoop->scheduleUpdate();
    142152    });
    143153}
     
    147157    m_compositingRunLoop->performTask([this, protectedThis = Ref<ThreadedCompositor>(*this), drawsBackground] {
    148158        m_drawsBackground = drawsBackground;
    149         scheduleDisplayImmediately();
     159        m_compositingRunLoop->scheduleUpdate();
    150160    });
    151161}
     
    165175void ThreadedCompositor::updateViewport()
    166176{
    167     m_compositingRunLoop->startUpdateTimer(CompositingRunLoop::WaitUntilNextFrame);
    168 }
    169 
    170 void ThreadedCompositor::scheduleDisplayImmediately()
    171 {
    172     m_compositingRunLoop->startUpdateTimer(CompositingRunLoop::Immediate);
     177    m_compositingRunLoop->scheduleUpdate();
    173178}
    174179
     
    206211
    207212    m_context->swapBuffers();
     213
     214    sceneUpdateFinished();
     215}
     216
     217void ThreadedCompositor::sceneUpdateFinished()
     218{
     219    bool shouldDispatchDisplayRefreshCallback = m_clientRendersNextFrame.load()
     220        || m_displayRefreshMonitor->requiresDisplayRefreshCallback();
     221    bool shouldCoordinateUpdateCompletionWithClient = m_coordinateUpdateCompletionWithClient.load();
     222
     223    if (shouldDispatchDisplayRefreshCallback)
     224        m_displayRefreshMonitor->dispatchDisplayRefreshCallback();
     225    if (!shouldCoordinateUpdateCompletionWithClient)
     226        m_compositingRunLoop->updateCompleted();
    208227}
    209228
     
    212231    ASSERT(isMainThread());
    213232    RefPtr<CoordinatedGraphicsScene> scene = m_scene;
    214     m_scene->appendUpdate([scene, state] {
     233    m_scene->appendUpdate([this, scene, state] {
    215234        scene->commitSceneState(state);
    216     });
    217 
    218     scheduleDisplayImmediately();
    219 }
     235
     236        m_clientRendersNextFrame.store(true);
     237        bool coordinateUpdate = std::any_of(state.layersToUpdate.begin(), state.layersToUpdate.end(),
     238            [](const std::pair<CoordinatedLayerID, CoordinatedGraphicsLayerState>& it) {
     239                return it.second.platformLayerChanged || it.second.platformLayerUpdated;
     240            });
     241        m_coordinateUpdateCompletionWithClient.store(coordinateUpdate);
     242    });
     243
     244    m_compositingRunLoop->scheduleUpdate();
     245}
     246
     247#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
     248RefPtr<WebCore::DisplayRefreshMonitor> ThreadedCompositor::displayRefreshMonitor(PlatformDisplayID)
     249{
     250    return m_displayRefreshMonitor.copyRef();
     251}
     252
     253void ThreadedCompositor::renderNextFrameIfNeeded()
     254{
     255    if (m_clientRendersNextFrame.compareExchangeStrong(true, false))
     256        m_scene->renderNextFrame();
     257}
     258
     259void ThreadedCompositor::completeCoordinatedUpdateIfNeeded()
     260{
     261    if (m_coordinateUpdateCompletionWithClient.compareExchangeStrong(true, false))
     262        m_compositingRunLoop->updateCompleted();
     263}
     264
     265void ThreadedCompositor::coordinateUpdateCompletionWithClient()
     266{
     267    m_coordinateUpdateCompletionWithClient.store(true);
     268    if (!m_compositingRunLoop->isActive())
     269        m_compositingRunLoop->scheduleUpdate();
     270}
     271#endif
    220272
    221273}
  • trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h

    r211281 r215259  
    3434#include <WebCore/IntSize.h>
    3535#include <WebCore/TextureMapper.h>
     36#include <wtf/Atomics.h>
    3637#include <wtf/FastMalloc.h>
    3738#include <wtf/Noncopyable.h>
    3839#include <wtf/ThreadSafeRefCounted.h>
     40
     41#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
     42#include <WebCore/DisplayRefreshMonitor.h>
     43#endif
    3944
    4045namespace WebCore {
     
    4651class CoordinatedGraphicsScene;
    4752class CoordinatedGraphicsSceneClient;
     53class ThreadedDisplayRefreshMonitor;
    4854
    4955class ThreadedCompositor : public CoordinatedGraphicsSceneClient, public ThreadSafeRefCounted<ThreadedCompositor> {
     
    7480    void forceRepaint();
    7581
     82#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
     83    RefPtr<WebCore::DisplayRefreshMonitor> displayRefreshMonitor(WebCore::PlatformDisplayID);
     84    void renderNextFrameIfNeeded();
     85    void completeCoordinatedUpdateIfNeeded();
     86    void coordinateUpdateCompletionWithClient();
     87#endif
     88
    7689private:
    7790    ThreadedCompositor(Client&, const WebCore::IntSize&, float scaleFactor, uint64_t nativeSurfaceHandle, ShouldDoFrameSync, WebCore::TextureMapper::PaintFlags);
     
    8396
    8497    void renderLayerTree();
    85     void scheduleDisplayImmediately();
     98    void sceneUpdateFinished();
    8699
    87100    void createGLContext();
     
    101114
    102115    std::unique_ptr<CompositingRunLoop> m_compositingRunLoop;
     116
     117#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
     118    Ref<ThreadedDisplayRefreshMonitor> m_displayRefreshMonitor;
     119#endif
     120
     121    Atomic<bool> m_clientRendersNextFrame;
     122    Atomic<bool> m_coordinateUpdateCompletionWithClient;
    103123};
    104124
  • trunk/Source/WebKit2/WebProcess/WebPage/AcceleratedDrawingArea.cpp

    r215173 r215259  
    224224}
    225225
     226#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
     227RefPtr<WebCore::DisplayRefreshMonitor> AcceleratedDrawingArea::createDisplayRefreshMonitor(WebCore::PlatformDisplayID displayID)
     228{
     229    if (!m_layerTreeHost || m_wantsToExitAcceleratedCompositingMode || exitAcceleratedCompositingModePending())
     230        return nullptr;
     231    return m_layerTreeHost->createDisplayRefreshMonitor(displayID);
     232}
     233#endif
     234
    226235void AcceleratedDrawingArea::updateBackingStoreState(uint64_t stateID, bool respondImmediately, float deviceScaleFactor, const IntSize& size, const IntSize& scrollOffset)
    227236{
  • trunk/Source/WebKit2/WebProcess/WebPage/AcceleratedDrawingArea.h

    r212608 r215259  
    5959    void scheduleCompositingLayerFlush() override;
    6060    void scheduleCompositingLayerFlushImmediately() override;
     61
     62#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
     63    virtual RefPtr<WebCore::DisplayRefreshMonitor> createDisplayRefreshMonitor(WebCore::PlatformDisplayID);
     64#endif
    6165
    6266#if USE(TEXTURE_MAPPER_GL) && PLATFORM(GTK) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW)
  • trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.cpp

    r211365 r215259  
    7575        // Rendering to the actual screen will happen later anyway since the UI process schedules a redraw for every update,
    7676        // the compositor will take care of syncing to vblank.
    77         m_compositor = ThreadedCompositor::create(m_compositorClient, scaledSize, scaleFactor, m_surface->window(), ThreadedCompositor::ShouldDoFrameSync::No, paintFlags);
     77        m_compositor = ThreadedCompositor::create(m_compositorClient, scaledSize, scaleFactor, m_surface->window(), ThreadedCompositor::ShouldDoFrameSync::Yes, paintFlags);
    7878        m_layerTreeContext.contextID = m_surface->surfaceID();
    7979    } else
     
    248248}
    249249
     250#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
     251RefPtr<WebCore::DisplayRefreshMonitor> ThreadedCoordinatedLayerTreeHost::createDisplayRefreshMonitor(PlatformDisplayID displayID)
     252{
     253    return m_compositor->displayRefreshMonitor(displayID);
     254}
     255#endif
     256
    250257} // namespace WebKit
    251258
  • trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h

    r211365 r215259  
    102102    void commitSceneState(const WebCore::CoordinatedGraphicsState&) override;
    103103
     104#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
     105    RefPtr<WebCore::DisplayRefreshMonitor> createDisplayRefreshMonitor(WebCore::PlatformDisplayID) override;
     106#endif
     107
    104108    enum class DiscardableSyncActions {
    105109        UpdateSize = 1 << 1,
  • trunk/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h

    r212608 r215259  
    3030
    3131#include "LayerTreeContext.h"
     32#include <WebCore/DisplayRefreshMonitor.h>
     33#include <WebCore/PlatformScreen.h>
    3234#include <wtf/Forward.h>
    3335#include <wtf/RefCounted.h>
     
    9799#endif
    98100
     101#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
     102    virtual RefPtr<WebCore::DisplayRefreshMonitor> createDisplayRefreshMonitor(WebCore::PlatformDisplayID) { return nullptr; }
     103#endif
     104
    99105    virtual void setViewOverlayRootLayer(WebCore::GraphicsLayer* viewOverlayRootLayer) { m_viewOverlayRootLayer = viewOverlayRootLayer; }
    100106
Note: See TracChangeset for help on using the changeset viewer.