前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >高性能Web动画和渲染原理系列(4)“Compositor-Pipeline演讲PPT”学习摘要

高性能Web动画和渲染原理系列(4)“Compositor-Pipeline演讲PPT”学习摘要

作者头像
大史不说话
发布于 2019-11-15 02:26:19
发布于 2019-11-15 02:26:19
8720
举报

示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:《大史住在大前端》原创博文目录

术语里的cc指的是Chromium Compositor

一直以来都想了解浏览器合成层的运作机制,但是相关的中文资料大多比较关注框架和开发技术,这方面的资料实在是太少了,后来在chromium官方网站的文档里找到了项目组成员malaykeshav在 2019年4月的一份关于浏览器合成流水线的演讲PPT,个人感觉里面讲的非常清楚了,由于没有找到视频,有些部分只能自行理解,本文仅对关键信息做一些笔记,对此感兴趣的读者可以在文章开头的github仓库或附件中拿到这个PPT自行学习。

摘要

1.合成流水线

合成流水线,就是指浏览器处理合成层的工作流程,其基本步骤如下:

大致的流程就是说Paint环节会生成一个列表,列表里登记了页面元素的绘制指令,接着这个列表需要经过Raster光栅化处理,并在合成帧中处理纹理,最后的Draw环节才是将这些纹理图展示在浏览器内容区。

2. 预定义UI层

chromium中预定义了一些指定类型的UI层,大致分为:

  • Not Drawn - 为了处理透明度或滤镜效果、transform变形或者clip剪裁的非绘制层
  • Solid color layer - 固有颜色层
  • Painted texture layer - Texture纹理会在这个层执行paint渲染和后续的rasterized光栅化任务
  • Transferable resource layer - 共享资源层,可能是GPU里面的Texture纹理也可能未来会发给GPU的位图
  • Surface layer - 临时占位层,因为自顶向下遍历layer树时子树都还没处理,需要先占位最后再填充
  • Nine patch layer - 用于实现阴影的层

3. paint是什么意思

每个层layer是由若干个views组成的,所谓paint,就是每个views将自己对应图形的绘制指令添加到层的可展示元素列表Display Item List里,这个列表会被添加到一个延迟执行的光栅化任务中,并最终生成当前层的texture纹理(可以理解为当前层的绘制结果),考虑到传输性能以及未来增量更新的需求,光栅化的结果会以tiles瓦片形式保存。在chrome中也可以看到页面瓦片化拆分的结果:

4. 分层的优势和劣势

分层的优势和劣势也在此进行了说明,和之前我们主动思考的答案基本一致(暗爽一下)。

5. 视图属性及其处理方式

views中支持的属性包含Clip剪裁,transform变换,effect效果(如半透明或滤镜等),mask遮罩,通常按照后序遍历的方式自底向上进行遍历处理。

clip剪裁的处理方式是在父节点和子节点之间插入一个剪裁层,用来将其子树的渲染结果剪裁到限定的范围内,然后再向上与父级进行合并;

transform变换直接作用于父节点,处理到这个节点时其子树都已经处理完毕,直接将整体应用变形即可;

effect效果一般直接作用于当前处理的节点,有时也会产生交叉依赖的场景;

PPT第40页中在介绍effect效果处理时描述了两种不同的透明度处理需求,从而引出了一个Render Surface的概念,它相当于一个临时的层,它的子树需要先绘制在这个层上,然后再向上与父节点进行合并,屏幕就是是根级的Render Surface

6. Quads

Layer遍历处理输出的结果被称为Quads(从意思上理解好像就是指输出了很多个矩形方块),每个quad都持有它被绘制到目标缓冲区所需要的资源,根据它持有的资源不同可以分为:

  • Solid Color-固定颜色型
  • Texture- 纹理型
  • Tile- 瓦片型
  • Surface- 临时绘图表面型
  • Video - 视频帧型
  • Render Pass - Render Surface类型的占位区,Render Surface子树处理完后填充到关联的Render Pass

7. Compositor Frame

合成层真正的工作要开始了,主角概念Compositor Frame(合成帧)登场,它负责将quads合并绘制在一起,胶片里59-62页非常清楚地展示了合成的过程,最终输出的结果就是根节点的纹理。

chromium是多进程架构,Browser Process浏览器进程会对菜单栏等等容器部分的画面生成合成帧来输出,每个网页的Render Process渲染进程会对页面内容生成合成帧来输出,最终的结果都被共享给GPU ProcessGPU进程进行聚合并生成最终完整的合成表面,接着在Display Compositor环节将最后的位图展示在屏幕上。

8. 关于光栅化以及渲染方式

胶片里并没有描述具体的光栅化的处理过程,但是layer输出的quads看起来应该是光栅化以后的结果,推测应该是处理Display Item List中的绘图指令时也和WebGL类似,经过顶点着色器片元着色器的遍历式处理机制,并在过程中自动完成像素插值。

9.【重要】软件渲染和硬件渲染的区别

声明:本节内容是个人理解,仅用作技术交流,不保证对!

软件渲染和硬件渲染的区别对笔者而言一直非常抽象,只是知道基本概念。后来在【chromium开发者文档】(国内可能无法访问)中《Compositor Thread Architecture》这篇合成器线程架构的文章中找到了一些相关描述,也解开了笔者心中一直以来的疑惑,相关部分摘抄如下:

Texture Upload One challenge with all these textures is that we rasterize them on the main thread of the renderer process, but need to actually get them into the GPU memory. This requires handing information about these textures (and their contents) to the impl thread, then to the GPU process, and once there, into the GL/D3D driver. Done naively, this causes us to copy a single texture over and over again, something we definitely don't want to do. We have two tricks that we use right now to make this a bit faster. To understand them, an aside on “painting” versus “rasterization.”

  • Painting is the word we use for telling webkit to dump a part of its RenderObject tree to a GraphicsContext. We can pass the painting routine a GraphicsContext implementation that executes the commands as it receives them, or we can pass it a recording context that simply writes down the commands as it receives them.
  • Rasterization is the word we use for actually executing graphics context commands. We typically execute the rasterization commands with the CPU (software rendering) but could also execute them directly with the GPU using Ganesh.
  • Upload: this is us actually taking the contents of a rasterized bitmap in main memory and sending it to the GPU as a texture.With these definitions in mind, we deal with texture upload with the following tricks:
  • Per-tile painting: we pass WebKit paint a recording context that simply records the GraphicsContext operations into an SkPicture data structure. We can then rasterize several texture tiles from that one picture.
  • SHM upload: instead of rasterizing into a void* from the renderer heap, we allocate a shared memory buffer and upload into that instead. The GPU process then issues its glTex* operations using that shared memory, avoiding one texture copy.The holy grail of texture upload is “zero copy” upload. With such a scheme, we manage to get a raw pointer inside the renderer process’ sandbox to GPU memory, which we software-rasterize directly into. We can’t yet do this anywhere, but it is something we fantasize about.

大概翻译一下,方便英语水平一般的小伙伴理解,GPU处理图片的方式是按照Texture进行贴图的,对此不熟悉的小伙伴可以查看笔者以前发的有关Three.js相关的博文。

纹理上传: 处理纹理的挑战之一就是它是在渲染进程(可以理解为单个Tab网页的进程)的主线程里进行的,但是最终需要将其放入GPU内存。这就需要将纹理数据递交给合成器线程,然后再交给GPU进程(Chromium架构里有专门的GPU进程用来专门处理和GPU之间的协作任务),最后再传递给底层的Direct3DOpenGL(也就是图形学的底层技术),如果只是按照常规流程来处理,就会需要一次又一次来复制生成的纹理数据,这显然不是我们想要的。 我们现在使用了两个小方法来使这个流程变得快一点。它们分别作用于painting(绘制)和rasterization(光栅化)两个阶段。

  • 1号知识点!!!Painting我们用来告诉webkit为RenderObject Tree的来生成对应的GraphicsContext。通过给painting routine(绘制流程)传递一个GraphicsContext的具体实现来执行这些已经编排好的绘制命令,也可以传递一个record context(记录上下文)只是简单地把绘图命令都记录下来。
  • 2号知识点!!!Rasterization(光栅化)是指Graphics context关联的绘图命令实际被执行的过程。通常我们使用CPU(也就是软件渲染的方式)来执行光栅化任务,也可以直接使用GPU来渲染(也就是硬件渲染的方式)。
  • 上传:指在主线程存储区获取到光栅化以后的位图内容然后将它作为纹理上传给GPU的过程,考虑到上述已经提及的定义,上传过程是如下来处理的:
    • 瓦片绘制:我们在webkit中使用recording context来简单地记录Graphics Context的操作指令,将它存储为SkPicture类型(直接使用软件光栅化时生成的是SkBitmap类型),随后可以从一张picture里面光栅化处理得到多个纹理瓦片
    • 共享内存:在软件渲染的方式中,光栅化的结果会被存储在renderer进程的堆内存里,现在不这样搞了,我们重新分配了一块共享缓冲区,然后通过它来传递相关对象,GPU进程随后在获取纹理时直接从共享内存中获取就行了,这样就避免了数据的拷贝。 总的来说,纹理上传的过程几乎是零拷贝的。利用这样的结构,我们在renderer进程(也就是网页的渲染进程)的沙箱环境内也可以获取到指向GPU 内存的指针,而在软件光栅化的过程中,是直接将位图结果放在这里的。

  • Painting: this is the process of asking Layers for their content. This is where we ask webkit to tell us what is on a layer. We might then rasterize that content into a bitmap using software, or we might do something fancier. Painting is a main thread operation.
  • Drawing: this is the process of taking the layer tree and smashing it together with OpenGL onto the screen. Drawing is an impl-thread operation.
  • painting:表示的过程是向Layers对象查询层内容,也就是让webkit告诉我们每一层上面到底有什么。接下来我们就可以使用软件光栅化的方式将这些内容处理为位图,也可以做一些更牛的事情,painting是一个主线程行为。
  • drawing:是指将Layer中的内容用OpenGL绘制在屏幕上的过程,它是另一个线程中的操作。

概念比较多没有基础的读者可能理解起来有难度,我尝试用自己的话复述一下:

【软件渲染】的模式下,在paint时会直接利用Graphics Context绘图上下文将结果绘制出来,在一个SkBitmap实例中保存为位图信息;【硬件渲染】的模式下,在paint时传入一个SkPicture实例,将需要执行的绘图命令保存在里面先不执行,然后通过共享内存将它传给GPU进程,借助GPU来最终去执行绘图命令,生成多个瓦片化的位图纹理结果(OpenGL中顶点着色器向片元着色器传递数据时可以自动进行数据插值,完成光栅化的任务)。 纯软件渲染里严格说是没有合成层概念的,因为最终输出的只有一张位图,按照顺序从下往上画,和画到一个新层上再把新层贴到已有结果上其实是一样的。

不管使用哪种途径,paint动作都是得到位图数据,而最终的draw这个动作是借助OpenGL和位图数据最终把图形显示在显示器上。

所以【硬件渲染】就是渲染进程把要做的事情和需要的数据都写好,然后打包递给GPU让它去干活。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-11-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Centos7升级内核至5.4
用户5921339
2025/05/20
2570
Centos7升级内核至5.4
CentOS7升级内核
安装导入包 rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm rpm -import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org 查看可用内核版本 yum --disablerepo="*" --enablerepo="elrepo-kernel" list available 安装4版本kernel-lt内核 yum -y --enablerepo=elrep
院长技术
2020/12/10
1.3K0
CentOS 7/6系统升级内核版本到5.2.2
由于公司服务器新业务需要,需要将CentOS 7系统的内核(3.10.0-229)进行升级。
用户1679793
2019/07/25
7.3K0
CentOS 7 升级 Linux 内核
升级 CentOS 内核参考资料 1 升级 CentOS 内核参考资料 2 通过 /proc 虚拟文件系统读取或配置内核 Linux 内核官网 CentOS 官网
全栈程序员站长
2022/09/15
4.2K0
Centos 7 升级内核版本为 5.12.11​
为了 Docker、Kubernetes 运行稳定,升级 Centos 7 内核版本为 5.12.11。
叨叨软件测试
2021/07/16
3K0
centos7 安装高版本内核
因为一些调试及测试需要,我们的centos需要安装高版本内核以便进行BCC和BPF的实时调试功能。 
保持热爱奔赴山海
2020/02/17
2.1K0
CentOS 7 开启 BBR 加速
Google 在 2016年9月份开源了他们的优化网络拥堵算法BBR,最新版本的 Linux内核(4.9-rc8)中已经集成了该算法。 对于TCP单边加速,并非所有人都很熟悉,不过有另外一个大名鼎鼎的商业软件“锐速”,相信很多人都清楚。特别是对于使用国外服务器或者VPS的人来说,效果更佳。 网上有很多在 Debian 和 Ubuntu 系统下启用 BBR 的教程,我就不粘贴了,我自己一直用的是 CentOS,本文介绍一下在 64位 CentOS 7 系统下开启BBR的方法。 升级内核 第一步首先是升级内核到
小李刀刀
2018/03/02
5.1K0
Linux:Centos7升级内核 原
默认启动的顺序是从0开始,新内核是从头插入(目前位置在0,而4.4.4的是在1),所以需要选择0。
拓荒者
2019/03/11
1.8K0
centos7 内核如何升级
需求:由于客户容器化的需要,需要将当前的操作系统升级为5.10.7的版本。 内核升级操作步骤如下: 步骤一:载入公钥、安装elrepo rpm -import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm 步骤二、载入elrepo-kernel元数据 yum --disablerepo=\* --enablerepo
Linux运维技术之路
2022/06/07
2.6K0
centos系统yum升级内核版本
#查看现在的内核版本uname -aLinux worker01 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux#查看 yum 中可升级的内核版本yum list kernel --showduplicates#如果list中有需要的版本可以直接执行 update 升级,多数是没有的,所以要按以下步骤操作#导入ELRepo软件仓库的公共秘钥rpm --import https:
dgds
2023/05/11
1.6K0
干货,分享一次完整的CentOS升级内核脚本。
默认启动的顺序是从0开始,新内核是从头插入(目前位置在0,而4.4.4的是在1),所以需要选择0。
justmine
2019/03/11
1.4K0
018.CentOS升级内核
一 更新yum源 1 [root@localhost ~]# rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org 2 [root@localhost ~]# rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm 3 二 安装内核版本 2.1 查看当前内核版本 1 [root@localhost ~]# uname -a 2 L
木二
2021/04/20
8590
018.CentOS升级内核
Centos7升级内核开启BBR过程
先升级软件最新 yum update -y 然后导入 elrepo 软件源的 key 并安装 rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm 安装最新内核 yum -y --enablerepo=elrepo-kernel install kernel-ml-devel kernel-ml
jcjyxjs
2021/09/04
4490
linux-kernel(内核)升级,降级与使用
大家好,又见面了,我是你们的朋友全栈君。 1,查看当前linux内核版本命令 [root@ ~]uname -a Linux critical-drum-1.localdomain 4.12.10-1.el7.elrepo.x86_64 #1 SMP Wed Aug 30 13:00:07 EDT 2017 x86_64 x86_64 x86_64 GNU/Linux [root@ ~]uname -r 4.12.10-1.el7.elrepo.x86_64 [root@ ~]cat /etc/re
全栈程序员站长
2022/08/09
2.4K0
CentOS7 升级最新内核
yum 方式升级到最新版 导入 elrepo 仓库 rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org yum install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm 列出可用的内核相关包 # kernel-lt:长期支持版本,用于修复旧版内核的 BUG,这些内核只会修复重大 BUG,并且不会频繁发布版本。 # kernel-ml:最新稳定版本 yum --d
陳斯托洛夫斯記
2022/10/27
2.4K0
CentOS7 升级最新内核
CentOS7安装新版内核和开启BBR加速
uname命令用于打印当前系统相关信息(内核版本号、硬件架构、主机名称和操作系统类型等)。
4O4
2022/07/12
9.2K0
CentOS7安装新版内核和开启BBR加速
Centos 7 升级系统内核
我们使用 Linux 来表示整个操作系统,但严格地来说,Linux 只是个内核。各种发行版(RedHat、ubuntu、CentOS等)是一个完整功能的系统,它建立在内核之上,具有各种各样的应用程序工具和库。
玖柒的小窝
2021/12/09
1.5K0
Centos7升级内核
1.首先去清华的TUNA或者中科大的USTC的elrepo下载适合自己的内核rpm包,我的是64位的,地址如下:
缘、妙不可言
2019/09/09
2.1K0
CentOS 上开启 BBR 加速
BBR 算法需要 Linux 4.9 及以上的内核支持,所以想要使用该方式的需要先升级内核版本。
老马
2018/07/31
1.3K0
聊一聊CentOS 7升级内核方案
CentOS 7自带的内核版本还停留在3.x,如果某些软件对Linux内核版本有要求,就不得不升级内核来支持,比如Google的BBR加速,要求Linux内核大于4.9以上,这篇文章来聊一聊CentOS 7内核升级的话题。
星哥玩云
2022/08/13
2.8K0
聊一聊CentOS 7升级内核方案
相关推荐
Centos7升级内核至5.4
更多 >
LV.0
这个人很懒,什么都没有留下~
目录
  • 摘要
    • 1.合成流水线
    • 2. 预定义UI层
    • 3. paint是什么意思
    • 4. 分层的优势和劣势
    • 5. 视图属性及其处理方式
    • 6. Quads
    • 7. Compositor Frame
    • 8. 关于光栅化以及渲染方式
    • 9.【重要】软件渲染和硬件渲染的区别
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档