chromium ⑨

DOM树构建完成后,就开始构建RenderObject树了。渲染过程分为布局和绘制两个阶段,最终得到用户可见区域(ViewPort)图像在内存中的表示Bitmap。

1 RenderObject

RenderObject是渲染树中的子节点,也是RenderText,RenderImage等很多渲染树节点的基类,所以比较关键。

主要方法

  1. 递归遍历等操作,如parent(), firstChild(), nextSibling(), previousSibling()等
  2. 计算布局和获取布局相关信息,如layout(), style(), enclosingBox()
  3. 判断RenderObject对象属于哪种类型的子类,如IsASubClass()
  4. 坐标和绘图相关,如paint(), repaint()等。

子类

每个渲染对象用一个CSS盒模型对应的矩形区域来表示,包含宽高和位置之类的信息。盒模型受display属性影响, 根据它的值生成RenderInline RenderBlock等对象,他们都是RenderObject子类.

对于Text,Image等元素,分别有RenderText RenderImage等对象与之对应,他们也是RenderObject子类

与DOM对应关系

RenderObject树和DOM树的节点基本上是一一对应,但也有例外

  1. 不可见DOM节点没有RenderObject,如display: none的节点(display: hidden表示的有),head节点等。
  2. 复杂的DOM节点有多个RenderObject与之对应。如select节点,它对应显示区域,下拉列表和按钮三个RenderObject对象。

下面是一个对应关系的例子

2 布局

Webkit根据框模型来计算每个RenderObject的宽高和位置信息,这一过程称为布局。(对应到Android中的measure和layout两个阶段)。

布局是一个递归过程,从root开始,因此是一个很耗时耗内存的过程。大概分为下面几个步骤

  1. 主要由RenderObject的layout()函数完成。先判断节点是否需要重新计算。一个渲染对象发生变化了,就会给它的dirty bit做标记。渲染对象或者它的任何一个子节点如果有dirty bit标记,都会重新layout。
  2. parent对象会决定渲染对象的宽度,如100%则表示和父对象宽度一致。
  3. 递归遍历每个子节点,依次计算它们的布局。这个过程完成了才能知道父节点的高度。
  4. 得到宽高后,根据position属性可以计算得到它的位置信息。

3 绘制

绘制顺序

布局阶段完成后,就会开始绘制阶段了。此处的绘制是生成用户可见区域(ViewPort)的界面图像,保存在内存中。真正的图形绘制到界面上则是在你Browser进程中完成。绘制的过程大概分为下面几个步骤

  1. 绘制元素背景和边框
  2. 绘制浮动内容
  3. 绘制前景,也就是content,padding,border等。

增量绘制

第一次绘制时,需要绘制整颗RenderObject树。之后用户交互过程中(如滑动屏幕),则只需要绘制改变的部分即可。

渲染方式

分为两种,CPU软件合成和GPU硬件绘制。CPU软件合成可以利用增量绘制,适合不复杂的2D图形。GPU硬件绘制充分利用了并发优势,速度快,在显存中进行,但每次需要绘制整个图像,适合复杂的3D绘制和H5动画。

猜你喜欢

转载自www.cnblogs.com/dhsz/p/9252895.html