福建白癜风医院 http://baidianfeng.39.net/a_cjzz/131118/4292721.htmlA浏览器结构模型
Chromium主要有Browser,Render,GPU等进程,还有插件进程没在下图表示。由于Chromium工程设计的灵活性,提供多种选择,所以这几个可以部分为独立进程,也可以不设置为独立进程。当然这种灵活性本身也增加了不少工程量。
Chroimium跨进程模型
1、Browser进程
页面显示,tab页面管理,用户交互,下载管理等。
2、Render进程
渲染进程,根据不同情况可以为一个或者多个,
Processpersiteinstance:
每一个页面都创建一个独立的Render进程,不管这些页面是否来自于同一域。
Processpersite:
属于同一个域的页面共享同一个进程,而不同属一个域的页面则分属不同的进程。
Processpertab:
Chromium每个标签页都是独立进程
Singleprocess:
该类型的含义是,Chromium不单独为页面创建任何独立进程,所有渲染工作都在Browser进程中进行,它们是Browser进程中的多个线程。
3、GPU进程
4、NPAPI插件进程
B不同平台之间的跨平台问题
Chromium由Google开源并维护,代码规模异常庞大,跨多个平台,包括Mac系统,Linux系统,Windows系统,iOS系统(其中有部分和maccocoa共用)以及Google自己的Android系统。Chomium维护了多个平台和UI的一致性,这也是导致他异常复杂的原因之一了。
我们可以参考一下Chromium跨平台的一些做法,这些做法让代码结构易于维护和保持一致性。
一、就是利用后缀命名的方式:
Mac文件用_mac,其中涉及UI(cocoa)部分用_cocoa。MacCocoa:chrome/browser/ui/cocoa
Linux文件用_linux后缀,其中GTK专有的部分用_gtk,其他专有部分用_x。LinuxGTK:chrome/browser/ui/gtk
Windows系统用_win后缀。
iOS用_ios后缀,不过iOS部分使用_mac。
各平台(MaciOSLinux)用_posix后缀share文件。
浏览器前端代码分别由各自的平台自己的目录下面。
二、#ifdef大法
refC++语言。待续C++部分
三、impl大法
refC++语言。头文件h文件中,可以用#ifdef区别不太的平台,如果比较大的实现部分可以用implenataion的方式来分离。
在base目录下就有不少的例子,其中waitable_event.h中,基于不同平台的情况定义通用API。其中给不同的平台定义了不同的实现,当然,如果需要定义一些通用的东西还是需要增加waitable_event.cc的实现的。
和waitable_event有关的目录
另外,单独的几乎没有共用部分的代码可以使用xx_xx_win这样的方式来命名,其中的类Xx_Xx_Win。
C浏览器的启动过程代码
浏览器启动部分代码目录:
启动入口目录
Windows
在Windows系统上,构建一个dll来启动WinMain入口。。。。
Mac
在Mac上打包成一个Framework以及一个可执行文件,这二者可链接在一起。通过main函数启动ChromeMain来启动。另外还有一个启动入口位于/src/chrome/app_shim/chrome_main_app_mode_mac.mm。这个入口同样调用ChromeMain函数
Linux
由于沙盒的因素,可以启动一个子进程,确保子进程本身不会再进main函数。最后也同样是调用ChromeMain函数。
D渲染模型
Chromium及其庞大复杂,其中webkit/blink渲染页面主要包括如下几个步骤:
1、解析成DOM
----每一个HTML节点都可以对应到DOM树种的一个节点Node。其中顶层根节点应该就是Document节点。
2、将DOM转成RenderObject树
-----DOM树种的每个可视节点都对应到Render树的每个节点,并且通过GraphicsContext绘制。GraphicsContext可以wrap一些skiaopengl等,关于GraphicsContext待续。
3、转成RenderLayer
----每一个RenderObject节点都可以通过祖先节点直接或者间接的对应到RenderLayer节点。有共同坐标系空间的RenderObject都在一个RenderLayer。
符合一些条件可以为部分的RenderObeject创建一个RenderLayer,定义RenderBoxModelObject::requiresLayer()
DOM树的Document节点对应的RenderView节点。DOM树中的Document的子女节点,也就是HTML节点对应的RenderBlock节点。显式的指定CSS位置的RenderObject节点。有透明效果的RenderObject节点。节点有溢出(Overflow)、alpha或者反射等效果的RenderObject节点。使用Canvas2D和3D(WebGL)技术的RenderObject节点。Video节点对应的RenderObject节点。
*页面的根节点
*显示的有CSS指定的位置属性(相对绝对or转换)。
*透明节点
*有溢出alpha或者反射效果的节点
*有一个CSS过滤器
*可以有3D(WebGL)或者加速2DContext对应到canvas节点
*对应到video节点
所以RenderObject和RenderLayer不是一一对应的关系。并且RenderLayer本身也是树形结构。
*从RenderLayers到GraphicsLayers**
为了利用Compositor,部分RenderLayer有自己的BackingSurface。所有的RenderLayer都有都使用自己的graphicLayer或者自己最近祖先的GraphicLayer。这点和RenderObject和RenderLayer关系类似。
每个GraphicsLayer都有一个GraphicsContext供关联的RenderLayers绘制。合成器最终负责在随后的合成过程中将GraphicsContexts的位图输出一起合并到最终的屏幕图像中。
从理论上讲,每个单独的RenderLayer都可以将其自身绘制到单独的支持表面上,但实际上在内存方面(尤其是VRAM)这可能非常浪费。在当前的Blink实现中,必须满足以下条件之一才能使RenderLayer获得其自己的合成层(/third_party/blink/renderer/platform/graphics/