Chromium 软件渲染
- 软件渲染就是利用
CPU
,根据一定的算法来计算生成网页的内容; Chromium
都是用软件渲染的技术来完成页面的绘制工作(除非强行打开硬件加速绘制);
软件渲染基础和架构
Renderer
进程:RenderWidget
对象,它负责调度页面渲染和页面更新等操作以及和Browser
进程的通信;PlatformCanvas
,即SkiaCanvas
,Render
树的绘制操作中Canvas
的元素的实现;
Browser
进程:RenderWidgetHos
对象,负责同Renderer
进程的通信;BackingStore
,它是一个后端的存储空间,大小通常是网页可视区域的大小,该空间存储的就是页面的绘制结果;
- 两个进程之间的通信:
WebKit
负责遍历Render
树,每个RenderObject
节点根据需要来绘制自己和子节点的内容到目标存储,就是SkiaCanvas
所对应的共享内存的Bitmap
中;之后,RenderWidgetHost
把bitmap
复制到backingstore
的相应区域中,并调用paint
来把自己绘制到窗口中;
具体渲染过程
发起重新绘制某些区域的请求
- 前端请求:包括从
browser
进程发起的请求,可能是browser
自身的,也有可能是其他窗口系统; - 后端请求:由页面自身发起更新部分区域的请求,如
HTML
元素或者样式的改变,动画等等。
例子:JS
代码每隔50ms更新元素;
Renderer
进程的message loop
调用处理Invalidation
的回调函数,该函数主要调用RenderWidget::DoDeferredUpdate
来完成绘制请求;RenderWidget::DoDeferredUpdate
首先调用layout
来触发检查是否有需要重新计算的布局和更新请求;RenderWidget
调用TransportDIB
来创建共享内存,内存大小为绘制区域的高×宽×4,同时调用Skia
来创建一 个canvas
,它的绘制目标是一个使用共享内存存储的bitmap
;- 当渲染该页面的全部或者部分时,
ScrollView
请求按照从前到后顺序遍历并绘制所有的RenderLayer
的内容到目标的bitmap
中,每个RenderLayer
的绘制通过以下步骤来完成:- 首先计算重绘的区域是否和自己有重叠,如果有, 则要求该
layer
中的所有RenderObject
对象绘制自己;
- 首先计算重绘的区域是否和自己有重叠,如果有, 则要求该
- 绘制完成后,发送
UpdateRect
的消息给browser
进程,Renderer
进程同时返回完成绘制;Browser
进程接受到消息后首先由BackingStoreManager
来获取或者创建BackingStoreX
,大小是 Viewport,包