《Life of a pixel (Chrome University 2019)》学习

学习资料:链接

学习进度

  • 20210518,学习最高优先级
  • 2021.06.11,已完成对html、css、javascript学习,预计耗时2天时间学习本资料
  • 2021.06.11晚,熟悉html css js语法后,更加理解视频的内容

Content

chrome安全模型,很关键的一个步骤,渲染在sandboxed process中

Blink:Rendering engine

web content

  • HTML(Hyper-Text Markup Language)
  • CSS(Cascading Style Sheets)
  • JavaScript:和Rendering打交道
  • images
  • 不依赖于额外的库,这是web流行很重要的原因之一

DOM stage

目前市场上的图形库:Opengl,DirectX,Vulcan

 渲染的目标

  • 将HTML CSS JS正确地翻译到OpenGL calls去画像素
  • 通过中间数据,实现快速的实时渲染。Intermediate data strucures let chrome update the rendering more efficiently

HTML Parse

  • 对于HTML的文本内容,解析成一颗Tree——Document Object Model (DOM)
    • DOM two duty
      • 浏览器内部实现的代表结构
      • 暴露API给JS
        • V8 JS 引擎,暴露DOM AIPs给js,通过C++包装最后提供使用
  • 解析过程如果碰到<script>就会停止HTML解析,因为js可能会修改DOM Tree结构
  • 一个Document可能有多个DOM
    • 因为存在customeElement,所以会有多个DOM。每个cutsomElement又有一个ShadowTree,有slot插槽,用于内嵌markup标签

style stage

允许用户通过属性,定义渲染方式

style可以修改某个指定的节点Node,也可以影响该以该节点为根的子树

style的定义可能会有冲突,这里面会有复杂的优先级判定。这也是style engine's job

CSS文本,被解析成一个object model

  • 解析成StyleRule,包含SlectorList以及Property mappings
  • CSS的底层实现,和py,.cc,.json有密不可分的关系

现在我们来看看解析style后,我们如何应用到DOM上

  • 对于每一个DOM NODE先序遍历,都产生了一个ComputedStyle,计算属性值。F12→Element→Computed
  • 通过 style engine(Blink)处理的

layout stage (LayOut Engine:NG)

简单来说,style values作为input到layout,layout通过各种算法进行布局

创建Layout Tree,计算好几何数据,绘制的顺序

  • 我们可以认为每一个元素占领了content里面一个矩形区域。因此layout(布局)的工作,就是为了处理这些矩形坐标关系
    • 使用了一个库叫做HarfBuzz,根据字体的长宽这些参数(Style属性的生成),计算出它们应该放在哪个位置,字体间距调整等等
    • Layout会维护Scroll相关的数据。 DOM Root Node就是一个很典型的scrollable,相当于浏览器可上下拖动。CSS使得任何Node/Element都是scrollable

Layout Tree的节点和DOM节点基本上是一一对应,每个Layout TreeNode都实现了LayOut算法进行布局。每一个LayOutNode都是一个LayOut Object

  • 一些特例,例如display:none的情况下,就没有LayOut Node

Compositing Update stage(输入分层,类似ps一样有多个图层)

在layout之后,paint之前

将页面分成多个图层,每个图层都有对应的display item list


Prepaint stage

创建Property tree


paint stage

在已有layout处理结果的情况下,在paint list里记录了所有的pain operationd

paint使用的是stacking顺序而非DOM顺序,例如z-index越大,反而会越靠后渲染


以上是main线程做的事情,输出paintOperationItemList

以下是compositor thread(Impl thread),输出最后的光栅化结果给GPU PROCESS


Divide tiles

将layer broken to tiles


Raster stage(光栅化)

光栅化将paintOperationItemList转变成bitmap 【RGBA】 和 GPUMemory

光栅化也在处理<img>标签的图片,对图片资源进行解码,然后通过光栅化的手段转换成像素点的rgba

Chrome光栅化使用的库,叫Skia Graphics library,简称SGL,以第三方插件(The Thrid Party)的形式在chrome中使用

  • skia因为在render process中,是sandbox,因此不能直接进行system calls。需要通过GPU Process发起真正的OpenGL调用

CompositorFrame Buffer是渲染进程的结果,最后交给gpu process


GPU stage(GPU Process)

最后的光栅化结果从Render Process传送给GPU Process的skia图形库去处理。GPU有更强大的处理能力,以及更加安全的进行渲染

  • 有另一种方式,skia图形库的光栅化在GPU上进行。直接 paintOperationItemList into gpu process,and run skia on gpu

在windows下,通过ANGLE,将OpenGL转化为DirectX


Optimization(渲染是动态的,走完所有stage是昂贵的,因此我们要做优化)

优化

  • 如果每一帧都要把所有的stage跑一遍,那可能消耗太大了,因此要做按需update。需要改的地方重新渲染,不需要改动的地方reused复用
  • chromium团队提出类似photoshop来解决卡顿(jank):enter:compositing
    • layer的渲染是独立的,每个layer单独进行光栅化,将layer划分成若干个tiles,tile就变成了光栅化的更小单元
      •  compositor有一个tile manager去处理合并tile,在viewport的tile,优先光栅化。所有tile光栅化完毕之后,compositor thread开始draw quad,最后交给gpu process
      • 例如wobble摇晃功能,只光栅化一次,之后直接在GPU移动bitmap on gpu
      • 对于each layer,有一个property tree,最早是和layer耦合在一起。 近期chrome已经解耦,为了compositing architecture更加的flexible。有点像享元模式,节省了内存
    • 单独使用一个impl线程去进程图层合成
      • 当我们进行缩放,移动操作时,impl线程会监听用户的input,让main thread 继续执行 javascript code。如果其发现不能解决,还是会交给main thread执行

为了防止draw没完成,又来了一个commit,有一个临时的copy版本,pending tree供使用

display compositor 合并多个frame来自多个surface。简单来说,它可以处理多个render process output and 调用OpenGL calls


总结

web content → render → pixel


一些补充知识

现代浏览器是多进程架构

  • 浏览器进程
  • 缓存进程
  • 网络进程
  • 渲染器进程
  • GPU进程
  • 插件进程

为什么是多进程而不是多线程?

  • 多进程安全,不会因为一个页面卡死,所有页面都卡死
  • 有一些进程是沙箱环境,例如插件进程,防止恶意程序搞破坏
  • 本质上还是内存换安全和鲁棒
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值