RenderingUpdateScheduler.cpp [plain text]
#include "config.h"
#include "RenderingUpdateScheduler.h"
#include "Chrome.h"
#include "ChromeClient.h"
#include "DisplayRefreshMonitorManager.h"
#include "Logging.h"
#include "Page.h"
#include <wtf/SystemTracing.h>
#include <wtf/text/TextStream.h>
namespace WebCore {
RenderingUpdateScheduler::RenderingUpdateScheduler(Page& page)
: m_page(page)
{
windowScreenDidChange(page.chrome().displayID());
}
void RenderingUpdateScheduler::setPreferredFramesPerSecond(FramesPerSecond preferredFramesPerSecond)
{
if (m_preferredFramesPerSecond == preferredFramesPerSecond)
return;
m_preferredFramesPerSecond = preferredFramesPerSecond;
DisplayRefreshMonitorManager::sharedManager().setPreferredFramesPerSecond(*this, m_preferredFramesPerSecond);
}
bool RenderingUpdateScheduler::scheduleAnimation(FramesPerSecond preferredFramesPerSecond)
{
#if !PLATFORM(IOS_FAMILY)
if (preferredFramesPerSecond != FullSpeedFramesPerSecond)
return false;
#endif
setPreferredFramesPerSecond(preferredFramesPerSecond);
auto result = DisplayRefreshMonitorManager::sharedManager().scheduleAnimation(*this);
LOG_WITH_STREAM(EventLoop, stream << "RenderingUpdateScheduler for page " << &m_page << " scheduleAnimation(" << preferredFramesPerSecond << "fps) - scheduled " << result);
return result;
}
void RenderingUpdateScheduler::adjustRenderingUpdateFrequency()
{
Seconds interval = m_page.preferredRenderingUpdateInterval();
if (interval <= 1_s)
setPreferredFramesPerSecond(preferredFramesPerSecond(interval));
if (isScheduled()) {
clearScheduled();
scheduleRenderingUpdate();
}
}
void RenderingUpdateScheduler::scheduleRenderingUpdate()
{
LOG_WITH_STREAM(EventLoop, stream << "RenderingUpdateScheduler for page " << &m_page << " scheduleTimedRenderingUpdate() - already scheduled " << isScheduled() << " page visible " << m_page.isVisible());
if (isScheduled())
return;
if (!m_page.isVisible()) {
triggerRenderingUpdate();
return;
}
tracePoint(ScheduleRenderingUpdate);
Seconds interval = m_page.preferredRenderingUpdateInterval();
if (interval <= 1_s)
m_scheduled = scheduleAnimation(preferredFramesPerSecond(interval));
if (!isScheduled())
startTimer(interval);
}
bool RenderingUpdateScheduler::isScheduled() const
{
ASSERT_IMPLIES(m_refreshTimer.get(), m_scheduled);
return m_scheduled;
}
void RenderingUpdateScheduler::startTimer(Seconds delay)
{
LOG_WITH_STREAM(EventLoop, stream << "RenderingUpdateScheduler for page " << &m_page << " startTimer(" << 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;
}
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);
}
void RenderingUpdateScheduler::displayRefreshFired()
{
LOG_WITH_STREAM(EventLoop, stream << "RenderingUpdateScheduler for page " << &m_page << " displayRefreshFired()");
tracePoint(TriggerRenderingUpdate);
clearScheduled();
triggerRenderingUpdate();
}
void RenderingUpdateScheduler::triggerRenderingUpdateForTesting()
{
triggerRenderingUpdate();
}
void RenderingUpdateScheduler::triggerRenderingUpdate()
{
m_page.chrome().client().triggerRenderingUpdate();
}
}