#include "config.h"
#include "cc/CCScheduler.h"
#include "TraceEvent.h"
namespace WebCore {
CCScheduler::CCScheduler(CCSchedulerClient* client, PassOwnPtr<CCFrameRateController> frameRateController)
: m_client(client)
, m_frameRateController(frameRateController)
, m_updateMoreResourcesPending(false)
{
ASSERT(m_client);
m_frameRateController->setClient(this);
m_frameRateController->setActive(m_stateMachine.vsyncCallbackNeeded());
}
CCScheduler::~CCScheduler()
{
m_frameRateController->setActive(false);
}
void CCScheduler::setCanBeginFrame(bool can)
{
m_stateMachine.setCanBeginFrame(can);
processScheduledActions();
}
void CCScheduler::setVisible(bool visible)
{
m_stateMachine.setVisible(visible);
processScheduledActions();
}
void CCScheduler::setNeedsCommit()
{
m_stateMachine.setNeedsCommit();
processScheduledActions();
}
void CCScheduler::setNeedsForcedCommit()
{
m_stateMachine.setNeedsForcedCommit();
processScheduledActions();
}
void CCScheduler::setNeedsRedraw()
{
m_stateMachine.setNeedsRedraw();
processScheduledActions();
}
void CCScheduler::setNeedsForcedRedraw()
{
m_stateMachine.setNeedsForcedRedraw();
processScheduledActions();
}
void CCScheduler::setMainThreadNeedsLayerTextures()
{
m_stateMachine.setMainThreadNeedsLayerTextures();
processScheduledActions();
}
void CCScheduler::beginFrameComplete()
{
TRACE_EVENT("CCScheduler::beginFrameComplete", this, 0);
m_stateMachine.beginFrameComplete();
processScheduledActions();
}
void CCScheduler::setMaxFramesPending(int maxFramesPending)
{
m_frameRateController->setMaxFramesPending(maxFramesPending);
}
void CCScheduler::didSwapBuffersComplete()
{
TRACE_EVENT("CCScheduler::didSwapBuffersComplete", this, 0);
m_frameRateController->didFinishFrame();
}
void CCScheduler::didLoseContext()
{
TRACE_EVENT("CCScheduler::didLoseContext", this, 0);
m_frameRateController->didAbortAllPendingFrames();
m_stateMachine.didLoseContext();
processScheduledActions();
}
void CCScheduler::didRecreateContext()
{
TRACE_EVENT("CCScheduler::didRecreateContext", this, 0);
m_stateMachine.didRecreateContext();
processScheduledActions();
}
void CCScheduler::vsyncTick()
{
if (m_updateMoreResourcesPending) {
m_updateMoreResourcesPending = false;
m_stateMachine.beginUpdateMoreResourcesComplete(m_client->hasMoreResourceUpdates());
}
TRACE_EVENT("CCScheduler::vsyncTick", this, 0);
m_stateMachine.didEnterVSync();
processScheduledActions();
m_stateMachine.didLeaveVSync();
}
CCSchedulerStateMachine::Action CCScheduler::nextAction()
{
m_stateMachine.setCanDraw(m_client->canDraw());
return m_stateMachine.nextAction();
}
void CCScheduler::processScheduledActions()
{
if (nextAction() == CCSchedulerStateMachine::ACTION_NONE) {
m_frameRateController->setActive(m_stateMachine.vsyncCallbackNeeded());
return;
}
CCSchedulerStateMachine::Action action;
do {
action = nextAction();
m_stateMachine.updateState(action);
switch (action) {
case CCSchedulerStateMachine::ACTION_NONE:
break;
case CCSchedulerStateMachine::ACTION_BEGIN_FRAME:
m_client->scheduledActionBeginFrame();
break;
case CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES:
m_client->scheduledActionUpdateMoreResources();
if (!m_client->hasMoreResourceUpdates()) {
m_updateMoreResourcesPending = false;
m_stateMachine.beginUpdateMoreResourcesComplete(false);
} else
m_updateMoreResourcesPending = true;
break;
case CCSchedulerStateMachine::ACTION_COMMIT:
m_client->scheduledActionCommit();
break;
case CCSchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE: {
CCScheduledActionDrawAndSwapResult result = m_client->scheduledActionDrawAndSwapIfPossible();
m_stateMachine.didDrawIfPossibleCompleted(result.didDraw);
if (result.didSwap)
m_frameRateController->didBeginFrame();
break;
}
case CCSchedulerStateMachine::ACTION_DRAW_FORCED: {
CCScheduledActionDrawAndSwapResult result = m_client->scheduledActionDrawAndSwapForced();
if (result.didSwap)
m_frameRateController->didBeginFrame();
break;
} case CCSchedulerStateMachine::ACTION_BEGIN_CONTEXT_RECREATION:
m_client->scheduledActionBeginContextRecreation();
break;
case CCSchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD:
m_client->scheduledActionAcquireLayerTexturesForMainThread();
break;
}
} while (action != CCSchedulerStateMachine::ACTION_NONE);
m_frameRateController->setActive(m_stateMachine.vsyncCallbackNeeded());
}
}