站在老罗的肩膀上:https://blog.youkuaiyun.com/luoshengyang/article/details/51054990
调度器通过类SchedulerStateMachine描述内部的状态机。有以下4种状态
class CC_EXPORT SchedulerStateMachine {
public:
...
// corresponding to previous OutputSurfaceState
enum class LayerTreeFrameSinkState {
NONE,
ACTIVE,
CREATING,
WAITING_FOR_FIRST_COMMIT,
WAITING_FOR_FIRST_ACTIVATION,
};
...
enum class BeginImplFrameState {
IDLE,
INSIDE_BEGIN_FRAME,
INSIDE_DEADLINE,
};
// corresponding to previous CommitState
enum class BeginMainFrameState {
IDLE,
SENT,
STARTED,
READY_TO_COMMIT,
};
enum class ForcedRedrawOnTimeoutState {
IDLE,
WAITING_FOR_COMMIT,
WAITING_FOR_ACTIVATION,
WAITING_FOR_DRAW,
};
...
LayerTreeFrameSinkState layer_tree_frame_sink_state_ =
LayerTreeFrameSinkState::NONE;
BeginImplFrameState begin_impl_frame_state_ = BeginImplFrameState::IDLE;
BeginMainFrameState begin_main_frame_state_ = BeginMainFrameState::IDLE;
ForcedRedrawOnTimeoutState forced_redraw_state_ =
ForcedRedrawOnTimeoutState::IDLE;
}
enum class Action {
NONE,
SEND_BEGIN_MAIN_FRAME,
COMMIT,
ACTIVATE_SYNC_TREE,
PERFORM_IMPL_SIDE_INVALIDATION,
DRAW_IF_POSSIBLE,
DRAW_FORCED,
DRAW_ABORT,
BEGIN_LAYER_TREE_FRAME_SINK_CREATION,
PREPARE_TILES,
INVALIDATE_LAYER_TREE_FRAME_SINK,
NOTIFY_BEGIN_MAIN_FRAME_NOT_SENT,
};
1. LayerTreeFrameSinkState(原OutputSurfaceState)描述的是网页绘图表面的状态,记录于layer_tree_frame_sink_state_
2. BeginImplFrameState记录于begin_impl_frame_state_
3. BeginMainFrameState(原CommitState)描述的是CC Layer Tree的提交状态,包括同步到CC Pending Layer Tree,以及CC Pending Layer Tree激活为CC Active Layer Tree的过程记录于begin_main_frame_state_,只有CC Layer Tree的提交状态处于COMMIT_STATE_IDLE时,Main线程才可以绘制网页的下一帧
4. ForcedRedrawOnTimeoutState描述网页的渲染状态,记录于forced_redraw_state_
调度器通过Scheduler类实现,调度器的执行过程就表现为Scheduler类的成员函数ProcessScheduledActions不断地被调用,如下所示:
void Scheduler::ProcessScheduledActions() {
// Do not perform actions during compositor shutdown.
if (stopped_)
return;
// We do not allow ProcessScheduledActions to be recursive.
// The top-level call will iteratively execute the next action for us anyway.
if (inside_process_scheduled_actions_ || inside_scheduled_action_)
return;
base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true);
SchedulerStateMachine::Action action;
do {
action = state_machine_.NextAction();
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
"SchedulerStateMachine", "state", AsValue());
base::AutoReset<SchedulerStateMachine::Action> mark_inside_action(
&inside_action_, action);
switch (action) {
case SchedulerStateMachine::Action::NONE:
break;
case SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME:
compositor_timing_history_->WillBeginMainFrame(
begin_main_frame_args_.on_critical_path,
begin_main_frame_args_.frame_time);
state_machine_.WillSendBeginMainFrame();
// TODO(brianderson): Pass begin_main_frame_args_ directly to client.
client_->ScheduledActionSendBeginMainFrame(begin_main_frame_args_);
break;
case SchedulerStateMachine::Action::NOTIFY_BEGIN_MAIN_FRAME_NOT_SENT:
state_machine_.WillNotifyBeginMainFrameNotSent();
// If SendBeginMainFrameNotExpectedSoon was not previously sent by
// BeginImplFrameNotExpectedSoon (because the messages were not required
// at that time), then send it now.
if (!observing_begin_frame_source_) {
client_->SendBeginMainFrameNotExpectedSoon();
} else {
BeginMainFrameNotExpectedUntil(begin_main_frame_args_.frame_time +
begin_main_frame_args_.interval);
}
break;
case SchedulerStateMachine::Action::COMMIT: {
bool commit_has_no_updates = false;
state_machine_.WillCommit(commit_has_no_updates);
compositor_timing_history_->WillCommit();
client_->ScheduledActionCommit();
break;
}
case SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE:
compositor_timing_history_->WillActivate();
state_machine_.WillActivate();
client_->ScheduledActionActivateSyncTree();
compositor_timing_history_->DidActivate();
break;
case SchedulerStateMachine::Action::PERFORM_IMPL_SIDE_INVALIDATION:
state_machine_.WillPerformImplSideInvalidation();
compositor_timing_history_->WillInvalidateOnImplSide();
client_->ScheduledActionPerformImplSideInvalidation();
break;
case SchedulerStateMachine::Action::DRAW_IF_POSSIBLE:
DrawIfPossible();
break;
case SchedulerStateMachine::Action::DRAW_FORCED:
DrawForced();
break;
case SchedulerStateMachine::Action::DRAW_ABORT: {
// No action is actually performed, but this allows the state machine to
// drain the pipeline without actually drawing.
state_machine_.AbortDraw();
compositor_timing_history_->DrawAborted();
break;
}
case SchedulerStateMachine::Action::BEGIN_LAYER_TREE_FRAME_SINK_CREATION:
state_machine_.WillBeginLayerTreeFrameSinkCreation();
client_->ScheduledActionBeginLayerTreeFrameSinkCreation();
break;
case SchedulerStateMachine::Action::PREPARE_TILES:
state_machine_.WillPrepareTiles();
client_->ScheduledActionPrepareTiles();
break;
case SchedulerStateMachine::Action::INVALIDATE_LAYER_TREE_FRAME_SINK: {
state_machine_.WillInvalidateLayerTreeFrameSink();
client_->ScheduledActionInvalidateLayerTreeFrameSink(
state_machine_.RedrawPending());
break;
}
}
} while (action != SchedulerStateMachine::Action::NONE);
ScheduleBeginImplFrameDeadline();
PostPendingBeginFrameTask();
StartOrStopBeginFrames();
}
Scheduler创建的调用栈:
ProxyImpl::ProxyImpl(base::WeakPtr<ProxyMain> proxy_main_weak_ptr,
LayerTreeHost* layer_tree_host,
TaskRunnerProvider* task_runner_provider)
: layer_tree_host_id_(layer_tree_host->GetId()),
...,
proxy_main_weak_ptr_(proxy_main_weak_ptr) {
...
host_impl_ = layer_tree_host->CreateLayerTreeHostImpl(this);
const LayerTreeSettings& settings = layer_tree_host->GetSettings();
SchedulerSettings scheduler_settings(settings.ToSchedulerSettings());
std::unique_ptr<CompositorTimingHistory> compositor_timing_history(
new CompositorTimingHistory(
scheduler_settings.using_synchronous_renderer_compositor,
CompositorTimingHistory::RENDERER_UMA,
rendering_stats_instrumentation_));
scheduler_.reset(new Scheduler(this, scheduler_settings, layer_tree_host_id_,
task_runner_provider_->ImplThreadTaskRunner(),
std::move(compositor_timing_history)));
DCHECK_EQ(scheduler_->visible(), host_impl_->visible());
}
由ProxyMain创建,其在创建CClayer的管理者LayerTreeHost时候通过LayerTreeHost::InitializeThreaded创建