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

2019-01-27 12:51

Chromium网页渲染调度器(Scheduler)

实现分析

在采用线程化渲染方式渲染网页时,Chromium依赖一个调度器协调Main线程和Compositor线程的执行,同时也通过这个调度器决定它们什么时候该执行什么操作。调度器将Main线程和Compositor线程的当前状态记录在一个状态机中,然后通过这个状态机决定下一个要执行的操作。这个操作在满足当前设置条件下是最优的,因此可以使网页渲染更快更流畅。本文接下来就分析Chromium网页调度器的实现。

调度器实现在Chromium的CC模块中,并且运行在Compositor线程中。Compositor线程的职责是将网页的内容渲染出来。从这个角度看,调度器只不过是在调度Compositor线程的执行。不过由于要渲染的网页内容是由Main线程提供给Compositor线程的,因此调度器也会在必要的时候调度Main线程执行,使得它可以提供最新的网页内容给Compositor线程渲染。

网页是一帧一帧地渲染出来的。从前面这个系列的文章我们学习到,Android应用程序UI的每一帧的最佳渲染时机是下一个屏幕VSync信号到来时。Chromium也不例外,它在渲染网页的时候,也是利用了屏幕的VSync信号。这一点在调度器的时间轴中可以得到体现,如图1所示:

从图1可以看到,调度器并没有严格在VSync到来时就去渲染网页的下一帧,而是为网页的下一帧渲染时机设置了一个Deadline。在Deadline到来前,调度器可以调度执行其它的渲染操作。

在继续分析上述的Deadline机制之前,我们要先搞清楚网页的一帧渲染涉及到哪些操作。这些操作如图2所示:

图2的完整分析可以参考前面一文。我们前面说的Deadline,是针对第6个操作ACTION_DRAW_AND_SWAP_FORCED而言的。也就是说,当VSync信号到来时,ACTION_DRAW_AND_SWAP_FORCED操作最迟必须在设置的Deadline到来时执行。

这个Deadline是怎么计算出来的呢?我们先来看网页的渲染过程。首先是Render进程进行渲染,然后交给Browser进程进行合成。因此,网页的渲染过程可以看作由两部分时间组成:estimated_draw_duration + estimated_browser_composite_time。其中,estimated_draw_duration表示Render进程的渲染时间,estimated_browser_composite_time表示Browser进程的合成时间。

假设下一个VSync到来的时间为frame_time,VSync信号时间周期为interval,那么就可以计算出Deadline = frame_time + (interval - estimated_draw_duration - estimated_browser_composite_time)。剩下来的时间区间[frame_time, deadline)可以用做其它事情,例如执行图2所示的第2个操作ACTION_SEND_BEGIN_MAIN_FRAME,也就是通知Main线程对CC Layer Tree进行绘制。

时间区间[frame_time, deadline)称为BEGIN_IMPL_FRAME时间。在BEGIN_IMPL_FRAME时间内,存在四个BeginImplFrameState状态,如下所示:

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 class CC_EXPORT SchedulerStateMachine { public: ......

// Note: BeginImplFrameState will always cycle through all the states in // order. Whether or not it actually waits or draws, it will at least try to

// wait in BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME and try to draw in // BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE enum BeginImplFrameState {

BEGIN_IMPL_FRAME_STATE_IDLE,

BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING, BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME, BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, };

......

protected: ......

BeginImplFrameState begin_impl_frame_state_; ...... };

这个状态定义在文件external/chromium_org/cc/scheduler/scheduler_state_machine.h中。

调度器通过类SchedulerStateMachine描述内部的状态机。状态机的BeginImplFrameState状态记录在SchedulerStateMachine类的成员变量begin_impl_frame_state_中。

四个BeginImplFrameState状态分别为:

1. BEGIN_IMPL_FRAME_STATE_IDLE

2. BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING

3. BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME

4. BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE

它们的变迁关系如图3所示:

下一个VSync信号到来之前,状态机处于BEGIN_IMPL_FRAME_STATE_IDLE状态。

下一个VSync信号到来之时,调度器调用SchedulerStateMachine类的成员函数OnBeginImplFrame将状态机的BeginImplFrameState状态设置为BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING。这时候调度器通过调用Scheduler类的成员函数ProcessScheduledActions调度计算网页中的动画,或者执行图2所示的第2个操作ACTION_SEND_BEGIN_MAIN_FRAME,也就是通知Main线程对网页内容进行绘制。

从Scheduler类的成员函数ProcessScheduledActions返回后,BeginImplFrameState状态就从BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING变为BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME。这时候调度器等待Deadline的到来。

Deadline到来之时,调度器调用SchedulerStateMachine类的成员函数OnBeginImplFrameDeadline将BeginImplFrameState状态从BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME设置为BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE。这时候调度器就会通过调用Scheduler类的成员函数ProcessScheduledActions调度执行网页的渲染操作,也就是图2所示的第6个操作ACTION_DRAW_AND_SWAP_FORCED。

从Scheduler类的成员函数ProcessScheduledActions返回后,BeginImplFrameState状态就从BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE重新变为BEGIN_IMPL_FRAME_STATE_IDLE。这时候调度器等待再下一个VSync信号的到来。

状态机除了有BeginImplFrameState状态,还有其它三个状态,分别是OutputSurfaceState、CommitState和ForcedRedrawOnTimeoutState。

OutputSurfaceState描述的是网页绘图表面的状态,如下所示:

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 class CC_EXPORT SchedulerStateMachine { public:

......

enum OutputSurfaceState {

OUTPUT_SURFACE_ACTIVE, OUTPUT_SURFACE_LOST,

OUTPUT_SURFACE_CREATING,

OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT, OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION, };

......

protected: ......

OutputSurfaceState output_surface_state_; ...... };

这个状态定义在文件external/chromium_org/cc/scheduler/scheduler_state_machine.h中。 网页绘图表面的状态记录在SchedulerStateMachine类的成员变量output_surface_state_中。网页绘图表面的状态有五个状态,分别是:

1. OUTPUT_SURFACE_LOST

2. OUTPUT_SURFACE_CREATING

3. OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT

4. OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION

5. OUTPUT_SURFACE_ACTIVE

它们的变迁关系如图4所示:


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

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

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

马上注册会员

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