Diff
Modified: trunk/Source/WebCore/ChangeLog (275162 => 275163)
--- trunk/Source/WebCore/ChangeLog 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/ChangeLog 2021-03-29 17:21:03 UTC (rev 275163)
@@ -1,3 +1,81 @@
+2021-03-28 Simon Fraser <[email protected]>
+
+ Plumb DisplayUpdate through the display refresh monitors
+ https://bugs.webkit.org/show_bug.cgi?id=223847
+
+ Reviewed by Sam Weinig.
+
+ Future work will allow DisplayRefreshMonitorClients to request different frame rates, which
+ are whole fractions of the display's nominal refresh rate. These various frame rate requests
+ flow up through the DisplayRefreshMonitors, and in WebKit2, up through IPC to the
+ per-display DisplayLink which may even service multiple processes.
+
+ For power reasons, we don't want to trigger display refresh notifications down the chain at
+ the highest possible frequency; at various stages of propagation the rate might be halved if
+ that's necessary for downstream clients.
+
+ To make this frequency splitting logic simple, this patch introduces DisplayUpdate, which
+ represents an update of the display, and contains data about it in the form of a numerator
+ is the frame index, and the denominator is the nominal frame rate. Frame index wraps to zero
+ every second.
+
+ For example, a 60Hz display will generate display refreshes with DisplayUpdates which
+ sequentially will be { 0, 60 }, { 1, 60 }, { 2, 60 } ... { 59, 60 }, { 0, 60 }. The
+ zeroth frame is at some arbitrary time and not aligned with wallclock time.
+
+ Thus a client with a 30Hz update requirement can simply ignore every odd-numbered frame, and
+ a client downstream from it with a 15Hz requirement, which only receives those even-numbered
+ frames, still has enough information to compute which frames to ignore.
+
+ Classes which are sources of callbacks for DisplayRefreshMonitor need to generate these
+ DisplayUpdates; that includes the various platform DisplayRefreshMonitor subclasses in
+ WebCore, and those in WebKit that live in the UI process and trigger updates over IPC.
+
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * loader/EmptyClients.cpp:
+ * platform/graphics/AnimationFrameRate.cpp:
+ * platform/graphics/AnimationFrameRate.h:
+ * platform/graphics/DisplayRefreshMonitor.cpp:
+ (WebCore::DisplayRefreshMonitor::displayLinkFired):
+ (WebCore::DisplayRefreshMonitor::dispatchDisplayDidRefresh):
+ (WebCore::DisplayRefreshMonitor::displayDidRefresh):
+ * platform/graphics/DisplayRefreshMonitor.h:
+ * platform/graphics/DisplayRefreshMonitorManager.cpp:
+ (WebCore::DisplayRefreshMonitorManager::displayWasUpdated):
+ * platform/graphics/DisplayRefreshMonitorManager.h:
+ * platform/graphics/DisplayUpdate.cpp: Copied from Source/WebCore/platform/graphics/win/DisplayRefreshMonitorWin.h.
+ (WebCore::operator<<):
+ * platform/graphics/DisplayUpdate.h: Copied from Source/WebCore/platform/graphics/gtk/DisplayRefreshMonitorGtk.h.
+ (WebCore::DisplayUpdate::didUpdate):
+ (WebCore::DisplayUpdate::encode const):
+ (WebCore::DisplayUpdate::decode):
+ * platform/graphics/gtk/DisplayRefreshMonitorGtk.cpp: Assume a 60fps refresh rate but this code
+ should probably use gdk_frame_clock_get_refresh_info() to get the correct rate.
+ (WebCore::onFrameClockUpdate):
+ (WebCore::DisplayRefreshMonitorGtk::displayLinkCallbackFired):
+ (WebCore::DisplayRefreshMonitorGtk::startNotificationMechanism):
+ * platform/graphics/gtk/DisplayRefreshMonitorGtk.h:
+ * platform/graphics/ios/DisplayRefreshMonitorIOS.h:
+ * platform/graphics/ios/DisplayRefreshMonitorIOS.mm:
+ (-[WebDisplayLinkHandler initWithMonitor:]):
+ (-[WebDisplayLinkHandler handleDisplayLink:]):
+ (WebCore::DisplayRefreshMonitorIOS::displayLinkCallbackFired):
+ (WebCore::DisplayRefreshMonitorIOS::startNotificationMechanism):
+ (-[WebDisplayLinkHandler setPreferredFramesPerSecond:]): Deleted.
+ * platform/graphics/mac/LegacyDisplayRefreshMonitorMac.cpp:
+ (WebCore::displayLinkCallback):
+ (WebCore::LegacyDisplayRefreshMonitorMac::displayLinkCallbackFired):
+ (WebCore::LegacyDisplayRefreshMonitorMac::dispatchDisplayDidRefresh):
+ (WebCore::LegacyDisplayRefreshMonitorMac::nominalFramesPerSecondFromDisplayLink):
+ (WebCore::LegacyDisplayRefreshMonitorMac::startNotificationMechanism):
+ * platform/graphics/mac/LegacyDisplayRefreshMonitorMac.h:
+ (WebCore::LegacyDisplayRefreshMonitorMac::currentUpdate const):
+ * platform/graphics/win/DisplayRefreshMonitorWin.cpp:
+ (WebCore::DisplayRefreshMonitorWin::DisplayRefreshMonitorWin):
+ (WebCore::DisplayRefreshMonitorWin::displayLinkCallbackFired):
+ * platform/graphics/win/DisplayRefreshMonitorWin.h:
+
2021-03-29 Aditya Keerthi <[email protected]>
Use enum classes and OptionSets for ControlStates::States
Modified: trunk/Source/WebCore/Headers.cmake (275162 => 275163)
--- trunk/Source/WebCore/Headers.cmake 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/Headers.cmake 2021-03-29 17:21:03 UTC (rev 275163)
@@ -1189,6 +1189,7 @@
platform/graphics/DisplayRefreshMonitorClient.h
platform/graphics/DisplayRefreshMonitorFactory.h
platform/graphics/DisplayRefreshMonitorManager.h
+ platform/graphics/DisplayUpdate.h
platform/graphics/ExtensionsGL.h
platform/graphics/FloatLine.h
platform/graphics/FloatPoint.h
Modified: trunk/Source/WebCore/Sources.txt (275162 => 275163)
--- trunk/Source/WebCore/Sources.txt 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/Sources.txt 2021-03-29 17:21:03 UTC (rev 275163)
@@ -1943,6 +1943,7 @@
platform/graphics/DisplayRefreshMonitor.cpp
platform/graphics/DisplayRefreshMonitorClient.cpp
platform/graphics/DisplayRefreshMonitorManager.cpp
+platform/graphics/DisplayUpdate.cpp
platform/graphics/FloatLine.cpp
platform/graphics/FloatPoint.cpp
platform/graphics/FloatPoint3D.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (275162 => 275163)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-03-29 17:21:03 UTC (rev 275163)
@@ -345,6 +345,7 @@
0FB6252F18DE1B1500A07C05 /* GeometryUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB6252D18DE1B1500A07C05 /* GeometryUtilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FB8890F167D30160010CDA5 /* ScrollingStateStickyNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB8890D167D30160010CDA5 /* ScrollingStateStickyNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FBB5FBE260991D20054572C /* DisplayRefreshMonitorFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBB5FBD26095A9C0054572C /* DisplayRefreshMonitorFactory.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FBB5FCC260E9E070054572C /* DisplayUpdate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBB5FCB260E9B440054572C /* DisplayUpdate.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC4B00622B9A02D00CF3B1E /* ScrollingTreeOverflowScrollProxyNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC4B00422B9A02C00CF3B1E /* ScrollingTreeOverflowScrollProxyNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FCF332F0F2B9A25004B6795 /* WebLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCF332B0F2B9A25004B6795 /* WebLayer.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FD3080F117CF7E700A791F7 /* RenderFrameBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD3080D117CF7E700A791F7 /* RenderFrameBase.h */; };
@@ -6204,6 +6205,8 @@
0FB8890C167D30160010CDA5 /* ScrollingStateStickyNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollingStateStickyNode.cpp; sourceTree = "<group>"; };
0FB8890D167D30160010CDA5 /* ScrollingStateStickyNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollingStateStickyNode.h; sourceTree = "<group>"; };
0FBB5FBD26095A9C0054572C /* DisplayRefreshMonitorFactory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DisplayRefreshMonitorFactory.h; sourceTree = "<group>"; };
+ 0FBB5FC9260E9B430054572C /* DisplayUpdate.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayUpdate.cpp; sourceTree = "<group>"; };
+ 0FBB5FCB260E9B440054572C /* DisplayUpdate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DisplayUpdate.h; sourceTree = "<group>"; };
0FBFCE24256CBD9A00A0B489 /* DisplayBoxClip.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayBoxClip.cpp; sourceTree = "<group>"; };
0FBFCE26256CBD9A00A0B489 /* DisplayBoxClip.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DisplayBoxClip.h; sourceTree = "<group>"; };
0FC05168219B5EBE0031C39E /* ScrollingTreeOverflowScrollingNodeMac.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollingTreeOverflowScrollingNodeMac.mm; sourceTree = "<group>"; };
@@ -26777,6 +26780,8 @@
0FBB5FBD26095A9C0054572C /* DisplayRefreshMonitorFactory.h */,
2D29ECC3192ECC8300984B78 /* DisplayRefreshMonitorManager.cpp */,
2D29ECC4192ECC8300984B78 /* DisplayRefreshMonitorManager.h */,
+ 0FBB5FC9260E9B430054572C /* DisplayUpdate.cpp */,
+ 0FBB5FCB260E9B440054572C /* DisplayUpdate.h */,
6E67D2A81280E8BD008758F7 /* ExtensionsGL.h */,
2E888CA925F6A4110057914A /* FloatLine.cpp */,
2E888CA825F6A4110057914A /* FloatLine.h */,
@@ -32114,6 +32119,7 @@
0FBB5FBE260991D20054572C /* DisplayRefreshMonitorFactory.h in Headers */,
2D29ECCA192F1F1D00984B78 /* DisplayRefreshMonitorIOS.h in Headers */,
2D29ECC8192ECC8300984B78 /* DisplayRefreshMonitorManager.h in Headers */,
+ 0FBB5FCC260E9E070054572C /* DisplayUpdate.h in Headers */,
0F790F432517CE6E009BA034 /* DisplayView.h in Headers */,
FD31609112B026F700C1A359 /* Distance.h in Headers */,
83040283249A7A6200A90D8D /* DistanceModelType.h in Headers */,
Modified: trunk/Source/WebCore/loader/EmptyClients.cpp (275162 => 275163)
--- trunk/Source/WebCore/loader/EmptyClients.cpp 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/loader/EmptyClients.cpp 2021-03-29 17:21:03 UTC (rev 275163)
@@ -133,7 +133,7 @@
return adoptRef(*new EmptyDisplayRefreshMonitor(displayID));
}
- void displayLinkFired() final { }
+ void displayLinkFired(const DisplayUpdate&) final { }
bool requestRefreshCallback() final { return false; }
void stop() final { }
Modified: trunk/Source/WebCore/platform/graphics/AnimationFrameRate.cpp (275162 => 275163)
--- trunk/Source/WebCore/platform/graphics/AnimationFrameRate.cpp 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/platform/graphics/AnimationFrameRate.cpp 2021-03-29 17:21:03 UTC (rev 275163)
@@ -26,6 +26,7 @@
#include "config.h"
#include "AnimationFrameRate.h"
+#include <wtf/text/TextStream.h>
namespace WebCore {
Modified: trunk/Source/WebCore/platform/graphics/AnimationFrameRate.h (275162 => 275163)
--- trunk/Source/WebCore/platform/graphics/AnimationFrameRate.h 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/platform/graphics/AnimationFrameRate.h 2021-03-29 17:21:03 UTC (rev 275163)
@@ -26,9 +26,13 @@
#pragma once
#include <wtf/OptionSet.h>
+#include <wtf/Optional.h>
#include <wtf/Seconds.h>
-#include <wtf/text/TextStream.h>
+namespace WTF {
+class TextStream;
+}
+
namespace WebCore {
using FramesPerSecond = unsigned;
@@ -54,6 +58,6 @@
WEBCORE_EXPORT Seconds preferredFrameInterval(const OptionSet<ThrottlingReason>&, Optional<FramesPerSecond> nominalFramesPerSecond);
WEBCORE_EXPORT FramesPerSecond preferredFramesPerSecondFromInterval(Seconds);
-WEBCORE_EXPORT TextStream& operator<<(TextStream&, const OptionSet<ThrottlingReason>&);
+WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const OptionSet<ThrottlingReason>&);
-}
+} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp (275162 => 275163)
--- trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp 2021-03-29 17:21:03 UTC (rev 275163)
@@ -128,7 +128,7 @@
return m_unscheduledFireCount > m_maxUnscheduledFireCount;
}
-void DisplayRefreshMonitor::displayLinkFired()
+void DisplayRefreshMonitor::displayLinkFired(const DisplayUpdate& displayUpdate)
{
{
auto locker = holdLock(m_lock);
@@ -146,19 +146,22 @@
setIsScheduled(false);
setIsPreviousFrameDone(false);
}
- dispatchDisplayDidRefresh();
+ dispatchDisplayDidRefresh(displayUpdate);
}
-void DisplayRefreshMonitor::dispatchDisplayDidRefresh()
+void DisplayRefreshMonitor::dispatchDisplayDidRefresh(const DisplayUpdate& displayUpdate)
{
ASSERT(isMainThread());
- displayDidRefresh();
+ displayDidRefresh(displayUpdate);
}
-void DisplayRefreshMonitor::displayDidRefresh()
+void DisplayRefreshMonitor::displayDidRefresh(const DisplayUpdate& displayUpdate)
{
ASSERT(isMainThread());
+ UNUSED_PARAM(displayUpdate);
+ LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitor::displayDidRefresh for display " << displayID() << " update " << displayUpdate);
+
// The call back can cause all our clients to be unregistered, so we need to protect
// against deletion until the end of the method.
Ref<DisplayRefreshMonitor> protectedThis(*this);
Modified: trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.h (275162 => 275163)
--- trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.h 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.h 2021-03-29 17:21:03 UTC (rev 275163)
@@ -26,6 +26,7 @@
#pragma once
#include "AnimationFrameRate.h"
+#include "DisplayUpdate.h"
#include "PlatformScreen.h"
#include <wtf/HashSet.h>
#include <wtf/Lock.h>
@@ -61,12 +62,12 @@
PlatformDisplayID displayID() const { return m_displayID; }
static RefPtr<DisplayRefreshMonitor> createDefaultDisplayRefreshMonitor(PlatformDisplayID);
- WEBCORE_EXPORT virtual void displayLinkFired();
+ WEBCORE_EXPORT virtual void displayLinkFired(const DisplayUpdate&);
protected:
WEBCORE_EXPORT explicit DisplayRefreshMonitor(PlatformDisplayID);
- WEBCORE_EXPORT virtual void dispatchDisplayDidRefresh();
+ WEBCORE_EXPORT virtual void dispatchDisplayDidRefresh(const DisplayUpdate&);
Lock& lock() { return m_lock; }
void setMaxUnscheduledFireCount(unsigned count) { m_maxUnscheduledFireCount = count; }
@@ -81,7 +82,7 @@
bool isPreviousFrameDone() const { return m_previousFrameDone; }
void setIsPreviousFrameDone(bool done) { m_previousFrameDone = done; }
- WEBCORE_EXPORT void displayDidRefresh();
+ WEBCORE_EXPORT void displayDidRefresh(const DisplayUpdate&);
private:
bool firedAndReachedMaxUnscheduledFireCount();
Modified: trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.cpp (275162 => 275163)
--- trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.cpp 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.cpp 2021-03-29 17:21:03 UTC (rev 275163)
@@ -108,11 +108,11 @@
scheduleAnimation(client);
}
-void DisplayRefreshMonitorManager::displayWasUpdated(PlatformDisplayID displayID)
+void DisplayRefreshMonitorManager::displayWasUpdated(PlatformDisplayID displayID, const DisplayUpdate& displayUpdate)
{
auto* monitor = monitorForDisplayID(displayID);
if (monitor)
- monitor->displayLinkFired();
+ monitor->displayLinkFired(displayUpdate);
}
size_t DisplayRefreshMonitorManager::findMonitorForDisplayID(PlatformDisplayID displayID) const
Modified: trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.h (275162 => 275163)
--- trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.h 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.h 2021-03-29 17:21:03 UTC (rev 275163)
@@ -34,6 +34,8 @@
namespace WebCore {
+struct DisplayUpdate;
+
class DisplayRefreshMonitorManager {
friend class NeverDestroyed<DisplayRefreshMonitorManager>;
friend class DisplayRefreshMonitor;
@@ -46,7 +48,7 @@
bool scheduleAnimation(DisplayRefreshMonitorClient&);
void windowScreenDidChange(PlatformDisplayID, DisplayRefreshMonitorClient&);
- WEBCORE_EXPORT void displayWasUpdated(PlatformDisplayID);
+ WEBCORE_EXPORT void displayWasUpdated(PlatformDisplayID, const DisplayUpdate&);
private:
DisplayRefreshMonitorManager() = default;
Copied: trunk/Source/WebCore/platform/graphics/DisplayUpdate.cpp (from rev 275162, trunk/Source/WebCore/platform/graphics/win/DisplayRefreshMonitorWin.h) (0 => 275163)
--- trunk/Source/WebCore/platform/graphics/DisplayUpdate.cpp (rev 0)
+++ trunk/Source/WebCore/platform/graphics/DisplayUpdate.cpp 2021-03-29 17:21:03 UTC (rev 275163)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "config.h"
+#include "DisplayUpdate.h"
+
+#include <wtf/text/TextStream.h>
+
+namespace WebCore {
+
+TextStream& operator<<(TextStream& ts, const DisplayUpdate& update)
+{
+ ts << update.updateIndex << "/" << update.updatesPerSecond;
+ return ts;
+}
+
+} // namespace WebCore
Copied: trunk/Source/WebCore/platform/graphics/DisplayUpdate.h (from rev 275162, trunk/Source/WebCore/platform/graphics/gtk/DisplayRefreshMonitorGtk.h) (0 => 275163)
--- trunk/Source/WebCore/platform/graphics/DisplayUpdate.h (rev 0)
+++ trunk/Source/WebCore/platform/graphics/DisplayUpdate.h 2021-03-29 17:21:03 UTC (rev 275163)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "AnimationFrameRate.h"
+#include <wtf/Optional.h>
+
+namespace WTF {
+class TextStream;
+}
+
+namespace WebCore {
+
+// Used to represent a given update. An value of { 3, 60 } indicates that this is the third update in a 1-second interval
+// on a 60fps cadence. updateIndex will reset to zero every second, so { 59, 60 } is followed by { 0, 60 }.
+struct DisplayUpdate {
+ unsigned updateIndex { 0 };
+ FramesPerSecond updatesPerSecond { 0 };
+
+ DisplayUpdate nextUpdate() const
+ {
+ return { (updateIndex + 1) % updatesPerSecond, updatesPerSecond };
+ }
+
+ template<class Encoder> void encode(Encoder&) const;
+ template<class Decoder> static Optional<DisplayUpdate> decode(Decoder&);
+};
+
+template<class Encoder>
+void DisplayUpdate::encode(Encoder& encoder) const
+{
+ encoder << updateIndex;
+ encoder << updatesPerSecond;
+}
+
+template<class Decoder>
+Optional<DisplayUpdate> DisplayUpdate::decode(Decoder& decoder)
+{
+ Optional<unsigned> updateIndex;
+ decoder >> updateIndex;
+ if (!updateIndex)
+ return WTF::nullopt;
+
+ Optional<FramesPerSecond> updatesPerSecond;
+ decoder >> updatesPerSecond;
+ if (!updatesPerSecond)
+ return WTF::nullopt;
+
+ return {{ *updateIndex, *updatesPerSecond }};
+}
+
+WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const DisplayUpdate&);
+
+} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/gtk/DisplayRefreshMonitorGtk.cpp (275162 => 275163)
--- trunk/Source/WebCore/platform/graphics/gtk/DisplayRefreshMonitorGtk.cpp 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/platform/graphics/gtk/DisplayRefreshMonitorGtk.cpp 2021-03-29 17:21:03 UTC (rev 275163)
@@ -33,6 +33,8 @@
namespace WebCore {
+constexpr FramesPerSecond DefaultFramesPerSecond = 60;
+
DisplayRefreshMonitorGtk::DisplayRefreshMonitorGtk(PlatformDisplayID displayID)
: DisplayRefreshMonitor(displayID)
{
@@ -45,9 +47,15 @@
static void onFrameClockUpdate(GdkFrameClock*, DisplayRefreshMonitorGtk* monitor)
{
- monitor->displayLinkFired();
+ monitor->displayLinkCallbackFired();
}
+void DisplayRefreshMonitorGtk::displayLinkCallbackFired()
+{
+ displayLinkFired(m_currentUpdate);
+ m_currentUpdate = m_currentUpdate.nextUpdate();
+}
+
void DisplayRefreshMonitorGtk::stop()
{
if (!m_window)
@@ -81,6 +89,9 @@
ASSERT(frameClock);
gdk_frame_clock_begin_updating(frameClock);
+ // FIXME: Use gdk_frame_clock_get_refresh_info to get the correct frame rate.
+ m_currentUpdate = { 0, DefaultFramesPerSecond };
+
m_clockIsActive = true;
return true;
}
Modified: trunk/Source/WebCore/platform/graphics/gtk/DisplayRefreshMonitorGtk.h (275162 => 275163)
--- trunk/Source/WebCore/platform/graphics/gtk/DisplayRefreshMonitorGtk.h 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/platform/graphics/gtk/DisplayRefreshMonitorGtk.h 2021-03-29 17:21:03 UTC (rev 275163)
@@ -42,6 +42,8 @@
virtual ~DisplayRefreshMonitorGtk();
+ void displayLinkCallbackFired();
+
private:
explicit DisplayRefreshMonitorGtk(PlatformDisplayID);
@@ -50,6 +52,7 @@
void stopNotificationMechanism() final;
GtkWidget* m_window { nullptr };
+ DisplayUpdate m_currentUpdate;
bool m_clockIsActive { false };
};
Modified: trunk/Source/WebCore/platform/graphics/ios/DisplayRefreshMonitorIOS.h (275162 => 275163)
--- trunk/Source/WebCore/platform/graphics/ios/DisplayRefreshMonitorIOS.h 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/platform/graphics/ios/DisplayRefreshMonitorIOS.h 2021-03-29 17:21:03 UTC (rev 275163)
@@ -43,6 +43,8 @@
virtual ~DisplayRefreshMonitorIOS();
+ void displayLinkCallbackFired();
+
private:
explicit DisplayRefreshMonitorIOS(PlatformDisplayID);
@@ -51,6 +53,7 @@
void stopNotificationMechanism() final;
RetainPtr<WebDisplayLinkHandler> m_handler;
+ DisplayUpdate m_currentUpdate;
bool m_displayLinkIsActive { false };
};
Modified: trunk/Source/WebCore/platform/graphics/ios/DisplayRefreshMonitorIOS.mm (275162 => 275163)
--- trunk/Source/WebCore/platform/graphics/ios/DisplayRefreshMonitorIOS.mm 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/platform/graphics/ios/DisplayRefreshMonitorIOS.mm 2021-03-29 17:21:03 UTC (rev 275163)
@@ -28,6 +28,7 @@
#if PLATFORM(IOS_FAMILY)
+#import "DisplayUpdate.h"
#import "Logging.h"
#import "WebCoreThread.h"
#import <QuartzCore/CADisplayLink.h>
@@ -36,6 +37,8 @@
using WebCore::DisplayRefreshMonitorIOS;
+constexpr WebCore::FramesPerSecond DisplayLinkFramesPerSecond = 60;
+
@interface WebDisplayLinkHandler : NSObject
{
DisplayRefreshMonitorIOS* m_monitor;
@@ -43,7 +46,6 @@
}
- (id)initWithMonitor:(DisplayRefreshMonitorIOS*)monitor;
-- (void)setPreferredFramesPerSecond:(NSInteger)preferredFramesPerSecond;
- (void)handleDisplayLink:(CADisplayLink *)sender;
- (void)setPaused:(BOOL)paused;
- (void)invalidate;
@@ -59,7 +61,7 @@
// Note that CADisplayLink retains its target (self), so a call to -invalidate is needed on teardown.
m_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)];
[m_displayLink addToRunLoop:WebThreadNSRunLoop() forMode:NSDefaultRunLoopMode];
- m_displayLink.preferredFramesPerSecond = 60;
+ m_displayLink.preferredFramesPerSecond = DisplayLinkFramesPerSecond;
}
return self;
}
@@ -70,16 +72,12 @@
[super dealloc];
}
-- (void)setPreferredFramesPerSecond:(NSInteger)preferredFramesPerSecond
-{
- m_displayLink.preferredFramesPerSecond = preferredFramesPerSecond;
-}
-
- (void)handleDisplayLink:(CADisplayLink *)sender
{
UNUSED_PARAM(sender);
ASSERT(isMainThread());
- m_monitor->displayLinkFired();
+
+ m_monitor->displayLinkCallbackFired();
}
- (void)setPaused:(BOOL)paused
@@ -116,6 +114,12 @@
m_handler = nil;
}
+void DisplayRefreshMonitorIOS::displayLinkCallbackFired()
+{
+ displayLinkFired(m_currentUpdate);
+ m_currentUpdate = m_currentUpdate.nextUpdate();
+}
+
bool DisplayRefreshMonitorIOS::startNotificationMechanism()
{
if (m_displayLinkIsActive)
@@ -128,7 +132,10 @@
LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitorIOS::startNotificationMechanism - starting WebDisplayLinkHandler");
[m_handler setPaused:NO];
+
+ m_currentUpdate = { 0, DisplayLinkFramesPerSecond };
m_displayLinkIsActive = true;
+
return true;
}
Modified: trunk/Source/WebCore/platform/graphics/mac/LegacyDisplayRefreshMonitorMac.cpp (275162 => 275163)
--- trunk/Source/WebCore/platform/graphics/mac/LegacyDisplayRefreshMonitorMac.cpp 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/platform/graphics/mac/LegacyDisplayRefreshMonitorMac.cpp 2021-03-29 17:21:03 UTC (rev 275163)
@@ -61,18 +61,30 @@
static CVReturn displayLinkCallback(CVDisplayLinkRef, const CVTimeStamp*, const CVTimeStamp*, CVOptionFlags, CVOptionFlags*, void* data)
{
LegacyDisplayRefreshMonitorMac* monitor = static_cast<LegacyDisplayRefreshMonitorMac*>(data);
- monitor->displayLinkFired();
+ monitor->displayLinkCallbackFired();
return kCVReturnSuccess;
}
-void LegacyDisplayRefreshMonitorMac::dispatchDisplayDidRefresh()
+void LegacyDisplayRefreshMonitorMac::displayLinkCallbackFired()
{
- RunLoop::main().dispatch([this, protectedThis = makeRef(*this)] {
+ displayLinkFired(m_currentUpdate);
+ m_currentUpdate = m_currentUpdate.nextUpdate();
+}
+
+void LegacyDisplayRefreshMonitorMac::dispatchDisplayDidRefresh(const DisplayUpdate& displayUpdate)
+{
+ RunLoop::main().dispatch([this, displayUpdate, protectedThis = makeRef(*this)] {
if (m_displayLink)
- displayDidRefresh();
+ displayDidRefresh(displayUpdate);
});
}
+WebCore::FramesPerSecond LegacyDisplayRefreshMonitorMac::nominalFramesPerSecondFromDisplayLink(CVDisplayLinkRef displayLink)
+{
+ CVTime refreshPeriod = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(displayLink);
+ return round((double)refreshPeriod.timeScale / (double)refreshPeriod.timeValue);
+}
+
bool LegacyDisplayRefreshMonitorMac::startNotificationMechanism()
{
if (!m_displayLink) {
@@ -83,6 +95,8 @@
error = CVDisplayLinkSetOutputCallback(m_displayLink, displayLinkCallback, this);
if (error)
return false;
+
+ m_currentUpdate = { 0, nominalFramesPerSecondFromDisplayLink(m_displayLink) };
}
if (!m_displayLinkIsActive) {
@@ -93,6 +107,7 @@
return false;
m_displayLinkIsActive = true;
+ m_currentUpdate.updateIndex = 0;
}
return true;
Modified: trunk/Source/WebCore/platform/graphics/mac/LegacyDisplayRefreshMonitorMac.h (275162 => 275163)
--- trunk/Source/WebCore/platform/graphics/mac/LegacyDisplayRefreshMonitorMac.h 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/platform/graphics/mac/LegacyDisplayRefreshMonitorMac.h 2021-03-29 17:21:03 UTC (rev 275163)
@@ -43,10 +43,12 @@
virtual ~LegacyDisplayRefreshMonitorMac();
+ void displayLinkCallbackFired();
+
private:
explicit LegacyDisplayRefreshMonitorMac(PlatformDisplayID);
- void dispatchDisplayDidRefresh() final;
+ void dispatchDisplayDidRefresh(const DisplayUpdate&) final;
void stop() final;
@@ -53,7 +55,11 @@
bool startNotificationMechanism() final;
void stopNotificationMechanism() final;
+ static FramesPerSecond nominalFramesPerSecondFromDisplayLink(CVDisplayLinkRef);
+
CVDisplayLinkRef m_displayLink { nullptr };
+
+ DisplayUpdate m_currentUpdate;
bool m_displayLinkIsActive { false };
};
Modified: trunk/Source/WebCore/platform/graphics/win/DisplayRefreshMonitorWin.cpp (275162 => 275163)
--- trunk/Source/WebCore/platform/graphics/win/DisplayRefreshMonitorWin.cpp 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/platform/graphics/win/DisplayRefreshMonitorWin.cpp 2021-03-29 17:21:03 UTC (rev 275163)
@@ -28,6 +28,8 @@
namespace WebCore {
+constexpr FramesPerSecond DefaultFramesPerSecond = 60;
+
RefPtr<DisplayRefreshMonitorWin> DisplayRefreshMonitorWin::create(PlatformDisplayID displayID)
{
return adoptRef(*new DisplayRefreshMonitorWin(displayID));
@@ -35,10 +37,17 @@
DisplayRefreshMonitorWin::DisplayRefreshMonitorWin(PlatformDisplayID displayID)
: DisplayRefreshMonitor(displayID)
- , m_timer(RunLoop::main(), this, &DisplayRefreshMonitor::displayLinkFired)
+ , m_timer(RunLoop::main(), this, &DisplayRefreshMonitorWin::displayLinkCallbackFired)
+ , m_currentUpdate({ 0, DefaultFramesPerSecond })
{
}
+void DisplayRefreshMonitorWin::displayLinkCallbackFired()
+{
+ displayLinkFired(m_currentUpdate);
+ m_currentUpdate = m_currentUpdate.nextUpdate();
+}
+
bool DisplayRefreshMonitorWin::startNotificationMechanism()
{
if (!m_timer.isActive())
Modified: trunk/Source/WebCore/platform/graphics/win/DisplayRefreshMonitorWin.h (275162 => 275163)
--- trunk/Source/WebCore/platform/graphics/win/DisplayRefreshMonitorWin.h 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebCore/platform/graphics/win/DisplayRefreshMonitorWin.h 2021-03-29 17:21:03 UTC (rev 275163)
@@ -39,8 +39,11 @@
bool startNotificationMechanism() final;
void stopNotificationMechanism() final;
+
+ void displayLinkCallbackFired();
RunLoop::Timer<DisplayRefreshMonitorWin> m_timer;
+ DisplayUpdate m_currentUpdate;
};
} // namespace WebCore
Modified: trunk/Source/WebKit/ChangeLog (275162 => 275163)
--- trunk/Source/WebKit/ChangeLog 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebKit/ChangeLog 2021-03-29 17:21:03 UTC (rev 275163)
@@ -1,3 +1,62 @@
+2021-03-28 Simon Fraser <[email protected]>
+
+ Plumb DisplayUpdate through the display refresh monitors
+ https://bugs.webkit.org/show_bug.cgi?id=223847
+
+ Reviewed by Sam Weinig.
+
+ Future work will allow DisplayRefreshMonitorClients to request different frame rates, which
+ are whole fractions of the display's nominal refresh rate. These various frame rate requests
+ flow up through the DisplayRefreshMonitors, and in WebKit2, up through IPC to the
+ per-display DisplayLink which may even service multiple processes.
+
+ For power reasons, we don't want to trigger display refresh notifications down the chain at
+ the highest possible frequency; at various stages of propagation the rate might be halved if
+ that's necessary for downstream clients.
+
+ To make this frequency splitting logic simple, this patch introduces DisplayUpdate, which
+ represents an update of the display, and contains data about it in the form of a numerator
+ is the frame index, and the denominator is the nominal frame rate. Frame index wraps to zero
+ every second.
+
+ For example, a 60Hz display will generate display refreshes with DisplayUpdates which
+ sequentially will be { 0, 60 }, { 1, 60 }, { 2, 60 } ... { 59, 60 }, { 0, 60 }. The
+ zeroth frame is at some arbitrary time and not aligned with wallclock time.
+
+ Thus a client with a 30Hz update requirement can simply ignore every odd-numbered frame, and
+ a client downstream from it with a 15Hz requirement, which only receives those even-numbered
+ frames, still has enough information to compute which frames to ignore.
+
+ Classes which are sources of callbacks for DisplayRefreshMonitor need to generate these
+ DisplayUpdates; that includes the various platform DisplayRefreshMonitor subclasses in
+ WebCore, and those in WebKit that live in the UI process and trigger updates over IPC.
+
+ * Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.cpp:
+ (WebKit::ThreadedDisplayRefreshMonitor::invalidate):
+ (WebKit::ThreadedDisplayRefreshMonitor::displayRefreshCallback):
+ (WebKit::ThreadedDisplayRefreshMonitor::ThreadedDisplayRefreshMonitor): Deleted.
+ * Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.h:
+ * UIProcess/mac/DisplayLink.cpp:
+ (WebKit::DisplayLink::addObserver):
+ (WebKit::DisplayLink::notifyObserversDisplayWasRefreshed):
+ * UIProcess/mac/DisplayLink.h:
+ * WebProcess/WebPage/EventDispatcher.cpp:
+ (WebKit::EventDispatcher::displayWasRefreshed):
+ * WebProcess/WebPage/EventDispatcher.h:
+ * WebProcess/WebPage/EventDispatcher.messages.in:
+ * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.h:
+ * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.mm:
+ (WebKit::RemoteLayerTreeDisplayRefreshMonitor::RemoteLayerTreeDisplayRefreshMonitor):
+ (WebKit::RemoteLayerTreeDisplayRefreshMonitor::setPreferredFramesPerSecond):
+ (WebKit::RemoteLayerTreeDisplayRefreshMonitor::didUpdateLayers):
+ * WebProcess/WebPage/mac/DisplayRefreshMonitorMac.cpp:
+ (WebKit::DisplayRefreshMonitorMac::dispatchDisplayDidRefresh):
+ * WebProcess/WebPage/mac/DisplayRefreshMonitorMac.h:
+ * WebProcess/WebProcess.cpp:
+ (WebKit::WebProcess::displayWasRefreshed):
+ * WebProcess/WebProcess.h:
+ * WebProcess/WebProcess.messages.in:
+
2021-03-29 Youenn Fablet <[email protected]>
Promote WKWebView getUserMedia SPI to API
Modified: trunk/Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.cpp (275162 => 275163)
--- trunk/Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.cpp 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.cpp 2021-03-29 17:21:03 UTC (rev 275163)
@@ -37,10 +37,14 @@
namespace WebKit {
+// FIXME: Use the correct frame rate.
+constexpr WebCore::FramesPerSecond DefaultFramesPerSecond = 60;
+
ThreadedDisplayRefreshMonitor::ThreadedDisplayRefreshMonitor(WebCore::PlatformDisplayID displayID, Client& client)
: WebCore::DisplayRefreshMonitor(displayID)
, m_displayRefreshTimer(RunLoop::main(), this, &ThreadedDisplayRefreshMonitor::displayRefreshCallback)
, m_client(&client)
+ , m_currentUpdate({ 0, DefaultFramesPerSecond })
{
#if USE(GLIB_EVENT_LOOP)
m_displayRefreshTimer.setPriority(RunLoopSourcePriority::DisplayRefreshMonitorTimer);
@@ -90,8 +94,10 @@
auto locker = holdLock(lock());
wasScheduled = isScheduled();
}
- if (wasScheduled)
- displayDidRefresh();
+ if (wasScheduled) {
+ displayDidRefresh(m_currentUpdate);
+ m_currentUpdate = m_currentUpdate.nextUpdate();
+ }
m_client = nullptr;
}
@@ -106,8 +112,10 @@
setIsPreviousFrameDone(false);
}
- if (shouldHandleDisplayRefreshNotification)
- displayDidRefresh();
+ if (shouldHandleDisplayRefreshNotification) {
+ displayDidRefresh(m_currentUpdate);
+ m_currentUpdate = m_currentUpdate.nextUpdate();
+ }
// Retrieve the scheduled status for this DisplayRefreshMonitor.
bool hasBeenRescheduled { false };
Modified: trunk/Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.h (275162 => 275163)
--- trunk/Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.h 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.h 2021-03-29 17:21:03 UTC (rev 275163)
@@ -63,6 +63,7 @@
void displayRefreshCallback();
RunLoop::Timer<ThreadedDisplayRefreshMonitor> m_displayRefreshTimer;
Client* m_client;
+ WebCore::DisplayUpdate m_currentUpdate;
};
} // namespace WebKit
Modified: trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp (275162 => 275163)
--- trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp 2021-03-29 17:21:03 UTC (rev 275163)
@@ -97,6 +97,8 @@
CVReturn error = CVDisplayLinkStart(m_displayLink);
if (error)
WTFLogAlways("Could not start the display link: %d", error);
+
+ m_currentUpdate = { 0, m_displayNominalFramesPerSecond };
}
}
@@ -152,12 +154,15 @@
m_fireCountWithoutObservers = 0;
for (auto& connection : m_observers.keys()) {
- LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink for display " << m_displayID << " sending for connection " << connection->uniqueID() << " on background queue " << shouldSendIPCOnBackgroundQueue);
+ LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink for display " << m_displayID << " (display fps " << m_displayNominalFramesPerSecond << ") update " << m_currentUpdate << " connection " << connection->uniqueID() << " on background queue " << shouldSendIPCOnBackgroundQueue);
+
if (shouldSendIPCOnBackgroundQueue)
- connection->send(Messages::EventDispatcher::DisplayWasRefreshed(m_displayID), 0);
+ connection->send(Messages::EventDispatcher::DisplayWasRefreshed(m_displayID, m_currentUpdate), 0);
else
- connection->send(Messages::WebProcess::DisplayWasRefreshed(m_displayID), 0);
+ connection->send(Messages::WebProcess::DisplayWasRefreshed(m_displayID, m_currentUpdate), 0);
}
+
+ m_currentUpdate = m_currentUpdate.nextUpdate();
}
} // namespace WebKit
Modified: trunk/Source/WebKit/UIProcess/mac/DisplayLink.h (275162 => 275163)
--- trunk/Source/WebKit/UIProcess/mac/DisplayLink.h 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebKit/UIProcess/mac/DisplayLink.h 2021-03-29 17:21:03 UTC (rev 275163)
@@ -30,6 +30,7 @@
#include "DisplayLinkObserverID.h"
#include <CoreVideo/CVDisplayLink.h>
#include <WebCore/AnimationFrameRate.h>
+#include <WebCore/DisplayUpdate.h>
#include <WebCore/PlatformScreen.h>
#include <wtf/HashMap.h>
#include <wtf/Lock.h>
@@ -69,6 +70,7 @@
HashMap<RefPtr<IPC::Connection>, Vector<DisplayLinkObserverID>> m_observers;
WebCore::PlatformDisplayID m_displayID;
WebCore::FramesPerSecond m_displayNominalFramesPerSecond { 0 };
+ WebCore::DisplayUpdate m_currentUpdate;
unsigned m_fireCountWithoutObservers { 0 };
static bool shouldSendIPCOnBackgroundQueue;
};
Modified: trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp (275162 => 275163)
--- trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp 2021-03-29 17:21:03 UTC (rev 275163)
@@ -33,6 +33,7 @@
#include "WebProcess.h"
#include "WebTouchEvent.h"
#include "WebWheelEvent.h"
+#include <WebCore/DisplayUpdate.h>
#include <WebCore/Page.h>
#include <WebCore/WheelEventTestMonitor.h>
#include <wtf/MainThread.h>
@@ -288,13 +289,13 @@
}
#if HAVE(CVDISPLAYLINK)
-void EventDispatcher::displayWasRefreshed(PlatformDisplayID displayID)
+void EventDispatcher::displayWasRefreshed(PlatformDisplayID displayID, const DisplayUpdate& displayUpdate)
{
ASSERT(!RunLoop::isMain());
notifyScrollingTreesDisplayWasRefreshed(displayID);
- RunLoop::main().dispatch([displayID]() {
- DisplayRefreshMonitorManager::sharedManager().displayWasUpdated(displayID);
+ RunLoop::main().dispatch([displayID, displayUpdate]() {
+ DisplayRefreshMonitorManager::sharedManager().displayWasUpdated(displayID, displayUpdate);
});
}
#endif
Modified: trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.h (275162 => 275163)
--- trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.h 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.h 2021-03-29 17:21:03 UTC (rev 275163)
@@ -43,6 +43,7 @@
#endif
namespace WebCore {
+struct DisplayUpdate;
class ThreadedScrollingTree;
using PlatformDisplayID = uint32_t;
}
@@ -107,7 +108,7 @@
#endif
#if PLATFORM(MAC)
- void displayWasRefreshed(WebCore::PlatformDisplayID);
+ void displayWasRefreshed(WebCore::PlatformDisplayID, const WebCore::DisplayUpdate&);
#endif
#if ENABLE(SCROLLING_THREAD)
Modified: trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.messages.in (275162 => 275163)
--- trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.messages.in 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.messages.in 2021-03-29 17:21:03 UTC (rev 275163)
@@ -30,6 +30,6 @@
GestureEvent(WebCore::PageIdentifier pageID, WebKit::WebGestureEvent event)
#endif
#if HAVE(CVDISPLAYLINK)
- DisplayWasRefreshed(uint32_t displayID)
+ DisplayWasRefreshed(uint32_t displayID, struct WebCore::DisplayUpdate update)
#endif
}
Modified: trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.h (275162 => 275163)
--- trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.h 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.h 2021-03-29 17:21:03 UTC (rev 275163)
@@ -53,6 +53,9 @@
void stopNotificationMechanism() final { }
WeakPtr<RemoteLayerTreeDrawingArea> m_drawingArea;
+
+ WebCore::FramesPerSecond m_preferredFramesPerSecond;
+ WebCore::DisplayUpdate m_currentUpdate;
};
-}
+} // namespace WebKit
Modified: trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.mm (275162 => 275163)
--- trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.mm 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.mm 2021-03-29 17:21:03 UTC (rev 275163)
@@ -32,9 +32,13 @@
namespace WebKit {
using namespace WebCore;
+constexpr FramesPerSecond DefaultPreferredFramesPerSecond = 60;
+
RemoteLayerTreeDisplayRefreshMonitor::RemoteLayerTreeDisplayRefreshMonitor(PlatformDisplayID displayID, RemoteLayerTreeDrawingArea& drawingArea)
: DisplayRefreshMonitor(displayID)
, m_drawingArea(makeWeakPtr(drawingArea))
+ , m_preferredFramesPerSecond(DefaultPreferredFramesPerSecond)
+ , m_currentUpdate({ 0, m_preferredFramesPerSecond })
{
}
@@ -46,6 +50,12 @@
void RemoteLayerTreeDisplayRefreshMonitor::setPreferredFramesPerSecond(FramesPerSecond preferredFramesPerSecond)
{
+ if (preferredFramesPerSecond == m_preferredFramesPerSecond)
+ return;
+
+ m_preferredFramesPerSecond = preferredFramesPerSecond;
+ m_currentUpdate = { 0, m_preferredFramesPerSecond };
+
if (m_drawingArea)
m_drawingArea->setPreferredFramesPerSecond(preferredFramesPerSecond);
}
@@ -72,7 +82,8 @@
return;
setIsPreviousFrameDone(false);
- displayDidRefresh();
+ displayDidRefresh(m_currentUpdate);
+ m_currentUpdate = m_currentUpdate.nextUpdate();
}
void RemoteLayerTreeDisplayRefreshMonitor::updateDrawingArea(RemoteLayerTreeDrawingArea& drawingArea)
@@ -80,4 +91,4 @@
m_drawingArea = makeWeakPtr(drawingArea);
}
-}
+} // namespace WebKit
Modified: trunk/Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.cpp (275162 => 275163)
--- trunk/Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.cpp 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.cpp 2021-03-29 17:21:03 UTC (rev 275163)
@@ -56,12 +56,13 @@
ASSERT(!m_displayLinkIsActive);
}
-void DisplayRefreshMonitorMac::dispatchDisplayDidRefresh()
+void DisplayRefreshMonitorMac::dispatchDisplayDidRefresh(const DisplayUpdate& displayUpdate)
{
+ // FIXME: This will perturb displayUpdate.
if (!m_firstCallbackInCurrentRunloop)
return;
- DisplayRefreshMonitor::dispatchDisplayDidRefresh();
+ DisplayRefreshMonitor::dispatchDisplayDidRefresh(displayUpdate);
}
bool DisplayRefreshMonitorMac::startNotificationMechanism()
Modified: trunk/Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.h (275162 => 275163)
--- trunk/Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.h 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.h 2021-03-29 17:21:03 UTC (rev 275163)
@@ -45,7 +45,7 @@
private:
explicit DisplayRefreshMonitorMac(WebCore::PlatformDisplayID);
- void dispatchDisplayDidRefresh() final;
+ void dispatchDisplayDidRefresh(const WebCore::DisplayUpdate&) final;
bool startNotificationMechanism() final;
void stopNotificationMechanism() final;
Modified: trunk/Source/WebKit/WebProcess/WebProcess.cpp (275162 => 275163)
--- trunk/Source/WebKit/WebProcess/WebProcess.cpp 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebKit/WebProcess/WebProcess.cpp 2021-03-29 17:21:03 UTC (rev 275163)
@@ -1893,11 +1893,11 @@
}
#if HAVE(CVDISPLAYLINK)
-void WebProcess::displayWasRefreshed(uint32_t displayID)
+void WebProcess::displayWasRefreshed(uint32_t displayID, const DisplayUpdate& displayUpdate)
{
ASSERT(RunLoop::isMain());
m_eventDispatcher->notifyScrollingTreesDisplayWasRefreshed(displayID);
- DisplayRefreshMonitorManager::sharedManager().displayWasUpdated(displayID);
+ DisplayRefreshMonitorManager::sharedManager().displayWasUpdated(displayID, displayUpdate);
}
#endif
Modified: trunk/Source/WebKit/WebProcess/WebProcess.h (275162 => 275163)
--- trunk/Source/WebKit/WebProcess/WebProcess.h 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebKit/WebProcess/WebProcess.h 2021-03-29 17:21:03 UTC (rev 275163)
@@ -94,6 +94,7 @@
enum class EventMakesGamepadsVisible : bool;
struct BackForwardItemIdentifier;
+struct DisplayUpdate;
struct MessagePortIdentifier;
struct MessageWithMessagePorts;
struct MockMediaDevice;
@@ -507,7 +508,7 @@
#endif
#if HAVE(CVDISPLAYLINK)
- void displayWasRefreshed(uint32_t displayID);
+ void displayWasRefreshed(uint32_t displayID, const WebCore::DisplayUpdate&);
#endif
#if PLATFORM(MAC)
Modified: trunk/Source/WebKit/WebProcess/WebProcess.messages.in (275162 => 275163)
--- trunk/Source/WebKit/WebProcess/WebProcess.messages.in 2021-03-29 16:32:58 UTC (rev 275162)
+++ trunk/Source/WebKit/WebProcess/WebProcess.messages.in 2021-03-29 17:21:03 UTC (rev 275163)
@@ -188,7 +188,7 @@
#endif
#if HAVE(CVDISPLAYLINK)
- DisplayWasRefreshed(uint32_t displayID)
+ DisplayWasRefreshed(uint32_t displayID, struct WebCore::DisplayUpdate update)
#endif
#if PLATFORM(MAC)