RenderingUpdateScheduler.cpp [plain text]
#include "config.h"
#include "RenderingUpdateScheduler.h"
#include "Chrome.h"
#include "ChromeClient.h"
#include "DisplayRefreshMonitorManager.h"
#include "Page.h"
#include <wtf/SystemTracing.h>
namespace WebCore {
RenderingUpdateScheduler::RenderingUpdateScheduler(Page& page)
: m_page(page)
{
#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
windowScreenDidChange(page.chrome().displayID());
#endif
}
#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) && PLATFORM(IOS_FAMILY)
void RenderingUpdateScheduler::adjustFramesPerSecond()
{
Seconds interval = m_page.preferredRenderingUpdateInterval();
if (interval < 1_s)
DisplayRefreshMonitorManager::sharedManager().setPreferredFramesPerSecond(*this, preferredFramesPerSecond(interval));
}
#endif
void RenderingUpdateScheduler::adjustRenderingUpdateFrequency()
{
#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) && PLATFORM(IOS_FAMILY)
adjustFramesPerSecond();
#endif
if (isScheduled()) {
clearScheduled();
scheduleTimedRenderingUpdate();
}
}
void RenderingUpdateScheduler::scheduleTimedRenderingUpdate()
{
if (isScheduled())
return;
if (!m_page.isVisible()) {
scheduleImmediateRenderingUpdate();
return;
}
tracePoint(ScheduleRenderingUpdate);
Seconds interval = m_page.preferredRenderingUpdateInterval();
#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
if (interval < 1_s) {
#if PLATFORM(IOS_FAMILY)
if (!m_isMonitorCreated) {
adjustFramesPerSecond();
m_isMonitorCreated = true;
}
#else
if (interval == FullSpeedAnimationInterval)
#endif
m_scheduled = DisplayRefreshMonitorManager::sharedManager().scheduleAnimation(*this);
}
#endif
if (!isScheduled())
startTimer(interval);
}
bool RenderingUpdateScheduler::isScheduled() const
{
ASSERT_IMPLIES(m_refreshTimer.get(), m_scheduled);
return m_scheduled;
}
void RenderingUpdateScheduler::startTimer(Seconds delay)
{
ASSERT(!isScheduled());
m_refreshTimer = makeUnique<Timer>(*this, &RenderingUpdateScheduler::displayRefreshFired);
m_refreshTimer->startOneShot(delay);
m_scheduled = true;
}
void RenderingUpdateScheduler::clearScheduled()
{
m_scheduled = false;
m_refreshTimer = nullptr;
}
#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
RefPtr<DisplayRefreshMonitor> RenderingUpdateScheduler::createDisplayRefreshMonitor(PlatformDisplayID displayID) const
{
if (auto monitor = m_page.chrome().client().createDisplayRefreshMonitor(displayID))
return monitor;
return DisplayRefreshMonitor::createDefaultDisplayRefreshMonitor(displayID);
}
void RenderingUpdateScheduler::windowScreenDidChange(PlatformDisplayID displayID)
{
DisplayRefreshMonitorManager::sharedManager().windowScreenDidChange(displayID, *this);
}
#endif
void RenderingUpdateScheduler::displayRefreshFired()
{
tracePoint(TriggerRenderingUpdate);
clearScheduled();
scheduleImmediateRenderingUpdate();
}
void RenderingUpdateScheduler::scheduleImmediateRenderingUpdate()
{
m_page.chrome().client().scheduleCompositingLayerFlush();
}
void RenderingUpdateScheduler::scheduleRenderingUpdate()
{
if (m_page.chrome().client().needsImmediateRenderingUpdate())
scheduleImmediateRenderingUpdate();
else
scheduleTimedRenderingUpdate();
}
}