Chromium网页渲染调度器(Scheduler)实现分析(3)

2019-01-27 12:51

一次图2所示的第3个操作ACTION_COMMIT,以便补充缺失的分块。

ACTION_COMMIT操作执行完成之后,如果Main线程在绘制网页时,仅仅记录了CC Layer Tree的绘制命令,也就是前面提到的impl_side_painting等于true,那么就意味着存在一个CC Pending Layer Tree,这时候网页渲染状态会被设置为FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION,表示等待CC Pending Layer Tree被激活为CC Active Layer Tree。

另一方面,ACTION_COMMIT操作执行完成之后,如果Main线程在绘制网页时,直接进行光栅化,也就是前面提到的impl_side_painting等于false,那么就意味着不会存在一个CC Pending Layer Tree,这时候网页渲染状态会被设置为FORCED_REDRAW_STATE_WAITING_FOR_DRAW,表示等待CC Active Layer Tree被渲染。

如果网页渲染状态被设置为FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION,那么当图2所示的第5个操作ACTION_ACTIVATE_PENDING_TREE执行完成之后。也就是CC Pending Layer Tree被激活为CC Active Layer Tree之后,网页渲染状态会被设置为FORCED_REDRAW_STATE_WAITING_FOR_DRAW,表示等待CC Active Layer Tree被渲染。

当CC Active Layer Tree被渲染之后,网页渲染状态就会从FORCED_REDRAW_STATE_WAITING_FOR_DRAW变为FORCED_REDRAW_STATE_IDLE状态。

理解了网页的BeginImplFrameState、OutputSurfaceState、CommitState和ForcedRedrawOnTimeoutState状态之后,接下来我们就可以分析调度器的实现了,也就是调度器的执行过程。

调度器通过Scheduler类实现,调度器的执行过程就表现为Scheduler类的成员函数ProcessScheduledActions不断地被调用,如下所示:

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 void Scheduler::ProcessScheduledActions() { ......

SchedulerStateMachine::Action action; do {

action = state_machine_.NextAction(); ......

state_machine_.UpdateState(action);

base::AutoReset mark_inside_action(&inside_action_, action); switch (action) {

case SchedulerStateMachine::ACTION_NONE: break;

case SchedulerStateMachine::ACTION_ANIMATE: client_->ScheduledActionAnimate(); break;

case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME: client_->ScheduledActionSendBeginMainFrame(); break;

case SchedulerStateMachine::ACTION_COMMIT: client_->ScheduledActionCommit(); break;

case SchedulerStateMachine::ACTION_UPDATE_VISIBLE_TILES: client_->ScheduledActionUpdateVisibleTiles(); break;

case SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE: client_->ScheduledActionActivatePendingTree(); break;

case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE: DrawAndSwapIfPossible(); break;

case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED: client_->ScheduledActionDrawAndSwapForced(); break;

case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: // No action is actually performed, but this allows the state machine to // advance out of its waiting to draw state without actually drawing. break;

case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: client_->ScheduledActionBeginOutputSurfaceCreation(); break;

case SchedulerStateMachine::ACTION_MANAGE_TILES: client_->ScheduledActionManageTiles(); break; }

} while (action != SchedulerStateMachine::ACTION_NONE);

SetupNextBeginFrameIfNeeded(); ......

if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) { ......

ScheduleBeginImplFrameDeadline(base::TimeTicks()); } }

这个函数定义在文件external/chromium_org/cc/scheduler/scheduler.cc中。

Scheduler类的成员函数ProcessScheduledActions在一个while循环中不断地调用成员变量state_machine_指向的SchedulerStateMachine对象的成员函数NextAction询问状态机下一个要执行的操作,直到状态机告知当前没有操作要执行为止。这些操作大概就对应于图2所示的操作。

每一个操作都是通过调用成员变量client_指向的ThreadProxy对象对应的成员函数执行的。例如,ACTION_SEND_BEGIN_MAIN_FRAME操作是通过调用成员变量client_指向的ThreadProxy对象的成员函数ScheduledActionSendBeginMainFrame执行的。ThreadProxy类的这些函数我们在后面的文章中再详细分析。每一个操作在执行之前,Scheduler类的成员函数ProcessScheduledActions会先调用state_machine_指向的SchedulerStateMachine对象的成员函数UpdateState更新状态机的状态。

跳出while循环之后,Scheduler类的成员函数ProcessScheduledActions调用另外一个成员函数SetupNextBeginFrameIfNeeded根据状态机的当前状态决定是否要发起下一个BEGIN_IMPL_FRAME操作。如果需要的话,就会在下一个VSync信号到来时,通过调用Scheduler类的成员函数ProcessScheduledActions渲染网页的下一帧。

Scheduler类的成员函数ProcessScheduledActions最后还会调用成员变量state_machine_指向的SchedulerStateMachine对象的成员函数ShouldTriggerBeginImplFrameDeadlineEarly检查是否提前执行渲染网页的操作。如果需要提前的话,那么就不会等待上一个VSync信号到来时设置的Deadline到期,而是马上调用成员函数ScheduleBeginImplFrameDeadline假设该Deadline已经到期,于是就可以马上渲染网页。

为了更好地理解调度器的执行过程,接下来我们继续前面提到的SchedulerStateMachine类的成员函数NextAction、UpdateState和ShouldTriggerBeginImplFrameDeadlineEarly以及Scheduler类的成员函数SetupNextBeginFrameIfNeeded和ScheduleBeginImplFrameDeadline的实现。

SchedulerStateMachine类的成员函数NextAction的实现如下所示:

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片

SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { if (ShouldUpdateVisibleTiles())

return ACTION_UPDATE_VISIBLE_TILES; if (ShouldActivatePendingTree())

return ACTION_ACTIVATE_PENDING_TREE; if (ShouldCommit())

return ACTION_COMMIT; if (ShouldAnimate())

return ACTION_ANIMATE; if (ShouldDraw()) {

if (PendingDrawsShouldBeAborted())

return ACTION_DRAW_AND_SWAP_ABORT;

else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) return ACTION_DRAW_AND_SWAP_FORCED; else

return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; }

if (ShouldManageTiles())

return ACTION_MANAGE_TILES; if (ShouldSendBeginMainFrame())

return ACTION_SEND_BEGIN_MAIN_FRAME; if (ShouldBeginOutputSurfaceCreation())

return ACTION_BEGIN_OUTPUT_SURFACE_CREATION; return ACTION_NONE; }

这个函数定义在文件external/chromium_org/cc/scheduler/scheduler_state_machine.cc中。

SchedulerStateMachine类的成员函数NextAction通过调用一系列的成员函数ShouldXXX决定当前需要执行的操作。例如,如果调用成员函数ShouldCommit得到的返回值为true,那么就SchedulerStateMachine类的成员函数NextAction就会返回一个ACTION_COMMIT值表示要执行一个ACTION_COMMIT操作。这些ShouldXXX成员函数我们在后面的文章中再详细分析。

SchedulerStateMachine类的成员函数UpdateState的实现如下所示:

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 void SchedulerStateMachine::UpdateState(Action action) { switch (action) {

case ACTION_NONE: return;

case ACTION_UPDATE_VISIBLE_TILES:

last_frame_number_update_visible_tiles_was_called_ = current_frame_number_; return;

case ACTION_ACTIVATE_PENDING_TREE: UpdateStateOnActivation(); return;

case ACTION_ANIMATE:

last_frame_number_animate_performed_ = current_frame_number_; needs_animate_ = false;

// TODO(skyostil): Instead of assuming this, require the client to tell // us.

SetNeedsRedraw(); return;

case ACTION_SEND_BEGIN_MAIN_FRAME: DCHECK(!has_pending_tree_ ||

settings_.main_frame_before_activation_enabled); DCHECK(!active_tree_needs_first_draw_ ||

settings_.main_frame_before_draw_enabled); DCHECK(visible_);

commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; needs_commit_ = false;

last_frame_number_begin_main_frame_sent_ = current_frame_number_; return;

case ACTION_COMMIT: {

bool commit_was_aborted = false;

UpdateStateOnCommit(commit_was_aborted); return; }

case ACTION_DRAW_AND_SWAP_FORCED:

case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: { bool did_request_swap = true;

UpdateStateOnDraw(did_request_swap); return; }

case ACTION_DRAW_AND_SWAP_ABORT: { bool did_request_swap = false;

UpdateStateOnDraw(did_request_swap); return; }

case ACTION_BEGIN_OUTPUT_SURFACE_CREATION:

DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_LOST); output_surface_state_ = OUTPUT_SURFACE_CREATING;

// The following DCHECKs make sure we are in the proper quiescent state. // The pipeline should be flushed entirely before we start output // surface creation to avoid complicated corner cases.

DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE); DCHECK(!has_pending_tree_);

DCHECK(!active_tree_needs_first_draw_);


Chromium网页渲染调度器(Scheduler)实现分析(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:建筑工程成本管理办法(重点) - 图文

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: