首页 > 其他分享 >Chromium Command Buffer原理解析

Chromium Command Buffer原理解析

时间:2023-10-26 17:45:09浏览次数:42  
标签:序列化 命令 Buffer buffer Command GL Chromium

Command Buffer 是支撑 Chromium 多进程硬件加速渲染的核心技术之一。它基于 OpenGLES2.0 定义了一套序列化协议,这套协议规定了所有 OpenGLES2.0 命令的序列化格式,使得应用对 OpenGL 的调用可以被缓存并传输到其他的进程中去执行(GPU进程),从而实现多个进程配合的渲染机制。

1. Command Buffer 命令的序列化

在 CommandBuffer 中共有三类命令,一类是直接对接OpenGLES的命令。例如下面的GL命令:

 

 他们的序列化格式定义为:

可以看到序列化的方式并不复杂,每个命令都有个 CommandId 和 header。header 占用 32 位,高 21 位表示当前命令的长度,低 11 位表示命令的 Id。其他字段表示命令的参数。

第二类命令是 CommandBuffer 自己需要用到的,这类命令称为公共命令(common command,Id<256),比如下面这两个:

这两个命令一个用于创建Bucket,一个用于向Bucket中放数据(关于Bucket后面会讲到)。他们都不是 OpenGL 定义的命令,是 CommandBuffer 为了自己的某种用途而添加的命令。

最后一种命令如下:

 可以看到 CommandBuffer 针对 glShaderSource 命令定义了不同的序列化格式,没有一种是按照原本的参数来定义的,这主要是因为 glShaderSource 命令可能会传输比较大的数据(第3个参数),如果直接把数据通过 IPC 传输可能会比较低效,因此方法1将数据存放在了共享内存,然后在命令中保留了对共享内存的引用,方法2是将数据保存在 Bucket,然后在命令中引用了 Bucket。这种处理方式主要是针对那些需要传输大批量数据的GL命令。

2. Command Buffer 命令的自动生成

Command Buffer 提供了三种 GL Context,分别时 GLES Context,Raster Context,WebGPU Context,它们用于不同的目的。GLES Context 用于常规的绘制,Raster Context 用于 Raster,WebGPU Context 用于 WebGPU。

在 gpu/command_buffer/gles2_cmd_buffer_functions.txt 文件中定义了 GLES Context 使用到的 GL 命令,包括 150 多个 OpenGLES2.0 命令,以及由 19 个扩展提供的 230 多个扩展命令,在编译过程中 gpu/command_buffer/build_gles2_cmd_buffer.py 脚本会读取该文件并生成相应的 *_autogen.* 文件。

在 gpu/command_buffer/raster_cmd_buffer_functions.txt 文件中定义了 Raster Context 使用到的 30 多个 GL 命令,它被 gpu/command_buffer/build_raster_cmd_buffer.py 脚本使用来生成相应的 *_autogen.* 文件。

用于 WebGPU Context 的命令定义在 gpu/command_buffer/webgpu_cmd_buffer_functions.txt 中,被脚本 gpu/command_buffer/build_webgpu_cmd_buffer.py 用来生成相关代码。

Command Buffer 通过这些自动生成的代码包装了所有的 GL 调用,然后将这些调用序列化后发送到 GPU 进程去执行。

3. Command Buffer 的架构设计

前面已经提到,Command Buffer 主要是为了解决多进程的渲染问题,因此它在设计上分两个端,分别是 client 端和 service 端。下图反映了 Chromium 中各种进程和 Command Buffer 中两个端的对应关系:

 

可以看到,Browser和Render进程都是 client 端, GPU 进程是 service 端。client 端负责调用 GL 命令来产生绘制操作,但是这些GL命令并不会真正执行而是被序列化为 Command Buffer 命令,然后通过 IPC 传输到 GPU 进程,GPU 进程负责反序列化 Command Buffer 命令并最终执行 GL 调用。

在 Chromium 的实现中,引入了更多的概念:

  • 每个client端和server端之间都通过 IPC channel (IPC::Channel) 通道进行连接。
  • 每个 IPC channel 可以有多个调度组(scheduling groups),每个调度组称为一个 stream,每个 stream 有自己的调度优先级。
  • 每个 stream 可以承载多个 command buffer
  • 每个 command buffer 都对应一个 GL context,在相同stream中的GL Context都属于同一个share group
  • 每个 command buffer 都包含一系列的 GL 命令。

下图反映了 context,commandbuffer,stream,channel 之间的关系:

 下面是 Command Buffer 的模块依赖关系:

 content 模块通过调用 GL 或者 Skia 来产生 GL 命令, 然后 Command Buffer client 将这些 GL 命令序列化,然后通过 IPC 传输到了 Command Buffer service 端,service 将命令反序列化然后调用 ui/gl 模块执行真正的 GL 调用。

4. Command Buffer 命令的传输方式

Command Buffer 定义了三种命令传输方式:

  1. 命令和命令涉及到的数据都直接放在 Command Buffer 中传输,在多进程模式下 Command Buffer 本身位于共享内存中;
  2. 命令放在 Command Buffer 中,数据放在共享内存中,在命令中引用该共享内存;
  3. 先使用 SetBucketSize 命令在 service 进程中创建一个足够大的 Bucket,然后将数据的一部分放在共享内存中,然后使用 SetBucketData 命令将该共享内存中的数据放到 service 进程的 Bucket 中,然后再放一部分数据到共享内存,再使用 SetBucketData 命令将数据传输到 service 进程中,循环这个操作直到将所有的数据都放到 service 进程中,最后调用原本的 GL 命令并引用这个 Bucket 的 Id 。Bucket 机制主要用在共享内存不足以存放所有要传输的数据的时候。由于涉及到多次数据从共享内存拷贝到进程空间的操作,因此性能较低。

5. Command Buffer 的具体实现

 6. 总结

Command Buffer 可以用于实现多进程的渲染架构,并且提供全平台支持。可以通过设置 is_component_build=true 来将 Command Buffer 模块编译为动态链接库,从而嵌入到自己的项目中。例如,Skia 项目就提供了对 Command Buffer 的。

7. 参考文献

 

标签:序列化,命令,Buffer,buffer,Command,GL,Chromium
From: https://www.cnblogs.com/rmb999/p/17789913.html

相关文章

  • String和StringBuffer的区别
    String和StringBuffer是Java中两种用于处理字符串的不同类,它们之间有一些重要的区别。 可变性:String 是不可变的(immutable):一旦创建了一个 String 对象,就不能更改它的内容。每次对 String 进行修改操作(例如拼接字符串),都会创建一个新的 String 对象。这可能会导致......
  • 如何在 Wget 中使用 Command Line Arguments 设置代理
    在使用Wget这个命令行工具进行文件下载时,有时我们需要通过代理服务器来进行网络连接。Wget提供了一些命令行参数,可以让我们设置代理服务器的信息。下面是如何在Wget中使用CommandLineArguments设置代理的步骤。首先,我们需要打开终端或命令提示符窗口,并进入到Wget的安装......
  • 数据序列化协议 Protocol Buffers(Protobuf) 认知
    写在前面需要存大数据,同事推荐,了解一下理解不足小伙伴帮忙指正对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是对大众理想的懦弱回归,是随波逐流,是对内心的恐惧——赫尔曼·黑塞《德米安》ProtocolBuf......
  • Total Commander使用技巧
    <1>常用的快捷键1.选中文件文件夹后拖放就是复制2.拖放的同时按住shift是移动3.shift+ctrl+拖放是建立快捷方式4.F4编辑文本文件5.shift+F4新建文本文件6.F7新建文件夹7.alt+↓历史文件列表,ctrl+D常用文件列表8.alt+Enter:查看文件属性9.支持多标签浏览ctrl+T新建标签......
  • 【图形学笔记】Lecture02&03 光栅化、抗锯齿、Z-buffer
    目录Lecture02-DigitalDrawing数码绘画Triangles-FundamentalAreaPrimitive三角形——基本区域Rasterization光栅化Sampling采样Lecture03-Sampling,Aliasing,Antialiasing采样、锯齿、抗锯齿Artifactsduetosampling-“Aliasing”采样产生的问题-混叠Antialias......
  • docker-compose: command not found问题的两种常用方法
    docker-compose:commandnotfounddocker-compose是什么Compose定位是「定义和运行多个Docker容器的应用(Definingandrunningmulti-containerDockerapplications)」,其前身是开源项目Fig。在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个......
  • InnoDB 存储引擎之 Buffer Pool
    Mysql5.7InnoDB存储引擎整体逻辑架构图一、BufferPool概述InnoDB作为一个存储引擎,为了降低磁盘IO,提升读写性能,必然有相应的缓冲池机制,这个缓冲池就是BufferPool为了方便理解,对于磁盘上的数据所在的页,叫做数据页,当数据页加载进BufferPool之后,叫做缓存页,......
  • Chromium GPU资源共享
    资源共享指的是在一个Context中的创建的Texture资源可以被其他Context所使用。一般来讲只有相同 sharegroup Context创建的Texture才可以被共享,而Chromium设计了一套允许不同 sharegroup 并且跨进程的Texture共享机制。Chromium中有新旧两套共享Texture的......
  • Top 19 Docker Commands
    Top19DockerCommands有一天我发现了这个有创造力的社区(bytebytego)和这些有创造力的工程师设计的流程图,很惊喜很喜欢,就把他们留存了下来。......
  • [926] Batch Script - Commands
    Inthischapter,wewilllookatsomeofthefrequentlyusedbatchcommands.S.NoCommands&Description1VERThisbatchcommandshowstheversionofMS-DOSyouareusing.2ASSOCThisisabatchcommandthatassociatesanextensionwithaf......