DisplayRefreshMonitor.cpp [plain text]
#include "config.h"
#include "DisplayRefreshMonitor.h"
#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
#include "DisplayRefreshMonitorClient.h"
#include "DisplayRefreshMonitorManager.h"
#if PLATFORM(IOS)
#include "DisplayRefreshMonitorIOS.h"
#elif PLATFORM(MAC)
#include "DisplayRefreshMonitorMac.h"
#elif PLATFORM(GTK)
#include "DisplayRefreshMonitorGtk.h"
#endif
namespace WebCore {
RefPtr<DisplayRefreshMonitor> DisplayRefreshMonitor::createDefaultDisplayRefreshMonitor(PlatformDisplayID displayID)
{
#if PLATFORM(MAC)
return DisplayRefreshMonitorMac::create(displayID);
#endif
#if PLATFORM(IOS)
return DisplayRefreshMonitorIOS::create(displayID);
#endif
#if PLATFORM(GTK)
return DisplayRefreshMonitorGtk::create(displayID);
#endif
UNUSED_PARAM(displayID);
return nullptr;
}
RefPtr<DisplayRefreshMonitor> DisplayRefreshMonitor::create(DisplayRefreshMonitorClient& client)
{
return client.createDisplayRefreshMonitor(client.displayID());
}
DisplayRefreshMonitor::DisplayRefreshMonitor(PlatformDisplayID displayID)
: m_displayID(displayID)
{
}
DisplayRefreshMonitor::~DisplayRefreshMonitor() = default;
void DisplayRefreshMonitor::handleDisplayRefreshedNotificationOnMainThread(void* data)
{
DisplayRefreshMonitor* monitor = static_cast<DisplayRefreshMonitor*>(data);
monitor->displayDidRefresh();
}
void DisplayRefreshMonitor::addClient(DisplayRefreshMonitorClient& client)
{
m_clients.add(&client);
}
bool DisplayRefreshMonitor::removeClient(DisplayRefreshMonitorClient& client)
{
if (m_clientsToBeNotified)
m_clientsToBeNotified->remove(&client);
return m_clients.remove(&client);
}
void DisplayRefreshMonitor::displayDidRefresh()
{
{
LockHolder lock(m_mutex);
LOG(RequestAnimationFrame, "DisplayRefreshMonitor::displayDidRefresh(%p) - m_scheduled(%d), m_unscheduledFireCount(%d)", this, m_scheduled, m_unscheduledFireCount);
if (!m_scheduled)
++m_unscheduledFireCount;
else
m_unscheduledFireCount = 0;
m_scheduled = false;
}
Ref<DisplayRefreshMonitor> protectedThis(*this);
HashSet<DisplayRefreshMonitorClient*> clientsToBeNotified = m_clients;
m_clientsToBeNotified = &clientsToBeNotified;
while (!clientsToBeNotified.isEmpty()) {
DisplayRefreshMonitorClient* client = clientsToBeNotified.takeAny();
client->fireDisplayRefreshIfNeeded();
if (m_clientsToBeNotified != &clientsToBeNotified)
break;
}
if (m_clientsToBeNotified == &clientsToBeNotified)
m_clientsToBeNotified = nullptr;
{
LockHolder lock(m_mutex);
setIsPreviousFrameDone(true);
}
DisplayRefreshMonitorManager::sharedManager().displayDidRefresh(*this);
}
}
#endif // USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)