webkit 学习笔记 - 7.渲染基础

RenderObject 树

  • 对于可视节点(head、meta 等为非可视节点),Webkit 会为它们建立相应的 RenderObject 对象,这个对象保存了为绘制 DOM 节点所需要的各种信息。这些 RenderObject 对象同 DOM 节点一样,也会构成一棵树,称为 RenderObject 树
    在这里插入图片描述
  • 每个 DOM 对象都会递归调用 attach 函数,该函数检查 Element 对象是否需要创建 RenderObject,如果需要,则调用 NodeRenderingContext 类来创建相应的 RenderObject 节点
  • RenderObject 基类和它的主要子类
    在这里插入图片描述
  • Webkit 在某些情况下需要建立匿名的 RenderObject,因为 RenderBlock 的子女必须都是内嵌的元素或者都是非内嵌的元素
    <!DOCTYPE html>
    <html>
    <head>
    	<style type="text/css">
    		video,div,canvas{
    			-webkit-transform: rotateY(30deg) rotateX(-45deg);
    		}
    	</style>
    </head>
    <body>
    	<video src="avideo.mp4"></video>
    	<div>
    		<canvas id="a2d"></canvas>
    		<canvas id="a3d"></canvas>
    	</div>
    	<script type="text/javascript">
    		var size = 300;
    		var a2dCtx = document.getElementById('a2d').getContext('2d');
    		a2dCtx.canvas.width = size;
    		a2dCtx.canvas.height = size;
    		a2dCtx.fillRect(0,0,200,200);
    
    		var a3dCtx = document.getElementById('a2d').getContext('2d');
    		a3dCtx.canvas.width = size;
    		a3dCtx.canvas.height = size;
    		a3dCtx.clearColor(0,0,192.0/255.0,192.0/255.0,80.0/255.0);
    		a3dCtx.clear(a3dCtx.COLOR_BUFFER_BIT);
    	</script>
    </body>
    </html>
    
  • DOM 树节点和 RenderObject 树的对应关系
    在这里插入图片描述

网页层次和 RenderLayer 树

  • Webkit 会为网页的层次创建相应的 RenderLayer 对象,当某些类型的 RenderObject 的节点或者具有某些 CSS 样式的 RenderObject 节点出现的时候,Webkit 会这些节点创建 RenderLayer 对象。一般来说,某个 RenderObject 节点的后代都属于该节点,除非 Webkit 根据规则为某个后代节点创建了一个新的 RenderLayer 对象
  • RenderLayer 树是基于 RenderObject 树建立起来的一棵新树。RenderObject 节点和 RenderLayer 节点不是一一对应关系,而是一对多的关系。下面这些情况会建立新的 RenderLayer 节点

    DOM 树的 Document 节点对应的 RenderView 节点
    DOM 树中的 Document 的子女节点,也即 HTM 对应的 RenderOject 节点
    显示的指定 CSS 位置的 RenderObject 节点(position:absolute等)
    有透明效果的 RenderObject 节点
    节点有溢出(Overflow)、alpha 或者反射等效果的 RenderObject 节点
    使用 Canvas 2D 和 3D 技术的 RenderObject 节点
    Video 节点对应的 RenderObject 节点

  • 除了 RenderLyaer 树的根节点,一个 RenderLayer 节点的父节点就是该 RenderLayer 节点对应的 RenderObject 节点的祖先链中最近的祖先
  • 每个 RenderLyaer 节点包含的 RenderObject 节点其实是一棵 RenderObject 子树。理想情况下,每个 RenderLayer 对象都会有一个后端类,该后端类用来存储该 RenderLayer 对象绘制的结果
  • RenderObject 树和 RenderLayer 树的对应关系
    在这里插入图片描述
    在这里插入图片描述

渲染方式

  • 在 Wibkit 中,绘图操作被定义了一个抽象层,称为绘图上下文。绘图上下文可分为两种类型,第一种是用来绘制 2D 图形的上下文,称之为 2D 绘图上下文(GraphicsContext);第二种是绘制 3D 图形的上下文,称之为 3D 绘图上下文(GraphicsContext3D)。这两种上下文都是抽象类,也就是说它们只提供接口,因为 Webkit 需要支持不同的移植。而这两个抽象基类的具体绘制则由不同的移植提供不同的实现
  • PlatfromCraphicsContext 类和 PlatfromCraphicsContext3D 类是两个表示上下文的类,Webkit 通过 C 语言的 typeof 来将每个不同移植的类重命名成 PlatfromCraphicsContext 和 PlatfromCraphicsContext3D
  • 每个 RenderLyaer 对象可以被想象成图像中的一个层,各个层一同构成了一个图像。在渲染的过程中,浏览器也可以作同样的理解。每个层对应网页中的一个或者一些可视元素,这些元素的都绘制内容到该层上。如果绘图操作使用 CPU 来完成,那么称之为软件绘图。如果绘图操作由 GPU 来完成,则称之为 GPU 硬件加速绘图。理想情况下,每个层都有个绘制的存储区域,这个存储区域用来保存绘图的结果。最后,需要将这些层的内容合并到同一个图像之中,称之为合成(Composit),使用了合成技术的渲染称之为合成化渲染
  • 渲染方式一般分为三种:

软件渲染:使用 CPU 来绘制每一层
硬件渲染:使用 GPU 来绘制每一层
合成化渲染:使用 CPU 绘制一些层,使用 GPU 绘制另一些层
在这里插入图片描述

  • 在软件渲染的机制中,通常渲染的结果就是一个位图(Bitmap),绘制每一层的时候都使用该位图,区别在于绘制的位置可能不一样,当然每一层都是按照顺序从后到前的顺序,所以软件渲染没有合成阶段
  • 硬件渲染和合成化渲染都包含了合成的工作,合成的工作都是由 GPU 来做,称之为硬件加速合成(Accelerated Compositing)。对于使用 CPU 来绘制的层,该层首先保存在 CPU 中,之后被传输到 GPU 内存中,用于之后的合成

软件渲染过程

  • 对于每个 RenderObject 对象,需要三个阶段来绘制自己,第一阶段是绘制该层的背景和边框,第二阶段是绘制浮动内容,第三阶段是绘制前景(子元素)、轮廓(outline)。子元素的绘制同样遵循该机制
  • Webkit 第一次绘制网页的时候,Webkit 绘制的区域等同于可视区域的大小。在这之后,Webkit 只是首先计算需要更新的区域,然后绘制和这些区域有交集的 RenderObject 节点。这也就是说,如果更新区域跟某个 RenderLayer 节点有交集,Webkit 会继续查找 RenderLayer 树中包含的 RenderObject 子树中的特定一个或一些节点,而不是绘制整个 RenderLayer 对应的 RenderObject 子树。如果该层和更新区域重叠,则需要绘制该层所有的 RenderObject
  • 在 Render 进程中,Skia Canvas 把内容绘制到位图中,该位图的后端即是共享的内存 CPU。当 Borwser 进程收到 Render 进程关于绘制完成的通知消息,Browser 进程会把共享内存复制到 BackingStrore 对象中,然后释放共享内存
    在这里插入图片描述
  • 一个多进程的软件渲染过程大致是这样的:RenderWidget类接受到更新请求时,Chrominum 创建一个共享内存区域。然后 Chrominum 创建 Skia 的 SkCanvas 对象,并且 RenderWidget 会把实际绘制任务派发给 RenderObject 树。Webkit 负责遍历 RenderObject 树,每个 RenderObject 节点根据需要来绘制自己和子女到目标存储空间,也就是 SkCanvas 对象对应的共享内存的位图中。最后,RenderWidgetHost 类把位图复制到 BackingStore 对象的相应区域中,并调用“paint”来把结果绘制到窗口中
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值