Chromium网页Layer Tree创建过程分析.docx

上传人:b****8 文档编号:23812383 上传时间:2023-05-21 格式:DOCX 页数:58 大小:93.32KB
下载 相关 举报
Chromium网页Layer Tree创建过程分析.docx_第1页
第1页 / 共58页
Chromium网页Layer Tree创建过程分析.docx_第2页
第2页 / 共58页
Chromium网页Layer Tree创建过程分析.docx_第3页
第3页 / 共58页
Chromium网页Layer Tree创建过程分析.docx_第4页
第4页 / 共58页
Chromium网页Layer Tree创建过程分析.docx_第5页
第5页 / 共58页
点击查看更多>>
下载资源
资源描述

Chromium网页Layer Tree创建过程分析.docx

《Chromium网页Layer Tree创建过程分析.docx》由会员分享,可在线阅读,更多相关《Chromium网页Layer Tree创建过程分析.docx(58页珍藏版)》请在冰豆网上搜索。

Chromium网页Layer Tree创建过程分析.docx

Chromium网页LayerTree创建过程分析

Chromium网页LayerTree创建过程分析

在Chromium中,WebKit会创建一个GraphicsLayerTree描述网页。

GraphicsLayerTree是和网页渲染相关的一个Tree。

网页渲染最终由Chromium的CC模块完成,因此CC模块又会根据GraphicsLayerTree创建一个LayerTree,以后就会根据这个LayerTree对网页进行渲染。

本文接下来就分析网页LayerTree的创建过程。

从前面一文可以知道,网页的GraphicsLayerTree是根据RenderLayerTree创建的,RenderLayerTree又是根据RenderObjectTree创建的。

GraphicsLayerTree与RenderLayerTree、RenderLayerTree与RenderObjectTree的节点是均是一对多的关系,然而GraphicsLayerTree与CC模块创建的LayerTree的节点是一一对应的关系,如图1所示:

也就是说,每一个GraphicsLayer都对应有一个CCLayer。

不过,GraphicsLayer与CCLayer不是直接的一一对应的,它们是透过另外两个Layer才对应起来的,如图2所示:

中间的两个Layer分别是WebContentLayerImpl和WebLayerImpl,它们是属于Content层的对象。

关于Chromium的层次划分,可以参考前面一文的介绍。

GraphicsLayer与CCLayer的对应关系,是在GraphicsLayer的创建过程中建立起来的,接下来我们就通过源码分析这种对应关系的建立过程。

从前面一文可以知道,GraphicsLayer是通过调用GraphicsLayerFactoryChromium类的成员函数createGraphicsLayer创建的,如下所示:

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

PassOwnPtrGraphicsLayerFactoryChromium:

:

createGraphicsLayer(GraphicsLayerClient*client)

{

OwnPtrlayer=adoptPtr(newGraphicsLayer(client));

......

returnlayer.release();

}

这个函数定义在文件external/chromium_org/third_party/WebKit/Source/web/GraphicsLayerFactoryChromium.cpp中。

参数client指向的实际上是一个CompositedLayerMapping对象,这个CompositedLayerMapping对象会用来构造一个GraphicsLayer。

GraphicsLayer的构造过程,也就是GraphicsLayer类的构造函数的实现,如下所示:

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

GraphicsLayer:

:

GraphicsLayer(GraphicsLayerClient*client)

:

m_client(client)

......

{

......

m_opaqueRectTrackingContentLayerDelegate=adoptPtr(newOpaqueRectTrackingContentLayerDelegate(this));

m_layer=adoptPtr(Platform:

:

current()->compositorSupport()->createContentLayer(m_opaqueRectTrackingContentLayerDelegate.get()));

......

}

这个函数定义在文件external/chromium_org/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp中。

GraphicsLayer类的构造函数首先是将参数client指向的CompositedLayerMapping对象保存在成员变量m_client中,接着又创建了一个OpaqueRectTrackingContentLayerDelegate对象保存在成员变量opaqueRectTrackingContentLayerDelegate中。

再接下来GraphicsLayer类的构造函数通过Platform类的静态成员函数current获得一个RendererWebKitPlatformSupportImpl对象。

这个RendererWebKitPlatformSupportImpl对象定义在Content模块中,它实现了由WebKit定义的Platform接口,用来向WebKit层提供平台相关的实现。

通过调用RendererWebKitPlatformSupportImpl类的成员函数compositorSupport可以获得一个WebCompositorSupportImpl对象。

有了这个WebCompositorSupportImpl对象之后,就可以调用它的成员函数createContentLayer创建一个WebContentLayerImpl对象,并且保存在GraphicsLayer类的成员变量m_layer中。

WebCompositorSupportImpl类的成员函数createContentLayer的实现如下所示:

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

WebContentLayer*WebCompositorSupportImpl:

:

createContentLayer(

WebContentLayerClient*client){

returnnewWebContentLayerImpl(client);

}

这个函数定义在文件external/chromium_org/content/renderer/compositor_bindings/web_compositor_support_impl.cc中。

从这里可以看到,WebCompositorSupportImpl类的成员函数createContentLayer创建了一个WebContentLayerImpl对象返回给调用者。

WebContentLayerImpl对象的创建过程,即WebContentLayerImpl类的构造函数的实现,如下所示:

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

WebContentLayerImpl:

:

WebContentLayerImpl(blink:

:

WebContentLayerClient*client)

:

client_(client),......{

if(WebLayerImpl:

:

UsingPictureLayer())

layer_=make_scoped_ptr(newWebLayerImpl(PictureLayer:

:

Create(this)));

else

layer_=make_scoped_ptr(newWebLayerImpl(ContentLayer:

:

Create(this)));

......

}

这个函数定义在文件external/chromium_org/content/renderer/compositor_bindings/web_content_layer_impl.cc中。

从前面的调用过程可以知道,参数client指向的实际上是一个OpaqueRectTrackingContentLayerDelegate对象,WebContentLayerImpl类的构造函数首先将它保存在成员变量client_中。

WebContentLayerImpl类的构造函数接下来调用WebLayerImpl类的静态成员函数UsingPictureLayer判断Render进程是否启用ImplSidePainting特性。

如果启用的话,就会调用PictureLayer类的静态成员函数Create创建一个PictureLayer;否则的话,就会调用ContentLayer类的静态成员函数Create创建一个ContentLayer。

有了PictureLayer或者ContentLayer之后,再创建一个WebLayerImpl对象,保存在WebContentLayerImpl类的成员变量layer_中。

当Render进程设置了enable-impl-side-painting启动选项时,就会启用ImplSidePainting特性,也就是会在Render进程中创建一个Compositor线程,与Render进程中的Main线程一起协作完成网页的渲染。

在这种情况下,GraphicsLayer在绘制网页内容的时候,实际上只是记录了绘制命令。

这些绘制命令就记录在对应的PictureLayer中。

另一方面,如果Render进程没有设置enable-impl-side-painting启动选项,那么GraphicsLayer在绘制网页内容的时候,就会通过ContentLayer提供的一个Canvas真正地把网页内容对应的UI绘制在一个内存缓冲区中。

无论是PictureLayer还是ContentLayer,它们都是在cc:

:

Layer类继承下来的,也就是说,它们对应于图2所示的CCLayer。

不过,我们只考虑PictureLayer的情况,因此接下来我们继续分析PictureLayer的创建过程,也就是PictureLayer类的静态成员函数Create的实现,如下所示:

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

scoped_refptrPictureLayer:

:

Create(ContentLayerClient*client){

returnmake_scoped_refptr(newPictureLayer(client));

}

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

从这里可以看到,PictureLayer类的静态成员函数Create创建了一个PictureLayer对象返回给调用者。

PictureLayer对象的创建过程,也就是PictureLayer类的构造函数的实现,如下所示:

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

PictureLayer:

:

PictureLayer(ContentLayerClient*client)

:

client_(client),

pile_(make_scoped_refptr(newPicturePile())),

......{

}

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

从前面的调用过程可以知道,参数client指向的实际上是一个WebContentLayerImpl对象,PictureLayer类的构造函数将它保存在成员变量client_中。

PictureLayer类的构造函数还做了另外一件重要的事情,就是创建了一个PicturePile对象,并且保存在成员变量pile_中。

这个PicturePile对象是用来将GraphicsLayer的绘制命令记录在PictrueLayer中的,后面我们分析网页内容的绘制过程时就会看到这一点。

回到WebContentLayerImpl类的构造函数中,它创建了一个PictrueLayer之后,接下来就会以这个PictrueLayer为参数,创建一个WebLayerImpl对象,如下所示:

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

WebLayerImpl:

:

WebLayerImpl(scoped_refptrlayer):

layer_(layer){

......

}

这个函数定义在文件external/chromium_org/content/renderer/compositor_bindings/web_layer_impl.cc中。

WebLayerImpl类的构造函数主要就是将参数layer描述的一个PictrueLayer对象保存在成员变量layer_中。

从前面一文还可以知道,GraphicsLayer与GraphicsLayer是通过GraphicsLayer类的成员函数addChild形成父子关系的(从而形成GraphicsLayerTree),如下所示:

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

voidGraphicsLayer:

:

addChild(GraphicsLayer*childLayer)

{

addChildInternal(childLayer);

updateChildList();

}

这个函数定义在文件external/chromium_org/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp中。

GraphicsLayer类的成员函数addChild首先调用成员函数addChildInternal将参数childLayer描述的一个GraphicsLayer作为当前正在处理的GraphicsLayer的子GraphicsLayer,如下所示:

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

voidGraphicsLayer:

:

addChildInternal(GraphicsLayer*childLayer)

{

......

childLayer->setParent(this);

m_children.append(childLayer);

......

}

这个函数定义在文件external/chromium_org/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp中。

这一步执行完成后,GraphicsLayer之间就建立了父子关系。

回到GraphicsLayer类的成员函数addChild中,它接下来还会调用另外一个成员函数updateChildList,用来在CCLayer之间建立父子关系,从而形CCLayerTree。

GraphicsLayer类的成员函数updateChildList的实现如下所示:

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

voidGraphicsLayer:

:

updateChildList()

{

WebLayer*childHost=m_layer->layer();

......

for(size_ti=0;i

childHost->addChild(m_children[i]->platformLayer());

......

}

这个函数定义在文件external/chromium_org/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp中。

从前面的分析可以知道,GraphicsLayer类的成员变量m_layer指向的是一个WebContentLayerImpl对象,调用这个WebContentLayerImpl对象的成员函数layer获得的是一个WebLayerImpl对象,如下所示:

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

blink:

:

WebLayer*WebContentLayerImpl:

:

layer(){

returnlayer_.get();

}

这个函数定义在文件external/chromium_org/content/renderer/compositor_bindings/web_content_layer_impl.cc中。

从前面的分析可以知道,WebContentLayerImpl类的成员变量layer_指向的是一个WebLayerImpl对象,因此WebContentLayerImpl类的成员函数layer返回的是一个WebLayerImpl对象。

回到GraphicsLayer类的成员函数updateChildList中,它接下来调用GraphicsLayer类的成员函数platformLayer获得当前正在处理的GraphicsLayer的所有子GraphicsLayer对应的WebLayerImpl对象,如下所示:

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

WebLayer*GraphicsLayer:

:

platformLayer()const

{

returnm_layer->layer();

}

这个函数定义在文件external/chromium_org/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp中。

这些子GraphicsLayer对应的WebLayerImpl对象也就是通过调用它们的成员变量m_layer指向的WebContentLayerImpl对象的成员函数layer获得的。

再回到GraphicsLayer类的成员函数updateChildList中,获得当前正在处理的GraphicsLayer对应的WebLayerImpl对象,以及其所有的子GraphicsLayer对应的WebLayerImpl对象之后,就可以通过调用WebLayerImpl类的成员函数addChild在它们之间也建立父子关系,如下所示:

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

voidWebLayerImpl:

:

addChild(WebLayer*child){

layer_->AddChild(static_cast(child)->layer());

}

这个函数定义在文件external/chromium_org/content/renderer/compositor_bindings/web_layer_impl.cc中。

从前面的分析可以知道,WebLayerImpl类的成员变量layer_指向的是一个PictrueLayer对象,因此WebLayerImpl类的成员函数addChild所做的事情就是在两个PictrueLayer对象之间建立父子关系,这是通过调用PictrueLayer类的成员函数AddChild实现的。

PictrueLayer类的成员函数AddChild是父类Layer继承下来的,它的实现如下所示:

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

voidLayer:

:

AddChild(scoped_refptrchild){

InsertChild(child,children_.size());

}

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

Layer类的成员函数AddChild将参数child描述的PictrueLayer设置为当前正在处理的PictureLayer的子PictureLayer,这是通过调用Layer类的成员函数InsertChild实现的,如下所示:

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

voidLayer:

:

InsertChild(scoped_refptrchild,size_tindex){

DCHECK(IsPropertyChangeAllowed());

child->RemoveFromParent();

child->SetParent(this);

child->stacking_order_changed_=true;

index=std:

:

min(index,children_.size());

children_.insert(children_.begin()+index,child);

SetNeedsFullTreeSync();

}

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

Layer类的成员函数InsertChild所做的第一件事情是将当前正在处理的PictureLayer设置为参数child描述的PictrueLayer的父PictureLayer,并且将参数child描述的PictrueLayer保存在当前正在处理的PictureLayer的子PictureLayer列表中。

Layer类的成员函数InsertChild所做的第二件事情是调用另外一个成员函数SetNeedsFullTreeSync发出一个通知,要在CCLayerTree与CCPendingLayerTree之间做一个Tree结构同步。

Layer类的成员函数SetNeedsFullTreeSync的实现如下所示:

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

voidLayer:

:

SetNeedsFullTreeSync(){

if(!

layer_tree_host_)

return;

layer_tree_host_->SetNeedsFullTreeSync();

}

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

Layer类的成员变量layer_tree_host_指向的是一个LayerTreeHost对象,这个LayerTreeHost是用来管理CCLayerTree的,后面我们再分析它的创建过程。

Layer类的成员函数SetNeedsFullTreeSync所做的事情就是调用这个LayerT

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1