Diff
Modified: trunk/Source/WebCore/ChangeLog (275143 => 275144)
--- trunk/Source/WebCore/ChangeLog 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebCore/ChangeLog 2021-03-28 02:52:37 UTC (rev 275144)
@@ -1,3 +1,93 @@
+2021-03-27 Simon Fraser <[email protected]>
+
+ Allow DisplayRefreshMonitor to be more long-lived objects
+ https://bugs.webkit.org/show_bug.cgi?id=223844
+
+ Reviewed by Chris Dumez.
+
+ The existing behavior for DisplayRefreshMonitors was that they were created and destroyed
+ frequently, as their clients are registered and unregistered. In addition, some of
+ their subclasses had duplicated logic related to how often they fired without clients
+ before they were removed.
+
+ The 1:1 correspondance between DisplayRefreshMonitors and physical displays makes them
+ a useful place to store per-display information (like refresh rate), which should
+ persist whether or not they have clients, so this change prepares for that.
+
+ The main changes in this patch are:
+ 1. Provide virtual startNotificationMechanism()/stopNotificationMechanism() functions on
+ DisplayRefreshMonitor that subclasses can use to start their CVDisplayLink or related
+ functionality.
+
+ 2. Provide some shared maxUnscheduledFireCount logic that subclasses can tune to
+ provide the hysteresis used to control the start/stop of the underlying
+ notification mechanism.
+
+ 3. Provide a shared dispatchDisplayDidRefresh() function that most implementations
+ can use.
+
+ DisplayRefreshMonitorManager no longer destroys DisplayRefreshMonitors when they lose
+ all their clients. This means that DisplayRefreshMonitors are never removed, but there
+ should only ever be as many as there are physical displays, and they are only
+ active if being scheduled by clients.
+
+ * loader/EmptyClients.cpp:
+ * platform/graphics/DisplayRefreshMonitor.cpp:
+ (WebCore::DisplayRefreshMonitor::stop):
+ (WebCore::DisplayRefreshMonitor::removeClient):
+ (WebCore::DisplayRefreshMonitor::requestRefreshCallback):
+ (WebCore::DisplayRefreshMonitor::firedAndReachedMaxUnscheduledFireCount):
+ (WebCore::DisplayRefreshMonitor::displayLinkFired):
+ (WebCore::DisplayRefreshMonitor::dispatchDisplayDidRefresh):
+ (WebCore::DisplayRefreshMonitor::displayDidRefresh):
+ * platform/graphics/DisplayRefreshMonitor.h:
+ (WebCore::DisplayRefreshMonitor::setMaxUnscheduledFireCount):
+ (WebCore::DisplayRefreshMonitor::mutex):
+ (WebCore::DisplayRefreshMonitor::displayLinkFired): Deleted.
+ (WebCore::DisplayRefreshMonitor::stop): Deleted.
+ (WebCore::DisplayRefreshMonitor::shouldBeTerminated const): Deleted.
+ (WebCore::DisplayRefreshMonitor::isActive const): Deleted.
+ (WebCore::DisplayRefreshMonitor::setIsActive): Deleted.
+ * platform/graphics/DisplayRefreshMonitorManager.cpp:
+ (WebCore::DisplayRefreshMonitorManager::unregisterClient):
+ (WebCore::DisplayRefreshMonitorManager::displayDidRefresh):
+ (WebCore::DisplayRefreshMonitorManager::displayWasUpdated):
+ * platform/graphics/gtk/DisplayRefreshMonitorGtk.cpp:
+ (WebCore::DisplayRefreshMonitorGtk::~DisplayRefreshMonitorGtk):
+ (WebCore::onFrameClockUpdate):
+ (WebCore::DisplayRefreshMonitorGtk::stop):
+ (WebCore::DisplayRefreshMonitorGtk::startNotificationMechanism):
+ (WebCore::DisplayRefreshMonitorGtk::stopNotificationMechanism):
+ (WebCore::DisplayRefreshMonitorGtk::requestRefreshCallback): Deleted.
+ (WebCore::DisplayRefreshMonitorGtk::displayLinkFired): Deleted.
+ * platform/graphics/gtk/DisplayRefreshMonitorGtk.h:
+ * platform/graphics/ios/DisplayRefreshMonitorIOS.h:
+ * platform/graphics/ios/DisplayRefreshMonitorIOS.mm:
+ (-[WebDisplayLinkHandler setPaused:]):
+ (WebCore::DisplayRefreshMonitorIOS::DisplayRefreshMonitorIOS):
+ (WebCore::DisplayRefreshMonitorIOS::~DisplayRefreshMonitorIOS):
+ (WebCore::DisplayRefreshMonitorIOS::stop):
+ (WebCore::DisplayRefreshMonitorIOS::startNotificationMechanism):
+ (WebCore::DisplayRefreshMonitorIOS::stopNotificationMechanism):
+ (WebCore::DisplayRefreshMonitorIOS::requestRefreshCallback): Deleted.
+ (WebCore::DisplayRefreshMonitorIOS::displayLinkFired): Deleted.
+ * platform/graphics/mac/LegacyDisplayRefreshMonitorMac.cpp:
+ (WebCore::LegacyDisplayRefreshMonitorMac::LegacyDisplayRefreshMonitorMac):
+ (WebCore::LegacyDisplayRefreshMonitorMac::stop):
+ (WebCore::LegacyDisplayRefreshMonitorMac::dispatchDisplayDidRefresh):
+ (WebCore::LegacyDisplayRefreshMonitorMac::startNotificationMechanism):
+ (WebCore::LegacyDisplayRefreshMonitorMac::stopNotificationMechanism):
+ (WebCore::LegacyDisplayRefreshMonitorMac::requestRefreshCallback): Deleted.
+ (WebCore::LegacyDisplayRefreshMonitorMac::displayLinkFired): Deleted.
+ * platform/graphics/mac/LegacyDisplayRefreshMonitorMac.h:
+ * platform/graphics/win/DisplayRefreshMonitorWin.cpp:
+ (WebCore::DisplayRefreshMonitorWin::DisplayRefreshMonitorWin):
+ (WebCore::DisplayRefreshMonitorWin::startNotificationMechanism):
+ (WebCore::DisplayRefreshMonitorWin::stopNotificationMechanism):
+ (WebCore::DisplayRefreshMonitorWin::requestRefreshCallback): Deleted.
+ (WebCore::DisplayRefreshMonitorWin::displayLinkFired): Deleted.
+ * platform/graphics/win/DisplayRefreshMonitorWin.h:
+
2021-03-27 Ryosuke Niwa <[email protected]>
Don't add Frame as an opaque root of DOMWindow
Modified: trunk/Source/WebCore/loader/EmptyClients.cpp (275143 => 275144)
--- trunk/Source/WebCore/loader/EmptyClients.cpp 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebCore/loader/EmptyClients.cpp 2021-03-28 02:52:37 UTC (rev 275144)
@@ -137,6 +137,9 @@
bool requestRefreshCallback() final { return false; }
void stop() final { }
+ bool startNotificationMechanism() final { return true; }
+ void stopNotificationMechanism() final { }
+
private:
explicit EmptyDisplayRefreshMonitor(PlatformDisplayID displayID)
: DisplayRefreshMonitor(displayID)
Modified: trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp (275143 => 275144)
--- trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp 2021-03-28 02:52:37 UTC (rev 275144)
@@ -44,6 +44,8 @@
namespace WebCore {
+constexpr unsigned maxUnscheduledFireCount { 1 };
+
RefPtr<DisplayRefreshMonitor> DisplayRefreshMonitor::createDefaultDisplayRefreshMonitor(PlatformDisplayID displayID)
{
#if PLATFORM(MAC)
@@ -80,6 +82,12 @@
DisplayRefreshMonitor::~DisplayRefreshMonitor() = default;
+void DisplayRefreshMonitor::stop()
+{
+ stopNotificationMechanism();
+ setIsScheduled(false);
+}
+
void DisplayRefreshMonitor::addClient(DisplayRefreshMonitorClient& client)
{
m_clients.add(&client);
@@ -89,24 +97,68 @@
{
if (m_clientsToBeNotified)
m_clientsToBeNotified->remove(&client);
+
return m_clients.remove(&client);
}
-void DisplayRefreshMonitor::displayDidRefresh()
+bool DisplayRefreshMonitor::requestRefreshCallback()
{
- ASSERT(isMainRunLoop());
+ auto locker = holdLock(m_lock);
+
+ if (isScheduled())
+ return true;
+ if (!startNotificationMechanism())
+ return false;
+
+ setIsScheduled(true);
+ return true;
+}
+
+bool DisplayRefreshMonitor::firedAndReachedMaxUnscheduledFireCount()
+{
+ ASSERT(m_lock.isLocked());
+
+ if (isScheduled()) {
+ m_unscheduledFireCount = 0;
+ return false;
+ }
+
+ ++m_unscheduledFireCount;
+ return m_unscheduledFireCount > m_maxUnscheduledFireCount;
+}
+
+void DisplayRefreshMonitor::displayLinkFired()
+{
{
- LockHolder lock(m_mutex);
- LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitor " << this << " displayDidRefresh for display " << displayID() << " scheduled " << m_scheduled << " unscheduledFireCount " << m_unscheduledFireCount);
- if (!m_scheduled)
- ++m_unscheduledFireCount;
- else
- m_unscheduledFireCount = 0;
+ auto locker = holdLock(m_lock);
- m_scheduled = false;
+ // This may be off the main thread.
+ if (!isPreviousFrameDone())
+ return;
+
+ LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitor::displayLinkFired for display " << displayID() << " - scheduled " << isScheduled() << " unscheduledFireCount " << m_unscheduledFireCount << " of " << m_maxUnscheduledFireCount);
+ if (firedAndReachedMaxUnscheduledFireCount()) {
+ stopNotificationMechanism();
+ return;
+ }
+
+ setIsScheduled(false);
+ setIsPreviousFrameDone(false);
}
+ dispatchDisplayDidRefresh();
+}
+void DisplayRefreshMonitor::dispatchDisplayDidRefresh()
+{
+ ASSERT(isMainThread());
+ displayDidRefresh();
+}
+
+void DisplayRefreshMonitor::displayDidRefresh()
+{
+ ASSERT(isMainThread());
+
// 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);
@@ -129,7 +181,7 @@
m_clientsToBeNotified = nullptr;
{
- LockHolder lock(m_mutex);
+ auto locker = holdLock(m_lock);
setIsPreviousFrameDone(true);
}
Modified: trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.h (275143 => 275144)
--- trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.h 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.h 2021-03-28 02:52:37 UTC (rev 275144)
@@ -39,20 +39,19 @@
class DisplayRefreshMonitorFactory;
class DisplayRefreshMonitor : public ThreadSafeRefCounted<DisplayRefreshMonitor> {
+ friend class DisplayRefreshMonitorManager;
public:
static RefPtr<DisplayRefreshMonitor> create(DisplayRefreshMonitorFactory*, PlatformDisplayID);
WEBCORE_EXPORT virtual ~DisplayRefreshMonitor();
+
+ WEBCORE_EXPORT virtual void stop();
- virtual void displayLinkFired() { }
-
virtual void setPreferredFramesPerSecond(FramesPerSecond) { }
// Return true if callback request was scheduled, false if it couldn't be
// (e.g., hardware refresh is not available)
- virtual bool requestRefreshCallback() = 0;
+ WEBCORE_EXPORT virtual bool requestRefreshCallback();
- virtual void stop() { }
-
void windowScreenDidChange(PlatformDisplayID);
bool hasClients() const { return m_clients.size(); }
@@ -61,24 +60,21 @@
PlatformDisplayID displayID() const { return m_displayID; }
- bool shouldBeTerminated() const
- {
- const int maxInactiveFireCount = 1;
- return !m_scheduled && m_unscheduledFireCount > maxInactiveFireCount;
- }
-
static RefPtr<DisplayRefreshMonitor> createDefaultDisplayRefreshMonitor(PlatformDisplayID);
+ WEBCORE_EXPORT virtual void displayLinkFired();
protected:
WEBCORE_EXPORT explicit DisplayRefreshMonitor(PlatformDisplayID);
- friend class DisplayRefreshMonitorManager;
-
- Lock& mutex() { return m_mutex; }
+ WEBCORE_EXPORT virtual void dispatchDisplayDidRefresh();
- bool isActive() const { return m_active; }
- void setIsActive(bool active) { m_active = active; }
+ Lock& lock() { return m_lock; }
+ void setMaxUnscheduledFireCount(unsigned count) { m_maxUnscheduledFireCount = count; }
+ // Returns true if the start was successful.
+ WEBCORE_EXPORT virtual bool startNotificationMechanism() = 0;
+ WEBCORE_EXPORT virtual void stopNotificationMechanism() = 0;
+
bool isScheduled() const { return m_scheduled; }
void setIsScheduled(bool scheduled) { m_scheduled = scheduled; }
@@ -85,19 +81,21 @@
bool isPreviousFrameDone() const { return m_previousFrameDone; }
void setIsPreviousFrameDone(bool done) { m_previousFrameDone = done; }
- virtual bool hasRequestedRefreshCallback() const { return false; }
WEBCORE_EXPORT void displayDidRefresh();
private:
+ bool firedAndReachedMaxUnscheduledFireCount();
HashSet<DisplayRefreshMonitorClient*> m_clients;
HashSet<DisplayRefreshMonitorClient*>* m_clientsToBeNotified { nullptr };
- Lock m_mutex;
PlatformDisplayID m_displayID { 0 };
- int m_unscheduledFireCount { 0 }; // Number of times the display link has fired with no clients.
- bool m_active { true };
+
+ Lock m_lock;
bool m_scheduled { false };
bool m_previousFrameDone { true };
+
+ unsigned m_unscheduledFireCount { 0 };
+ unsigned m_maxUnscheduledFireCount { 0 };
};
}
Modified: trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.cpp (275143 => 275144)
--- trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.cpp 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.cpp 2021-03-28 02:52:37 UTC (rev 275144)
@@ -72,11 +72,9 @@
auto index = findMonitorForDisplayID(clientDisplayID);
if (index == notFound)
return;
+
RefPtr<DisplayRefreshMonitor> monitor = m_monitors[index].monitor;
- if (monitor->removeClient(client)) {
- if (!monitor->hasClients())
- m_monitors.remove(index);
- }
+ monitor->removeClient(client);
}
void DisplayRefreshMonitorManager::setPreferredFramesPerSecond(DisplayRefreshMonitorClient& client, FramesPerSecond preferredFramesPerSecond)
@@ -94,16 +92,9 @@
return false;
}
-void DisplayRefreshMonitorManager::displayDidRefresh(DisplayRefreshMonitor& monitor)
+void DisplayRefreshMonitorManager::displayDidRefresh(DisplayRefreshMonitor&)
{
- if (!monitor.shouldBeTerminated())
- return;
-
- LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitorManager::displayDidRefresh() - destroying monitor " << &monitor);
-
- m_monitors.removeFirstMatching([&](auto& monitorWrapper) {
- return monitorWrapper.monitor == &monitor;
- });
+ // Maybe we should remove monitors that haven't been active for some time.
}
void DisplayRefreshMonitorManager::windowScreenDidChange(PlatformDisplayID displayID, DisplayRefreshMonitorClient& client)
@@ -120,7 +111,7 @@
void DisplayRefreshMonitorManager::displayWasUpdated(PlatformDisplayID displayID)
{
auto* monitor = monitorForDisplayID(displayID);
- if (monitor && monitor->hasRequestedRefreshCallback())
+ if (monitor)
monitor->displayLinkFired();
}
Modified: trunk/Source/WebCore/platform/graphics/gtk/DisplayRefreshMonitorGtk.cpp (275143 => 275144)
--- trunk/Source/WebCore/platform/graphics/gtk/DisplayRefreshMonitorGtk.cpp 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebCore/platform/graphics/gtk/DisplayRefreshMonitorGtk.cpp 2021-03-28 02:52:37 UTC (rev 275144)
@@ -40,6 +40,16 @@
DisplayRefreshMonitorGtk::~DisplayRefreshMonitorGtk()
{
+ ASSERT(!m_window);
+}
+
+static void onFrameClockUpdate(GdkFrameClock*, DisplayRefreshMonitorGtk* monitor)
+{
+ monitor->displayLinkFired();
+}
+
+void DisplayRefreshMonitorGtk::stop()
+{
if (!m_window)
return;
@@ -46,50 +56,45 @@
auto* frameClock = gtk_widget_get_frame_clock(m_window);
ASSERT(frameClock);
g_signal_handlers_disconnect_matched(frameClock, G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
- gdk_frame_clock_end_updating(frameClock);
+
gtk_widget_destroy(m_window);
+ m_window = nullptr;
}
-static void onFrameClockUpdate(GdkFrameClock*, DisplayRefreshMonitorGtk* monitor)
+bool DisplayRefreshMonitorGtk::startNotificationMechanism()
{
- monitor->displayLinkFired();
-}
+ if (m_clockIsActive)
+ return true;
-bool DisplayRefreshMonitorGtk::requestRefreshCallback()
-{
- if (!isActive())
- return false;
-
+ GdkFrameClock* frameClock;
if (!m_window) {
// GdkFrameClockIdle is private in GDK, so we need to create a toplevel to get its frame clock.
m_window = gtk_offscreen_window_new();
gtk_widget_realize(m_window);
- auto* frameClock = gtk_widget_get_frame_clock(m_window);
+ frameClock = gtk_widget_get_frame_clock(m_window);
ASSERT(frameClock);
-
g_signal_connect(frameClock, "update", G_CALLBACK(onFrameClockUpdate), this);
- gdk_frame_clock_begin_updating(frameClock);
+ } else
+ frameClock = gtk_widget_get_frame_clock(m_window);
- setIsActive(true);
- }
+ ASSERT(frameClock);
+ gdk_frame_clock_begin_updating(frameClock);
- LockHolder lock(mutex());
- setIsScheduled(true);
+ m_clockIsActive = true;
return true;
}
-void DisplayRefreshMonitorGtk::displayLinkFired()
+void DisplayRefreshMonitorGtk::stopNotificationMechanism()
{
- {
- LockHolder lock(mutex());
- if (!isPreviousFrameDone())
- return;
+ if (!m_clockIsActive)
+ return;
- setIsPreviousFrameDone(false);
- }
- ASSERT(isMainThread());
- displayDidRefresh();
+ auto* frameClock = gtk_widget_get_frame_clock(m_window);
+ ASSERT(frameClock);
+ gdk_frame_clock_end_updating(frameClock);
+
+ m_clockIsActive = false;
}
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/gtk/DisplayRefreshMonitorGtk.h (275143 => 275144)
--- trunk/Source/WebCore/platform/graphics/gtk/DisplayRefreshMonitorGtk.h 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebCore/platform/graphics/gtk/DisplayRefreshMonitorGtk.h 2021-03-28 02:52:37 UTC (rev 275144)
@@ -42,13 +42,15 @@
virtual ~DisplayRefreshMonitorGtk();
- void displayLinkFired() override;
- bool requestRefreshCallback() override;
-
private:
explicit DisplayRefreshMonitorGtk(PlatformDisplayID);
+ void stop() final;
+ bool startNotificationMechanism() final;
+ void stopNotificationMechanism() final;
+
GtkWidget* m_window { nullptr };
+ bool m_clockIsActive { false };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/ios/DisplayRefreshMonitorIOS.h (275143 => 275144)
--- trunk/Source/WebCore/platform/graphics/ios/DisplayRefreshMonitorIOS.h 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebCore/platform/graphics/ios/DisplayRefreshMonitorIOS.h 2021-03-28 02:52:37 UTC (rev 275144)
@@ -43,14 +43,17 @@
virtual ~DisplayRefreshMonitorIOS();
- void displayLinkFired() override;
- bool requestRefreshCallback() override;
-
private:
explicit DisplayRefreshMonitorIOS(PlatformDisplayID);
+
+ void stop() final;
+ bool startNotificationMechanism() final;
+ void stopNotificationMechanism() final;
+
RetainPtr<WebDisplayLinkHandler> m_handler;
+ bool m_displayLinkIsActive { false };
};
-}
+} // namespace WebCore
#endif // PLATFORM(IOS_FAMILY)
Modified: trunk/Source/WebCore/platform/graphics/ios/DisplayRefreshMonitorIOS.mm (275143 => 275144)
--- trunk/Source/WebCore/platform/graphics/ios/DisplayRefreshMonitorIOS.mm 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebCore/platform/graphics/ios/DisplayRefreshMonitorIOS.mm 2021-03-28 02:52:37 UTC (rev 275144)
@@ -28,11 +28,14 @@
#if PLATFORM(IOS_FAMILY)
+#import "Logging.h"
#import "WebCoreThread.h"
#import <QuartzCore/CADisplayLink.h>
#import <wtf/MainThread.h>
+#import <wtf/text/TextStream.h>
using WebCore::DisplayRefreshMonitorIOS;
+
@interface WebDisplayLinkHandler : NSObject
{
DisplayRefreshMonitorIOS* m_monitor;
@@ -42,6 +45,7 @@
- (id)initWithMonitor:(DisplayRefreshMonitorIOS*)monitor;
- (void)setPreferredFramesPerSecond:(NSInteger)preferredFramesPerSecond;
- (void)handleDisplayLink:(CADisplayLink *)sender;
+- (void)setPaused:(BOOL)paused;
- (void)invalidate;
@end
@@ -78,6 +82,11 @@
m_monitor->displayLinkFired();
}
+- (void)setPaused:(BOOL)paused
+{
+ [m_displayLink setPaused:paused];
+}
+
- (void)invalidate
{
[m_displayLink invalidate];
@@ -88,39 +97,51 @@
namespace WebCore {
+constexpr unsigned maxUnscheduledFireCount { 1 };
+
DisplayRefreshMonitorIOS::DisplayRefreshMonitorIOS(PlatformDisplayID displayID)
: DisplayRefreshMonitor(displayID)
{
+ setMaxUnscheduledFireCount(maxUnscheduledFireCount);
}
DisplayRefreshMonitorIOS::~DisplayRefreshMonitorIOS()
{
+ ASSERT(!m_handler);
+}
+
+void DisplayRefreshMonitorIOS::stop()
+{
[m_handler invalidate];
+ m_handler = nil;
}
-bool DisplayRefreshMonitorIOS::requestRefreshCallback()
+bool DisplayRefreshMonitorIOS::startNotificationMechanism()
{
- if (!isActive())
- return false;
+ if (m_displayLinkIsActive)
+ return true;
if (!m_handler) {
+ LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitorIOS::startNotificationMechanism - creating WebDisplayLinkHandler");
m_handler = adoptNS([[WebDisplayLinkHandler alloc] initWithMonitor:this]);
- setIsActive(true);
}
- setIsScheduled(true);
+ LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitorIOS::startNotificationMechanism - starting WebDisplayLinkHandler");
+ [m_handler setPaused:NO];
+ m_displayLinkIsActive = true;
return true;
}
-void DisplayRefreshMonitorIOS::displayLinkFired()
+void DisplayRefreshMonitorIOS::stopNotificationMechanism()
{
- if (!isPreviousFrameDone())
+ if (!m_displayLinkIsActive)
return;
- setIsPreviousFrameDone(false);
- displayDidRefresh();
+ LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitorIOS::stopNotificationMechanism - pausing WebDisplayLinkHandler");
+ [m_handler setPaused:YES];
+ m_displayLinkIsActive = false;
}
-}
+} // namespace WebCore
#endif // PLATFORM(IOS_FAMILY)
Modified: trunk/Source/WebCore/platform/graphics/mac/LegacyDisplayRefreshMonitorMac.cpp (275143 => 275144)
--- trunk/Source/WebCore/platform/graphics/mac/LegacyDisplayRefreshMonitorMac.cpp 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebCore/platform/graphics/mac/LegacyDisplayRefreshMonitorMac.cpp 2021-03-28 02:52:37 UTC (rev 275144)
@@ -28,16 +28,21 @@
#if PLATFORM(MAC)
+#include "Logging.h"
#include "RuntimeApplicationChecks.h"
-#include <QuartzCore/QuartzCore.h>
+#include <CoreVideo/CVDisplayLink.h>
#include <wtf/RunLoop.h>
+#include <wtf/text/TextStream.h>
namespace WebCore {
+constexpr unsigned maxUnscheduledFireCount { 20 };
+
LegacyDisplayRefreshMonitorMac::LegacyDisplayRefreshMonitorMac(PlatformDisplayID displayID)
: DisplayRefreshMonitor(displayID)
{
ASSERT(!isInWebProcess());
+ setMaxUnscheduledFireCount(maxUnscheduledFireCount);
}
LegacyDisplayRefreshMonitorMac::~LegacyDisplayRefreshMonitorMac()
@@ -47,10 +52,8 @@
void LegacyDisplayRefreshMonitorMac::stop()
{
- if (!m_displayLink)
- return;
-
- CVDisplayLinkStop(m_displayLink);
+ DisplayRefreshMonitor::stop();
+ LOG_WITH_STREAM(DisplayLink, stream << "LegacyDisplayRefreshMonitorMac::stop for dipslay " << displayID() << " destroying display link");
CVDisplayLinkRelease(m_displayLink);
m_displayLink = nullptr;
}
@@ -62,14 +65,18 @@
return kCVReturnSuccess;
}
-bool LegacyDisplayRefreshMonitorMac::requestRefreshCallback()
+void LegacyDisplayRefreshMonitorMac::dispatchDisplayDidRefresh()
{
- if (!isActive())
- return false;
+ RunLoop::main().dispatch([this, protectedThis = makeRef(*this)] {
+ if (m_displayLink)
+ displayDidRefresh();
+ });
+}
+bool LegacyDisplayRefreshMonitorMac::startNotificationMechanism()
+{
if (!m_displayLink) {
- setIsActive(false);
- CVReturn error = CVDisplayLinkCreateWithCGDisplay(displayID(), &m_displayLink);
+ auto error = CVDisplayLinkCreateWithCGDisplay(displayID(), &m_displayLink);
if (error)
return false;
@@ -76,33 +83,34 @@
error = CVDisplayLinkSetOutputCallback(m_displayLink, displayLinkCallback, this);
if (error)
return false;
+ }
- error = CVDisplayLinkStart(m_displayLink);
+ if (!m_displayLinkIsActive) {
+ LOG_WITH_STREAM(DisplayLink, stream << "LegacyDisplayRefreshMonitorMac::startNotificationMechanism for display " << displayID() << " starting display link");
+
+ auto error = CVDisplayLinkStart(m_displayLink);
if (error)
return false;
-
- setIsActive(true);
+
+ m_displayLinkIsActive = true;
}
- LockHolder lock(mutex());
- setIsScheduled(true);
return true;
}
-void LegacyDisplayRefreshMonitorMac::displayLinkFired()
+void LegacyDisplayRefreshMonitorMac::stopNotificationMechanism()
{
- LockHolder lock(mutex());
- if (!isPreviousFrameDone())
+ if (!m_displayLinkIsActive)
return;
- setIsPreviousFrameDone(false);
-
- RunLoop::main().dispatch([this, protectedThis = makeRef(*this)] {
- if (m_displayLink)
- displayDidRefresh();
- });
+ if (m_displayLink) {
+ LOG_WITH_STREAM(DisplayLink, stream << "LegacyDisplayRefreshMonitorMac::stopNotificationMechanism for display " << displayID() << " stopping display link");
+ CVDisplayLinkStop(m_displayLink);
+ }
+
+ m_displayLinkIsActive = false;
}
-}
+} // namespace WebCore
#endif // PLATFORM(MAC)
Modified: trunk/Source/WebCore/platform/graphics/mac/LegacyDisplayRefreshMonitorMac.h (275143 => 275144)
--- trunk/Source/WebCore/platform/graphics/mac/LegacyDisplayRefreshMonitorMac.h 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebCore/platform/graphics/mac/LegacyDisplayRefreshMonitorMac.h 2021-03-28 02:52:37 UTC (rev 275144)
@@ -43,16 +43,20 @@
virtual ~LegacyDisplayRefreshMonitorMac();
- void displayLinkFired() final;
- bool requestRefreshCallback() final;
- void stop() final;
-
private:
explicit LegacyDisplayRefreshMonitorMac(PlatformDisplayID);
+ void dispatchDisplayDidRefresh() final;
+
+ void stop() final;
+
+ bool startNotificationMechanism() final;
+ void stopNotificationMechanism() final;
+
CVDisplayLinkRef m_displayLink { nullptr };
+ bool m_displayLinkIsActive { false };
};
-}
+} // namespace WebCore
#endif // PLATFORM(MAC)
Modified: trunk/Source/WebCore/platform/graphics/win/DisplayRefreshMonitorWin.cpp (275143 => 275144)
--- trunk/Source/WebCore/platform/graphics/win/DisplayRefreshMonitorWin.cpp 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebCore/platform/graphics/win/DisplayRefreshMonitorWin.cpp 2021-03-28 02:52:37 UTC (rev 275144)
@@ -35,27 +35,21 @@
DisplayRefreshMonitorWin::DisplayRefreshMonitorWin(PlatformDisplayID displayID)
: DisplayRefreshMonitor(displayID)
- , m_timer(RunLoop::main(), this, &DisplayRefreshMonitorWin::displayLinkFired)
+ , m_timer(RunLoop::main(), this, &DisplayRefreshMonitor::displayLinkFired)
{
}
-bool DisplayRefreshMonitorWin::requestRefreshCallback()
+bool DisplayRefreshMonitorWin::startNotificationMechanism()
{
- if (!isActive())
- return false;
- m_timer.startOneShot(16_ms);
- setIsActive(true);
- setIsScheduled(true);
+ if (!m_timer.isActive())
+ m_timer.startRepeating(16_ms);
+
return true;
}
-void DisplayRefreshMonitorWin::displayLinkFired()
+void DisplayRefreshMonitorWin::stopNotificationMechanism()
{
- if (!isPreviousFrameDone())
- return;
-
- setIsPreviousFrameDone(false);
- displayDidRefresh();
+ m_timer.stop();
}
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/win/DisplayRefreshMonitorWin.h (275143 => 275144)
--- trunk/Source/WebCore/platform/graphics/win/DisplayRefreshMonitorWin.h 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebCore/platform/graphics/win/DisplayRefreshMonitorWin.h 2021-03-28 02:52:37 UTC (rev 275144)
@@ -34,11 +34,12 @@
public:
static RefPtr<DisplayRefreshMonitorWin> create(PlatformDisplayID);
- void displayLinkFired() override;
- bool requestRefreshCallback() override;
-
private:
explicit DisplayRefreshMonitorWin(PlatformDisplayID);
+
+ bool startNotificationMechanism() final;
+ void stopNotificationMechanism() final;
+
RunLoop::Timer<DisplayRefreshMonitorWin> m_timer;
};
Modified: trunk/Source/WebKit/ChangeLog (275143 => 275144)
--- trunk/Source/WebKit/ChangeLog 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebKit/ChangeLog 2021-03-28 02:52:37 UTC (rev 275144)
@@ -1,3 +1,51 @@
+2021-03-27 Simon Fraser <[email protected]>
+
+ Allow DisplayRefreshMonitor to be more long-lived objects
+ https://bugs.webkit.org/show_bug.cgi?id=223844
+
+ Reviewed by Chris Dumez.
+
+ The existing behavior for DisplayRefreshMonitors was that they were created and destroyed
+ frequently, as their clients are registered and unregistered. In addition, some of
+ their subclasses had duplicated logic related to how often they fired without clients
+ before they were removed.
+
+ The 1:1 correspondance between DisplayRefreshMonitors and physical displays makes them
+ a useful place to store per-display information (like refresh rate), which should
+ persist whether or not they have clients, so this change prepares for that.
+
+ The main changes in this patch are:
+ 1. Provide virtual startNotificationMechanism()/stopNotificationMechanism() functions on
+ DisplayRefreshMonitor that subclasses can use to start their CVDisplayLink or related
+ functionality.
+
+ 2. Provide some shared maxUnscheduledFireCount logic that subclasses can tune to
+ provide the hysteresis used to control the start/stop of the underlying
+ notification mechanism.
+
+ 3. Provide a shared dispatchDisplayDidRefresh() function that most implementations
+ can use.
+
+ * Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.cpp:
+ * Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.h:
+ * UIProcess/mac/DisplayLink.cpp:
+ (WebKit::DisplayLink::DisplayLink):
+ (WebKit::DisplayLink::~DisplayLink):
+ (WebKit::DisplayLink::addObserver):
+ (WebKit::DisplayLink::notifyObserversDisplayWasRefreshed):
+ * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.h:
+ * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.mm:
+ (WebKit::RemoteLayerTreeDisplayRefreshMonitor::requestRefreshCallback):
+ * WebProcess/WebPage/mac/DisplayRefreshMonitorMac.cpp:
+ (WebKit::DisplayRefreshMonitorMac::DisplayRefreshMonitorMac):
+ (WebKit::DisplayRefreshMonitorMac::~DisplayRefreshMonitorMac):
+ (WebKit::DisplayRefreshMonitorMac::dispatchDisplayDidRefresh):
+ (WebKit::DisplayRefreshMonitorMac::startNotificationMechanism):
+ (WebKit::DisplayRefreshMonitorMac::stopNotificationMechanism):
+ (WebKit::DisplayRefreshMonitorMac::requestRefreshCallback): Deleted.
+ (WebKit::DisplayRefreshMonitorMac::displayLinkFired): Deleted.
+ * WebProcess/WebPage/mac/DisplayRefreshMonitorMac.h:
+
2021-03-27 Kate Cheney <[email protected]>
PCM: Send report to both click source and attribution destination website
Modified: trunk/Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.cpp (275143 => 275144)
--- trunk/Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.cpp 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.cpp 2021-03-28 02:52:37 UTC (rev 275144)
@@ -55,7 +55,7 @@
bool previousFrameDone { false };
{
- LockHolder locker(mutex());
+ auto locker = holdLock(lock());
setIsScheduled(true);
previousFrameDone = isPreviousFrameDone();
}
@@ -71,7 +71,7 @@
bool ThreadedDisplayRefreshMonitor::requiresDisplayRefreshCallback()
{
- LockHolder locker(mutex());
+ auto locker = holdLock(lock());
return isScheduled() && isPreviousFrameDone();
}
@@ -87,7 +87,7 @@
m_displayRefreshTimer.stop();
bool wasScheduled = false;
{
- LockHolder locker(mutex());
+ auto locker = holdLock(lock());
wasScheduled = isScheduled();
}
if (wasScheduled)
@@ -95,11 +95,12 @@
m_client = nullptr;
}
+// FIXME: Refactor to share more code with DisplayRefreshMonitor::displayLinkFired().
void ThreadedDisplayRefreshMonitor::displayRefreshCallback()
{
bool shouldHandleDisplayRefreshNotification { false };
{
- LockHolder locker(mutex());
+ auto locker = holdLock(lock());
shouldHandleDisplayRefreshNotification = isScheduled() && isPreviousFrameDone();
if (shouldHandleDisplayRefreshNotification)
setIsPreviousFrameDone(false);
@@ -111,7 +112,7 @@
// Retrieve the scheduled status for this DisplayRefreshMonitor.
bool hasBeenRescheduled { false };
{
- LockHolder locker(mutex());
+ auto locker = holdLock(lock());
hasBeenRescheduled = isScheduled();
}
Modified: trunk/Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.h (275143 => 275144)
--- trunk/Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.h 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.h 2021-03-28 02:52:37 UTC (rev 275144)
@@ -57,6 +57,9 @@
private:
ThreadedDisplayRefreshMonitor(WebCore::PlatformDisplayID, Client&);
+ bool startNotificationMechanism() final { return true; }
+ void stopNotificationMechanism() final { }
+
void displayRefreshCallback();
RunLoop::Timer<ThreadedDisplayRefreshMonitor> m_displayRefreshTimer;
Client* m_client;
Modified: trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp (275143 => 275144)
--- trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp 2021-03-28 02:52:37 UTC (rev 275144)
@@ -29,8 +29,10 @@
#if HAVE(CVDISPLAYLINK)
#include "EventDispatcherMessages.h"
+#include "Logging.h"
#include "WebProcessMessages.h"
#include <wtf/ProcessPrivilege.h>
+#include <wtf/text/TextStream.h>
namespace WebKit {
@@ -40,6 +42,8 @@
DisplayLink::DisplayLink(WebCore::PlatformDisplayID displayID)
: m_displayID(displayID)
{
+ LOG_WITH_STREAM(DisplayLink, stream << "[UI ] Creating DisplayLink for display " << displayID);
+
// FIXME: We can get here with displayID == 0 (webkit.org/b/212120), in which case CVDisplayLinkCreateWithCGDisplay()
// probably defaults to the main screen.
ASSERT(hasProcessPrivilege(ProcessPrivilege::CanCommunicateWithWindowServer));
@@ -58,6 +62,8 @@
DisplayLink::~DisplayLink()
{
+ LOG_WITH_STREAM(DisplayLink, stream << "[UI ] Destroying DisplayLink for display " << m_displayID);
+
ASSERT(hasProcessPrivilege(ProcessPrivilege::CanCommunicateWithWindowServer));
ASSERT(m_displayLink);
if (!m_displayLink)
@@ -85,6 +91,7 @@
}
if (!CVDisplayLinkIsRunning(m_displayLink)) {
+ LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink for display " << m_displayID << " starting CVDisplayLink");
CVReturn error = CVDisplayLinkStart(m_displayLink);
if (error)
WTFLogAlways("Could not start the display link: %d", error);
@@ -134,13 +141,16 @@
LockHolder locker(m_observersLock);
if (m_observers.isEmpty()) {
- if (++m_fireCountWithoutObservers >= maxFireCountWithoutObservers)
+ if (++m_fireCountWithoutObservers >= maxFireCountWithoutObservers) {
+ LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink for display " << m_displayID << " fired " << m_fireCountWithoutObservers << " times with no observers; stopping CVDisplayLink");
CVDisplayLinkStop(m_displayLink);
+ }
return;
}
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);
if (shouldSendIPCOnBackgroundQueue)
connection->send(Messages::EventDispatcher::DisplayWasRefreshed(m_displayID), 0);
else
Modified: trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.h (275143 => 275144)
--- trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.h 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.h 2021-03-28 02:52:37 UTC (rev 275144)
@@ -41,7 +41,7 @@
virtual ~RemoteLayerTreeDisplayRefreshMonitor();
void setPreferredFramesPerSecond(WebCore::FramesPerSecond) override;
- bool requestRefreshCallback() override;
+ bool requestRefreshCallback() final;
void didUpdateLayers();
void updateDrawingArea(RemoteLayerTreeDrawingArea&);
@@ -49,6 +49,9 @@
private:
explicit RemoteLayerTreeDisplayRefreshMonitor(WebCore::PlatformDisplayID, RemoteLayerTreeDrawingArea&);
+ bool startNotificationMechanism() final { return true; }
+ void stopNotificationMechanism() final { }
+
WeakPtr<RemoteLayerTreeDrawingArea> m_drawingArea;
};
Modified: trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.mm (275143 => 275144)
--- trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.mm 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.mm 2021-03-28 02:52:37 UTC (rev 275144)
@@ -26,6 +26,9 @@
#import "config.h"
#import "RemoteLayerTreeDisplayRefreshMonitor.h"
+#import "Logging.h"
+#include <wtf/text/TextStream.h>
+
namespace WebKit {
using namespace WebCore;
@@ -49,13 +52,14 @@
bool RemoteLayerTreeDisplayRefreshMonitor::requestRefreshCallback()
{
- if (!m_drawingArea || !isActive())
+ if (!m_drawingArea)
return false;
- if (!isScheduled())
+ if (!isScheduled()) {
+ LOG_WITH_STREAM(DisplayLink, stream << "RemoteLayerTreeDisplayRefreshMonitor::requestRefreshCallback - triggering update");
static_cast<DrawingArea&>(*m_drawingArea.get()).triggerRenderingUpdate();
+ }
- setIsActive(true);
setIsScheduled(true);
return true;
}
Modified: trunk/Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.cpp (275143 => 275144)
--- trunk/Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.cpp 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.cpp 2021-03-28 02:52:37 UTC (rev 275144)
@@ -39,49 +39,61 @@
namespace WebKit {
using namespace WebCore;
+// Avoid repeated start/stop IPC when rescheduled inside the callback.
+constexpr unsigned maxUnscheduledFireCount { 1 };
+
DisplayRefreshMonitorMac::DisplayRefreshMonitorMac(PlatformDisplayID displayID)
: DisplayRefreshMonitor(displayID)
, m_observerID(DisplayLinkObserverID::generate())
{
ASSERT(isMainRunLoop());
+ setMaxUnscheduledFireCount(maxUnscheduledFireCount);
}
DisplayRefreshMonitorMac::~DisplayRefreshMonitorMac()
{
- if (m_hasSentMessage)
- WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::StopDisplayLink(m_observerID, displayID()), 0);
+ // stop() should have been called.
+ ASSERT(!m_displayLinkIsActive);
}
-bool DisplayRefreshMonitorMac::requestRefreshCallback()
+void DisplayRefreshMonitorMac::dispatchDisplayDidRefresh()
{
- if (!isActive())
- return false;
+ if (!m_firstCallbackInCurrentRunloop)
+ return;
- if (!m_hasSentMessage) {
- WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::StartDisplayLink(m_observerID, displayID()), 0);
- m_hasSentMessage = true;
+ DisplayRefreshMonitor::dispatchDisplayDidRefresh();
+}
+
+bool DisplayRefreshMonitorMac::startNotificationMechanism()
+{
+ if (m_displayLinkIsActive)
+ return true;
+
+ LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitorMac::requestRefreshCallback - starting");
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::StartDisplayLink(m_observerID, displayID()), 0);
+ if (!m_runLoopObserver) {
+ // The RunLoopObserver repeats.
m_runLoopObserver = makeUnique<RunLoopObserver>(kCFRunLoopEntry, [this]() {
m_firstCallbackInCurrentRunloop = true;
});
- m_runLoopObserver->schedule(CFRunLoopGetCurrent());
}
-
- setIsScheduled(true);
+ m_runLoopObserver->schedule(CFRunLoopGetCurrent());
+ m_displayLinkIsActive = true;
+
return true;
}
-void DisplayRefreshMonitorMac::displayLinkFired()
+void DisplayRefreshMonitorMac::stopNotificationMechanism()
{
- ASSERT(isMainRunLoop());
- if (!m_firstCallbackInCurrentRunloop)
+ if (!m_displayLinkIsActive)
return;
- m_firstCallbackInCurrentRunloop = false;
-
- LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitorMac::displayLinkFired() for display " << displayID());
-
- displayDidRefresh();
+ LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitorMac::requestRefreshCallback - stopping");
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::StopDisplayLink(m_observerID, displayID()), 0);
+ m_runLoopObserver->invalidate();
+
+ m_displayLinkIsActive = false;
}
} // namespace WebKit
Modified: trunk/Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.h (275143 => 275144)
--- trunk/Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.h 2021-03-28 00:40:03 UTC (rev 275143)
+++ trunk/Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.h 2021-03-28 02:52:37 UTC (rev 275144)
@@ -39,20 +39,21 @@
{
return adoptRef(*new DisplayRefreshMonitorMac(displayID));
}
-
+
virtual ~DisplayRefreshMonitorMac();
-
- void displayLinkFired() final;
- bool requestRefreshCallback() final;
-
+
private:
explicit DisplayRefreshMonitorMac(WebCore::PlatformDisplayID);
-
- bool hasRequestedRefreshCallback() const final { return m_hasSentMessage; }
+ void dispatchDisplayDidRefresh() final;
+
+ bool startNotificationMechanism() final;
+ void stopNotificationMechanism() final;
+
DisplayLinkObserverID m_observerID;
std::unique_ptr<WebCore::RunLoopObserver> m_runLoopObserver;
- bool m_hasSentMessage { false };
+
+ bool m_displayLinkIsActive { false };
bool m_firstCallbackInCurrentRunloop { false };
};