Skip to content

Commit

Permalink
[GTK] Add a DisplayLink implementation
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=261673

Reviewed by Simon Fraser.

Add DisplayLink implementation using DRM API when available to get the
vblank signal from monitor. When DRM is not available we fallback to use
a timer. The patch includes some refactorings needed to share the
implementation with other ports for non-platform specific parts. The
platform display ID is no longer generated based on the drawing area
identifier, but assigned by the screen manager to every monitor.
ThreadedDisplayRefreshMonitor and DisplayRefreshMonitorGtk are no longer
needed now.

* Source/WebCore/SourcesGTK.txt:
* Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp:
(WebCore::DisplayRefreshMonitor::createDefaultDisplayRefreshMonitor):
(WebCore::DisplayRefreshMonitor::requestRefreshCallback):
* Source/WebCore/platform/graphics/gtk/DisplayRefreshMonitorGtk.cpp: Removed.
* Source/WebKit/PlatformGTK.cmake:
* Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp:
(WebKit::ThreadedCompositor::create):
(WebKit::ThreadedCompositor::ThreadedCompositor):
(WebKit::ThreadedCompositor::invalidate):
(WebKit::ThreadedCompositor::renderLayerTree):
(WebKit::ThreadedCompositor::sceneUpdateFinished):
(WebKit::ThreadedCompositor::frameComplete):
* Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h:
* Source/WebKit/Sources.txt:
* Source/WebKit/SourcesCocoa.txt:
* Source/WebKit/SourcesGTK.txt:
* Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp:
(webkitWebViewBaseUpdateDisplayID):
(toplevelWindowConfigureEvent):
(webkitWebViewBaseSetToplevelOnScreenWindow):
(webkitWebViewBaseRealize):
(toplevelWindowMonitorsChanged):
(toplevelWindowRealized):
(toplevelWindowUnrealized):
(webkitWebViewBaseRoot):
(webkitWebViewBaseUnroot):
(webkitWebViewBaseCreateWebPage):
(webkitWebViewBaseDidRelaunchWebProcess):
* Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp:
(WebKit::DrawingAreaProxyCoordinatedGraphics::displayNominalFramesPerSecond):
* Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.h:
* Source/WebKit/UIProcess/DisplayLink.cpp: Renamed from Source/WebKit/UIProcess/mac/DisplayLink.cpp.
(WebKit::DisplayLink::DisplayLink):
(WebKit::DisplayLink::~DisplayLink):
(WebKit::DisplayLink::addObserver):
(WebKit::DisplayLink::notifyObserversDisplayDidRefresh):
(WebKit::DisplayLinkCollection::stopDisplayLinks):
* Source/WebKit/UIProcess/DisplayLink.h: Renamed from Source/WebKit/UIProcess/mac/DisplayLink.h.
* Source/WebKit/UIProcess/DisplayLinkProcessProxyClient.cpp: Renamed from Source/WebKit/UIProcess/mac/DisplayLinkProcessProxyClient.cpp.
* Source/WebKit/UIProcess/DisplayLinkProcessProxyClient.h: Copied from Source/WebKit/UIProcess/mac/DisplayLinkProcessProxyClient.h.
* Source/WebKit/UIProcess/Downloads/DownloadProxyMap.h:
* Source/WebKit/UIProcess/DrawingAreaProxy.h:
* Source/WebKit/UIProcess/Extensions/WebExtensionContext.cpp:
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::Internals::Internals):
(WebKit::WebPageProxy::sendWheelEvent):
(WebKit::WebPageProxy::updateWheelEventActivityAfterProcessSwap):
(WebKit::WebPageProxy::windowScreenDidChange):
(WebKit::WebPageProxy::setHasActiveAnimatedScrolls):
* Source/WebKit/UIProcess/WebPageProxy.h:
* Source/WebKit/UIProcess/WebPageProxyInternals.h:
* Source/WebKit/UIProcess/WebProcessPool.h:
* Source/WebKit/UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::~WebProcessProxy):
(WebKit::WebProcessProxy::connectionWillOpen):
(WebKit::WebProcessProxy::processWillShutDown):
(WebKit::WebProcessProxy::nominalFramesPerSecondForDisplay):
(WebKit::WebProcessProxy::startDisplayLink):
(WebKit::WebProcessProxy::stopDisplayLink):
(WebKit::WebProcessProxy::setDisplayLinkPreferredFramesPerSecond):
(WebKit::WebProcessProxy::setDisplayLinkForDisplayWantsFullSpeedUpdates):
* Source/WebKit/UIProcess/WebProcessProxy.h:
* Source/WebKit/UIProcess/WebProcessProxy.messages.in:
* Source/WebKit/UIProcess/glib/DisplayLinkGLib.cpp: Renamed from Source/WebKit/UIProcess/mac/DisplayLinkProcessProxyClient.h.
(WebKit::DisplayLink::platformInitialize):
(WebKit::DisplayLink::platformFinalize):
(WebKit::DisplayLink::platformIsRunning const):
(WebKit::DisplayLink::platformStart):
(WebKit::DisplayLink::platformStop):
* Source/WebKit/UIProcess/glib/DisplayVBlankMonitor.cpp: Added.
(WebKit::DisplayVBlankMonitor::create):
(WebKit::DisplayVBlankMonitor::DisplayVBlankMonitor):
(WebKit::DisplayVBlankMonitor::~DisplayVBlankMonitor):
(WebKit::DisplayVBlankMonitor::startThreadIfNeeded):
(WebKit::DisplayVBlankMonitor::start):
(WebKit::DisplayVBlankMonitor::stop):
(WebKit::DisplayVBlankMonitor::invalidate):
(WebKit::DisplayVBlankMonitor::isActive):
(WebKit::DisplayVBlankMonitor::setHandler):
(WebKit::DisplayVBlankMonitor::destroyThreadTimerFired):
* Source/WebKit/UIProcess/glib/DisplayVBlankMonitor.h: Copied from Source/WebKit/UIProcess/gtk/ScreenManager.h.
(WebKit::DisplayVBlankMonitor::refreshRate const):
(WebKit::DisplayVBlankMonitor::WTF_GUARDED_BY_LOCK):
* Source/WebKit/UIProcess/glib/DisplayVBlankMonitorDRM.cpp: Added.
(WebKit::findCrtc):
(WebKit::DisplayVBlankMonitorDRM::create):
(WebKit::DisplayVBlankMonitorDRM::DisplayVBlankMonitorDRM):
(WebKit::DisplayVBlankMonitorDRM::waitForVBlank const):
* Source/WebKit/UIProcess/glib/DisplayVBlankMonitorDRM.h: Renamed from Source/WebCore/platform/graphics/gtk/DisplayRefreshMonitorGtk.h.
* Source/WebKit/UIProcess/glib/DisplayVBlankMonitorTimer.cpp: Copied from Source/WebKit/UIProcess/gtk/ScreenManager.h.
(WebKit::DisplayVBlankMonitorTimer::create):
(WebKit::DisplayVBlankMonitorTimer::DisplayVBlankMonitorTimer):
(WebKit::DisplayVBlankMonitorTimer::waitForVBlank const):
* Source/WebKit/UIProcess/glib/DisplayVBlankMonitorTimer.h: Copied from Source/WebKit/UIProcess/gtk/ScreenManager.h.
* Source/WebKit/UIProcess/gtk/ScreenManager.cpp:
(WebKit::ScreenManager::displayID const):
(WebKit::ScreenManager::monitor const):
* Source/WebKit/UIProcess/gtk/ScreenManager.h:
* Source/WebKit/UIProcess/mac/DisplayLinkMac.cpp: Added.
(WebKit::DisplayLink::platformInitialize):
(WebKit::DisplayLink::platformFinalize):
(WebKit::DisplayLink::nominalFramesPerSecondFromDisplayLink):
(WebKit::DisplayLink::platformIsRunning const):
(WebKit::DisplayLink::platformStart):
(WebKit::DisplayLink::platformStop):
(WebKit::DisplayLink::displayLinkCallback):
* Source/WebKit/UIProcess/mac/WebProcessProxyMac.mm:
(WebKit::WebProcessProxy::nominalFramesPerSecondForDisplay): Deleted.
(WebKit::WebProcessProxy::startDisplayLink): Deleted.
(WebKit::WebProcessProxy::stopDisplayLink): Deleted.
(WebKit::WebProcessProxy::setDisplayLinkPreferredFramesPerSecond): Deleted.
(WebKit::WebProcessProxy::setDisplayLinkForDisplayWantsFullSpeedUpdates): Deleted.
* Source/WebKit/WebKit.xcodeproj/project.pbxproj:
* Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp:
(WebKit::DrawingAreaCoordinatedGraphics::createDisplayRefreshMonitor):
(WebKit::DrawingAreaCoordinatedGraphics::enterAcceleratedCompositingMode):
(WebKit::DrawingAreaCoordinatedGraphics::exitAcceleratedCompositingMode):
* Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.h:
* Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp:
(WebKit::LayerTreeHost::LayerTreeHost):
(WebKit::LayerTreeHost::layerFlushTimerFired):
(WebKit::LayerTreeHost::didRenderFrame):
* Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.h:
(WebKit::LayerTreeHost::LayerTreeHost):
(WebKit::LayerTreeHost::deviceOrPageScaleFactorChanged):
(WebKit::LayerTreeHost::createDisplayRefreshMonitor):
* Source/WebKit/WebProcess/WebPage/DrawingArea.messages.in:
* Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp:
* Source/WebKit/WebProcess/WebPage/EventDispatcher.h:
* Source/WebKit/WebProcess/WebPage/EventDispatcher.messages.in:
* Source/WebKit/WebProcess/WebPage/WebDisplayRefreshMonitor.cpp: Renamed from Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.cpp.
(WebKit::WebDisplayRefreshMonitor::WebDisplayRefreshMonitor):
(WebKit::WebDisplayRefreshMonitor::~WebDisplayRefreshMonitor):
(WebKit::WebDisplayRefreshMonitor::dispatchDisplayDidRefresh):
(WebKit::WebDisplayRefreshMonitor::startNotificationMechanism):
(WebKit::WebDisplayRefreshMonitor::stopNotificationMechanism):
(WebKit::WebDisplayRefreshMonitor::adjustPreferredFramesPerSecond):
* Source/WebKit/WebProcess/WebPage/WebDisplayRefreshMonitor.h: Renamed from Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.h.
* Source/WebKit/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
(WebKit::TiledCoreAnimationDrawingArea::createDisplayRefreshMonitor):
* Source/WebKit/WebProcess/WebProcess.cpp:
* Source/WebKit/WebProcess/WebProcess.h:
* Source/WebKit/WebProcess/WebProcess.messages.in:

Co-authored-by: Carlos Garcia Campos <cgarcia@igalia.com>
Canonical link: https://commits.webkit.org/268646@main
  • Loading branch information
alexgcastro authored and carlosgcampos committed Sep 29, 2023
1 parent 80daa4a commit 4aad349
Show file tree
Hide file tree
Showing 55 changed files with 1,129 additions and 322 deletions.
4 changes: 2 additions & 2 deletions Source/WTF/wtf/PlatformHave.h
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,8 @@
#define HAVE_IOSURFACE 1
#endif

#if PLATFORM(MAC)
#define HAVE_CVDISPLAYLINK 1
#if PLATFORM(MAC) || PLATFORM(GTK)
#define HAVE_DISPLAY_LINK 1
#endif

#if PLATFORM(MAC)
Expand Down
1 change: 0 additions & 1 deletion Source/WebCore/SourcesGTK.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ platform/graphics/gbm/GraphicsContextGLGBM.cpp @no-unify
platform/graphics/gbm/PlatformDisplayGBM.cpp @no-unify

platform/graphics/gtk/ColorGtk.cpp
platform/graphics/gtk/DisplayRefreshMonitorGtk.cpp
platform/graphics/gtk/GdkCairoUtilities.cpp
platform/graphics/gtk/ImageGtk.cpp
platform/graphics/gtk/SystemFontDatabaseGTK.cpp
Expand Down
7 changes: 1 addition & 6 deletions Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@
#include "DisplayRefreshMonitorIOS.h"
#elif PLATFORM(MAC)
#include "LegacyDisplayRefreshMonitorMac.h"
#elif PLATFORM(GTK)
#include "DisplayRefreshMonitorGtk.h"
#elif PLATFORM(WIN)
#include "DisplayRefreshMonitorWin.h"
#endif
Expand All @@ -52,9 +50,6 @@ RefPtr<DisplayRefreshMonitor> DisplayRefreshMonitor::createDefaultDisplayRefresh
#if PLATFORM(IOS_FAMILY)
return DisplayRefreshMonitorIOS::create(displayID);
#endif
#if PLATFORM(GTK) && !USE(GTK4)
return DisplayRefreshMonitorGtk::create(displayID);
#endif
#if PLATFORM(WIN)
return DisplayRefreshMonitorWin::create(displayID);
#endif
Expand Down Expand Up @@ -139,7 +134,7 @@ void DisplayRefreshMonitor::clientPreferredFramesPerSecondChanged(DisplayRefresh
bool DisplayRefreshMonitor::requestRefreshCallback()
{
Locker locker { m_lock };

if (isScheduled())
return true;

Expand Down
113 changes: 0 additions & 113 deletions Source/WebCore/platform/graphics/gtk/DisplayRefreshMonitorGtk.cpp

This file was deleted.

9 changes: 9 additions & 0 deletions Source/WebKit/PlatformGTK.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,15 @@ if (USE_WPE_RENDERER)
)
endif ()

if (USE_LIBDRM)
list(APPEND WebKit_SYSTEM_INCLUDE_DIRECTORIES
${LIBDRM_INCLUDE_DIR}
)
list(APPEND WebKit_LIBRARIES
${LIBDRM_LIBRARIES}
)
endif ()

if (GTK_UNIX_PRINT_FOUND)
list(APPEND WebKit_LIBRARIES GTK::UnixPrint)
endif ()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#if USE(COORDINATED_GRAPHICS)

#include "CompositingRunLoop.h"
#include "ThreadedDisplayRefreshMonitor.h"
#include <WebCore/PlatformDisplay.h>
#include <WebCore/TransformationMatrix.h>
#include <wtf/SetForScope.h>
Expand All @@ -38,6 +37,10 @@
#include <wtf/glib/RunLoopSourcePriority.h>
#endif

#if !HAVE(DISPLAY_LINK)
#include "ThreadedDisplayRefreshMonitor.h"
#endif

#if USE(LIBEPOXY)
#include <epoxy/gl.h>
#else
Expand All @@ -49,16 +52,29 @@ using namespace WebCore;

static constexpr unsigned c_defaultRefreshRate = 60000;

#if HAVE(DISPLAY_LINK)
Ref<ThreadedCompositor> ThreadedCompositor::create(Client& client, PlatformDisplayID displayID, const IntSize& viewportSize, float scaleFactor, TextureMapper::PaintFlags paintFlags)
{
return adoptRef(*new ThreadedCompositor(client, displayID, viewportSize, scaleFactor, paintFlags));
}
#else
Ref<ThreadedCompositor> ThreadedCompositor::create(Client& client, ThreadedDisplayRefreshMonitor::Client& displayRefreshMonitorClient, PlatformDisplayID displayID, const IntSize& viewportSize, float scaleFactor, TextureMapper::PaintFlags paintFlags)
{
return adoptRef(*new ThreadedCompositor(client, displayRefreshMonitorClient, displayID, viewportSize, scaleFactor, paintFlags));
}
#endif

#if HAVE(DISPLAY_LINK)
ThreadedCompositor::ThreadedCompositor(Client& client, PlatformDisplayID displayID, const IntSize& viewportSize, float scaleFactor, TextureMapper::PaintFlags paintFlags)
#else
ThreadedCompositor::ThreadedCompositor(Client& client, ThreadedDisplayRefreshMonitor::Client& displayRefreshMonitorClient, PlatformDisplayID displayID, const IntSize& viewportSize, float scaleFactor, TextureMapper::PaintFlags paintFlags)
#endif
: m_client(client)
, m_paintFlags(paintFlags)
, m_compositingRunLoop(makeUnique<CompositingRunLoop>([this] { renderLayerTree(); }))
#if !HAVE(DISPLAY_LINK)
, m_displayRefreshMonitor(ThreadedDisplayRefreshMonitor::create(displayID, displayRefreshMonitorClient, WebCore::DisplayUpdate { 0, c_defaultRefreshRate / 1000 }))
#endif
{
{
// Locking isn't really necessary here, but it's done for consistency.
Expand All @@ -68,16 +84,22 @@ ThreadedCompositor::ThreadedCompositor(Client& client, ThreadedDisplayRefreshMon
m_attributes.needsResize = !viewportSize.isEmpty();
}

#if !HAVE(DISPLAY_LINK)
m_display.displayID = displayID;
m_display.displayUpdate = { 0, c_defaultRefreshRate / 1000 };
#else
UNUSED_PARAM(displayID);
#endif

m_compositingRunLoop->performTaskSync([this, protectedThis = Ref { *this }] {
#if !HAVE(DISPLAY_LINK)
m_display.updateTimer = makeUnique<RunLoop::Timer>(RunLoop::current(), this, &ThreadedCompositor::displayUpdateFired);
#if USE(GLIB_EVENT_LOOP)
m_display.updateTimer->setPriority(RunLoopSourcePriority::CompositingThreadUpdateTimer);
m_display.updateTimer->setName("[WebKit] ThreadedCompositor::DisplayUpdate");
#endif
m_display.updateTimer->startOneShot(Seconds { 1.0 / m_display.displayUpdate.updatesPerSecond });
#endif

m_scene = adoptRef(new CoordinatedGraphicsScene(this));
m_nativeSurfaceHandle = m_client.nativeSurfaceHandleForCompositing();
Expand Down Expand Up @@ -120,7 +142,9 @@ void ThreadedCompositor::invalidate()
{
m_scene->detach();
m_compositingRunLoop->stopUpdates();
#if !HAVE(DISPLAY_LINK)
m_displayRefreshMonitor->invalidate();
#endif
m_compositingRunLoop->performTaskSync([this, protectedThis = Ref { *this }] {
if (!m_context || !m_context->makeContextCurrent())
return;
Expand All @@ -135,7 +159,9 @@ void ThreadedCompositor::invalidate()
m_client.didDestroyGLContext();
m_scene = nullptr;

#if !HAVE(DISPLAY_LINK)
m_display.updateTimer = nullptr;
#endif
});
m_compositingRunLoop = nullptr;
}
Expand Down Expand Up @@ -199,7 +225,9 @@ void ThreadedCompositor::renderLayerTree()
if (!m_context || !m_context->makeContextCurrent())
return;

#if !HAVE(DISPLAY_LINK)
m_display.updateTimer->stop();
#endif

// Retrieve the scene attributes in a thread-safe manner.
WebCore::IntSize viewportSize;
Expand Down Expand Up @@ -258,6 +286,7 @@ void ThreadedCompositor::renderLayerTree()

void ThreadedCompositor::sceneUpdateFinished()
{
#if !HAVE(DISPLAY_LINK)
// The composition has finished. Now we have to determine how to manage
// the scene update completion.

Expand All @@ -270,12 +299,15 @@ void ThreadedCompositor::sceneUpdateFinished()
Locker locker { m_attributes.lock };
shouldDispatchDisplayRefreshCallback |= m_attributes.clientRendersNextFrame;
}
#endif

Locker stateLocker { m_compositingRunLoop->stateLock() };

#if !HAVE(DISPLAY_LINK)
// Schedule the DisplayRefreshMonitor callback, if necessary.
if (shouldDispatchDisplayRefreshCallback)
m_displayRefreshMonitor->dispatchDisplayRefreshCallback();
#endif

// Mark the scene update as completed.
m_compositingRunLoop->updateCompleted(stateLocker);
Expand Down Expand Up @@ -306,18 +338,23 @@ void ThreadedCompositor::updateSceneWithoutRendering()
m_scene->updateSceneState();
}

#if !HAVE(DISPLAY_LINK)
WebCore::DisplayRefreshMonitor& ThreadedCompositor::displayRefreshMonitor() const
{
return m_displayRefreshMonitor.get();
}
#endif

void ThreadedCompositor::frameComplete()
{
ASSERT(m_compositingRunLoop->isCurrent());
#if !HAVE(DISPLAY_LINK)
displayUpdateFired();
#endif
sceneUpdateFinished();
}

#if !PLATFORM(GTK)
void ThreadedCompositor::targetRefreshRateDidChange(unsigned rate)
{
ASSERT(RunLoop::isMain());
Expand All @@ -328,7 +365,9 @@ void ThreadedCompositor::targetRefreshRateDidChange(unsigned rate)
m_display.displayUpdate = { 0, rate / 1000 };
});
}
#endif

#if !HAVE(DISPLAY_LINK)
void ThreadedCompositor::displayUpdateFired()
{
m_display.displayUpdate = m_display.displayUpdate.nextUpdate();
Expand All @@ -337,6 +376,7 @@ void ThreadedCompositor::displayUpdateFired()

m_display.updateTimer->startOneShot(Seconds { 1.0 / m_display.displayUpdate.updatesPerSecond });
}
#endif

}
#endif // USE(COORDINATED_GRAPHICS)
Loading

0 comments on commit 4aad349

Please sign in to comment.