Chrome页面渲染的GPU加速技术 - 基础:WebKit软件渲染模式

参考来源:http://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-in-chrome

WebKit的渲染引擎代码非常复杂,文档又比较欠缺。为了易于理解Chrome中GPU加速渲染的工作原理,最好先了解一下WebKit如何来渲染页面的。
我们先从非GPU加速的渲染来进行介绍,然后在此基础上再说GPU发挥了什么作用。

1. 节点(Nodes)和DOM树

在WebKit中,网页内容是通过由一些节点(Node)组成的树型结构组织在一起的,被称作DOM树。页面中的每个HTML元素以及元素携带的数据被保存在一个节点(Node)中。
DOM树中,最根部的节点(Node)总是一个Document节点。

2. 节点(Nodes)与渲染对象(RenderObjects)

DOM树中每个可以显示的节点(Node),都对应一个渲染对象(RenderObject),渲染对象被存储在一个有层级的树形结构中,叫做渲染树(Render Tree)。
一个渲染对象知道如何绘制其对应的节点到画布上,它对图形环境(GraphicsContext)执行一系列绘图操作,然后由图形环境(GraphicsContext)将绘图产生的像素值映射到显示屏幕上。

在Chrome中,2D图形环境(GraphicsContext)封装在Skia库中,大部分的绘图调用,都是针对SkCanvas或者SkPlatformCanvas的(详细内容请参考Chrome Skia)。

在软件渲染模式下,整个页面只需要一个图形环境(GraphicsContext),所有的渲染对象(RenderObject)都对它进行绘制。

3. 渲染对象(RenderObjects)与渲染图层(RenderLayers)

每个渲染对象(RenderObject)都有其对应的渲染图层(RenderLayer),或者是直接关联,或者是通过其根对象(其根级RenderObject)间接关联。

一般来讲,拥有相同坐标空间(如受控于相同的CSS变换)的渲染对象会属于同一个渲染图层。渲染图层可以保证渲染对象在重叠、半透明等情况时,能以正确层叠次序进行绘制。
RenderBoxModelObject::requiresLayer()中定义了一些为渲染对象创建新渲染图层的前提条件,如:

 * 渲染对象是页面的根对象;
 * 渲染对象有独立的CSS定位属性(相对、绝对、变换);
 * 渲染对象是透明的;
 * 覆盖有透明(Alpha)蒙版或者反射层;
 * 有CSS效果滤镜;
 * 该渲染对象对应于<canvas>标签指定的WebGL或者2D加速图形元素;
 * 该渲染对象对应于<video>标签元素;

注意渲染对象与渲染图层间不存在一对一关系,一个渲染对象,要么对应于专为它创建的的渲染图层,要么对应于其某级根对象的渲染图层。

渲染图层(RenderLayers)也是以树形结构来组织的,根部的图层即对应渲染树(Render Tree)中根部的渲染对象。
每个渲染图层(RenderLayer)同时存储在两个基于不同深度值方向(Z-Order)的列表中:正向深度列表posZOrderList,以及负向深度列表negZOrderList。

4. 三个树结构

可以说,渲染过程中,有三个树形结构各司其职:

 * DOM树(DOM Tree),持有构成页面的所有的数据节点对象;
 * 渲染对象树(RenderObject Tree),持有与可显示节点(Node)一对一的渲染对象,每个渲染对象知道如何绘制与其对应的节点;

 * 渲染图层树(RenderLayer Tree),基于渲染对象树构建的层级树,每个渲染图层对应一至多个渲染对象;


5. 软件渲染过程

WebKit在渲染页面时,从根节点开始遍历渲染图层树(RenderLayer Tree),直至叶子节点,在页面渲染的实现上,WebKit包含两种方式:
软件渲染和硬件加速渲染,而软件渲染是最基本的方式。

软件渲染过程,整个页面中的每个渲染图层按照深度从后向前的顺序依次被绘制,渲染图层的主要绘制工作都是在RenderLayer::paintLayer()中完成,其中大概包含如下步骤:

 a. 判断图层边界是否与刷新矩形有交叉;
 b. 通过调用图层的paintLayer()方法,屏幕深度上从前向后,递归绘制negZOrderList列表中位于该图层后面的图层;
 c. 让该图层相关联的所有渲染对象(RenderObject)完成各自的绘制;
 d. 渲染对象(RenderObject)的绘制过程,从那个创建该图层的对象开始,向渲染对象树(RenderObject Tree)末端遍历,
    直至遇到一个不属于当前渲染图层(RenderLayer)的渲染对象(RenderObject)而结束;
 e. 通过调用图层的paintLayer()方法,屏幕深度上从后向前,递归绘制posZOrderList列表中位于该图层前面的图层。
 
在这种渲染方式下,渲染对象通过对绘图环境(GraphicsContext,Chrome中的Skia库)执行一系列绘图操作,将自己的内容绘制在内存位图上。

绘图环境本身并不关心图层的概念,但是在绘制半透明图层时有一点需要注意:半透明图层在开始绘制渲染对象时,会调用GraphicsContext::beginTransparencyLayer(),
在Skia库的实现中,这个调用会使得后续的所有绘制都在独立的位图上进行,以至于当该图层相对应的所有对象渲染完成时(此时endTransparencyLayer()方法被调用),
这些独立位图能够与基础图像(或者称背景图像)进行合成(进行必要的Alpha混合,以实现半透明效果)。

6. 将WebKit渲染结果显示在屏幕上


当所有的渲染图层(RenderLayers)将内容绘制到内存位图上之后,还需要将内存位图呈现在屏幕上。在Chrome系统中,渲染器进程会将渲染好的内存位图放入共享内存中,
然后通过IPC消息通知浏览器进程进行界面更新,浏览器进程收到IPC通知后,使用操作系统API,将内存位图绘制到指定窗口(标签对应的网页视图)上。




 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值