Chromium网页Layer Tree同步为Pending Layer Tree的过程分析.docx
- 文档编号:5427730
- 上传时间:2022-12-16
- 格式:DOCX
- 页数:73
- 大小:234.19KB
Chromium网页Layer Tree同步为Pending Layer Tree的过程分析.docx
《Chromium网页Layer Tree同步为Pending Layer Tree的过程分析.docx》由会员分享,可在线阅读,更多相关《Chromium网页Layer Tree同步为Pending Layer Tree的过程分析.docx(73页珍藏版)》请在冰豆网上搜索。
Chromium网页LayerTree同步为PendingLayerTree的过程分析
Chromium网页LayerTree同步为PendingLayerTree的过程分析
CCLayerTree绘制完成后,会同步到一个新的CCPendingLayerTree去。
同步过程由Compositor线程执行,并且Main线程处于等待状态。
所谓同步,就是将CCLayerTree的内容拷贝到CCPendingLayerTree去。
同步完毕,Main线程就会被唤醒。
本文接下来分析CCLayerTree同步为CCPendingLayerTree的过程。
CCLayerTree同步为CCPendingLayerTree的操作是由调度器发起的,它对应于网页渲染过程中的第3个步骤ACTION_COMMIT,如下所示:
从前面一文可以知道,当调度器调用SchedulerStateMachine类的成员函数NextAction询问状态机下一步要执行的操作时,SchedulerStateMachine类的成员函数NextAction会调用另外一个成员函数ShouldCommit。
当SchedulerStateMachine类的成员函数ShouldCommit返回值等于true的时候,状态机就会提示调度器接下来需要执行ACTION_COMMIT操作,也就是将CCLayerTree同步为CCPendingLayerTree,如下所示:
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
SchedulerStateMachine:
:
ActionSchedulerStateMachine:
:
NextAction()const{
......
if(ShouldCommit())
returnACTION_COMMIT;
......
returnACTION_NONE;
}
这个函数定义在文件external/chromium_org/cc/scheduler/scheduler_state_machine.cc中。
接下来我们就继续分析SchedulerStateMachine类的成员函数ShouldCommit什么情况下会返回true,它的实现如下所示:
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
boolSchedulerStateMachine:
:
ShouldCommit()const{
if(commit_state_!
=COMMIT_STATE_READY_TO_COMMIT)
returnfalse;
//Wemustnotfinishthecommituntilthependingtreeisfree.
if(has_pending_tree_){
DCHECK(settings_.main_frame_before_activation_enabled);
returnfalse;
}
//Prioritizedrawingthepreviouscommitbeforefinishingthenextcommit.
if(active_tree_needs_first_draw_)
returnfalse;
returntrue;
}
这个函数定义在文件external/chromium_org/cc/scheduler/scheduler_state_machine.cc中。
SchedulerStateMachine类的成员函数ShouldCommit返回true需要满足三个条件:
1.状态机的CommitState状态等于COMMIT_STATE_READY_TO_COMMIT。
从前面一文可以知道,当CCLayerTree绘制完成时,会将状态机的CommitState状态设置为COMMIT_STATE_READY_TO_COMMIT。
2.成员变量has_pending_tree_的值等于false。
当这个成员变量的值等于true的时候,表示现在有一个CCPendingLayerTree正在执行光栅化操作。
要等到这个CCPendingLayerTree的光栅化操作完成,并且激活为CCActiveLayerTree之后,才可以执行下一个ACTION_COMMIT操作。
这是因为执行ACTION_COMMIT操作的时候又会产生一个新的CCPendingLayerTree。
同一时刻只能存在一个CCPendingLayerTree。
3.成员变量active_tree_needs_first_draw_的值等于false。
当这个成员变量的值等于true的时候,表示现在有一个CCActiveLayerTree刚刚被激活,但是这个刚刚被激活的CCActiveLayerTree还没有被执行过渲染操作。
渲染操作的优先级大于ACTION_COMMIT操作。
因此,在这种情况下,就不允许执行ACTION_COMMIT操作。
回到SchedulerStateMachine类的成员函数NextAction中,当它调用成员函数ShouldCommit得到的返回值等于true,它就会返回一个ACTION_COMMIT给Scheduler类的成员函数ProcessScheduledActions。
这时候Scheduler类的成员函数ProcessScheduledActions就会请求Compositor线程将刚刚绘制完成的CCLayerTree同步为CCPendingLayerTree,如下所示:
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
voidScheduler:
:
ProcessScheduledActions(){
......
SchedulerStateMachine:
:
Actionaction;
do{
action=state_machine_.NextAction();
......
state_machine_.UpdateState(action);
......
switch(action){
......
caseSchedulerStateMachine:
:
ACTION_COMMIT:
client_->ScheduledActionCommit();
break;
......
}
}while(action!
=SchedulerStateMachine:
:
ACTION_NONE);
SetupNextBeginFrameIfNeeded();
......
if(state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()){
......
ScheduleBeginImplFrameDeadline(base:
:
TimeTicks());
}
}
这个函数定义在文件external/chromium_org/cc/scheduler/scheduler.cc中。
Scheduler类的成员函数ProcessScheduledActions的详细分析可以参考前面一文。
这时候Scheduler类的成员函数ProcessScheduledActions首先调用SchedulerStateMachine类的成员函数UpdateState更新状态机的状态,接着再调用成员变量client_指向的一个ThreadProxy对象的成员函数ScheduledActionCommit请求Compositor线程将刚刚绘制好的CCLayerTree同步为CCPendingLayerTree。
SchedulerStateMachine类的成员函数UpdateState的实现如下所示:
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
voidSchedulerStateMachine:
:
UpdateState(Actionaction){
switch(action){
......
caseACTION_COMMIT:
{
boolcommit_was_aborted=false;
UpdateStateOnCommit(commit_was_aborted);
return;
}
......
}
}
这个函数定义在文件external/chromium_org/cc/scheduler/scheduler_state_machine.cc中。
SchedulerStateMachine类的成员函数UpdateState调用另外一个成员函数UpdateStateOnCommit修改状态机的CommitState状态。
SchedulerStateMachine类的成员函数UpdateStateOnCommit的详细分析可以参考前面一文,我们假设它将状态机的CommitState状态从COMMIT_STATE_READY_TO_COMMIT修改为COMMIT_STATE_WAITING_FOR_ACTIVATION,表示调度器正在等待一个新的CCPendingLayerTree被激活为CCActiveLayerTree。
回到Scheduler类的成员函数ProcessScheduledActions中,它修改了状态机的CommitState状态之后,接下来调用ThreadProxy类的成员函数ScheduledActionCommit请求Compositor线程将刚刚绘制好的CCLayerTree同步为CCPendingLayerTree,如下所示:
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
voidThreadProxy:
:
ScheduledActionCommit(){
......
impl().layer_tree_host_impl->BeginCommit();
......
layer_tree_host()->FinishCommitOnImplThread(
impl().layer_tree_host_impl.get());
......
boolhold_commit=layer_tree_host()->settings().impl_side_painting&&
blocked_main().commit_waits_for_activation;
......
if(hold_commit){
......
impl().completion_event_for_commit_held_on_tree_activation=
impl().commit_completion_event;
impl().commit_completion_event=NULL;
}else{
impl().commit_completion_event->Signal();
impl().commit_completion_event=NULL;
}
......
impl().layer_tree_host_impl->CommitComplete();
......
}
这个函数定义在文件external/chromium_org/cc/trees/thread_proxy.cc中。
调用ThreadProxy类的成员函数impl可以获得一个CompositorThreadOnly对象。
这个CompositorThreadOnly对象的成员变量layer_tree_host_impl指向一个LayerTreeHostImpl对象。
这个LayerTreeHostImpl对象负责管理CCPendingLayerTree和CCActiveLayerTree。
ThreadProxy类的成员函数ScheduledActionCommit首先调用这个LayerTreeHostImpl对象的成员函数BeginCommit创建一个空的CCPendingLayerTree。
ThreadProxy类的成员函数ScheduledActionCommit接下来又调用成员函数layer_tree_host获得一个LayerTreeHost对象。
这个LayerTreeHost对象负责管理CCLayerTree。
有了这个LayerTreeHost对象之后,就可以调用它的成员函数FinishCommitOnImplThread将刚刚绘制好的CCLayerTree同步到前面创建的CCPendingLayerTree中去。
调用ThreadProxy类的成员函数blocked_main可以获得一个MainThreadOrBlockedMainThread对象。
在Render进程启用了ImplSidePainting特性的情况下,当这个MainThreadOrBlockedMainThread对象的成员变量commit_waits_for_activation等于true时,表示CCLayerTree中的某些Layer请求Compositor线程一直阻塞Main线程,直到前面创建的CCPendingLayerTree完成光栅化并且激活为CCActiveLayerTree之后,再唤醒Main线程。
这些Layer有一个特点,就是不需要Compositor线程为它们执行光栅化操作,例如TextureLayer,本身的内容就是已经光栅化好了的。
如果需要阻塞Main线程到CCPendingLayerTree激活为CCActiveLayerTree之后,那么ThreadProxy类的成员函数ScheduledActionCommit就会将保存在前面获得的CompositorThreadOnly对象的成员变量commit_completion_event中的CompletionEvent转移到另外一个成员变量completion_event_for_commit_held_on_tree_activation中,以便在CCPendingLayerTree激活为CCAcitveLayerTree的时候,通过保存在后面这个成员变量中的CompletionEvent来唤醒Main线程。
另一方面,如果不需要阻塞Main线程到CCPendingLayerTree激活为CCActiveLayerTree之后,那么现在就可以唤醒Main线程了,也就是调用保存在前面获得的CompositorThreadOnly对象的成员变量commit_completion_event中的CompletionEvent的成员函数Signal。
最后,ThreadProxy类的成员函数ScheduledActionCommit又调用前面获得的CompositorThreadOnly对象的成员变量layer_tree_host_impl指向的LayerTreeHostImpl对象的成员函数CommitComplete为前面已经同步好的CCPendingLayerTree中的Layer创建分块,以便后面可以对这些分块执行光栅化操作。
接下来,我们就先分析LayerTreeHostImpl类的成员函数BeginCommit的实现,然后再分析LayerTreeHost类的成员函数FinishCommitOnImplThread以及LayerTreeHostImpl类的成员函数CommitComplete的实现,以便了解CCLayerTree同步为CCPendingLayerTree的过程,以及为CCPendingLayerTree创建分块的过程。
LayerTreeHostImpl类的成员函数BeginCommit的实现如下所示:
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
voidLayerTreeHostImpl:
:
BeginCommit(){
......
if(settings_.impl_side_painting)
CreatePendingTree();
}
这个函数定义在文件external/chromium_org/cc/trees/layer_tree_host_impl.cc中。
只有在Render进程启用ImplSidePainting特性情况下,才会存在CCPendingLayerTree。
因此,只有在Render进程启用ImplSidePainting特性情况下,LayerTreeHostImpl类的成员函数BeginCommit才会调用另外一个成员函数CreatePendingTree创建一个新的CCPendingLayerTree,如下所示:
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
voidLayerTreeHostImpl:
:
CreatePendingTree(){
CHECK(!
pending_tree_);
if(recycle_tree_)
recycle_tree_.swap(pending_tree_);
else
pending_tree_=LayerTreeImpl:
:
create(this);
......
}
这个函数定义在文件external/chromium_org/cc/trees/layer_tree_host_impl.cc中。
LayerTreeHostImpl类的成员变量pending_tree_描述的是上一次创建的CCPendingLayerTree。
这个CCPendingLayerTree正在执行光栅化操作。
一旦这个光栅化操作执行完成,LayerTreeHostImpl类的成员变量pending_tree_的值就会被设置为NULL,同时它原先指向的一个LayerTreeImpl对象会被缓存在另外一个成员变量recycle_tree_。
等到下次需要再创建新的CCPendingLayerTree时,LayerTreeHostImpl类的成员函数CreatePendingTree就会先检查成员变量recycle_tree_的值是否为NULL。
如果不为NULL,就会复用它所指向的一个LayerTreeImpl对象,用作新的CCPendingLayerTree。
否则的话,就会调用LayerTreeImpl类的静态成员函数create创建一个新的CCPendingLayerTree。
无论如何,最终得到的CCPendingLayerTree都保存在成员变量pending_tree_中。
LayerTreeImpl类的静态成员函数create的实现如下所示:
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
classCC_EXPORTLayerTreeImpl{
public:
staticscoped_ptr
LayerTreeHostImpl*layer_tree_host_impl){
returnmake_scoped_ptr(newLayerTreeImpl(layer_tree_host_impl));
}
......
};
这个函数定义在文件external/chromium_org/cc/trees/layer_tree_impl.h中。
从这里可以看到,LayerTreeImpl类的静态成员函数create创建的是一个LayerTreeImpl对象。
这个LayerTreeImpl对象的创建过程,也就是LayerTreeImpl类的构造函数的实现如下所示:
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
LayerTreeImpl:
:
LayerTreeImpl(LayerTreeHostImpl*layer_tree_host_impl)
:
layer_tree_host_impl_(layer_tree_host_impl),
......{
}
这个函数定义在文件external/chromium_org/cc/trees/layer_tree_impl.cc中。
LayerTreeImpl类的构造函数主要是将参数layer_tree_host_impl指向的一个LayerTreeHostImpl对象保存在成员变量layer_tree_host_impl_中。
回到前面分析的ThreadProxy类的成员函数ScheduledActionCommit中,它调用LayerTreeHostImpl类的成员函数BeginCommit创建了一个新的CCPendingLayerTree之后,接下来就调用LayerTreeHost类的成员函数FinishCommitOnImplThread将之前绘制好的CCLayerTree同步到刚才创建出来的CCPendingLayerTree去,如下所示:
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
voidLayerTreeHost:
:
FinishCommitOnImplThread(LayerTreeHostImpl*host_impl){
......
LayerTreeImpl*sync_tree=host_impl->sync_tree();
......
if(needs_full_tree_sync_)
sync_tree->SetRootLayer(TreeSynchronizer:
:
SynchronizeTrees(
root_layer(),sync_tree->DetachLayerTree(),sync_tree));
{
......
TreeSynchronizer:
:
PushProperties(root_layer(),sync_tree->root_layer());
}
sync_tree->set_needs_full_tree_sync(needs_full_tree_sync_);
needs_full_tree_sync_=false;
......
}
这个函数定义在文件external/chromium_org/cc/trees/layer_tree_host.cc中。
LayerTr
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Chromium网页Layer Tree同步为Pending Layer Tree的过程分析 Chromium 网页 Tree 同步 Pending 过程 分析
链接地址:https://www.bdocx.com/doc/5427730.html