Chromium GPU资源共享
资源共享指的是在一个 Context 中的创建的 Texture 资源可以被其他 Context 所使用。一般来讲只有相同 share group
Context 创建的 Texture 才可以被共享,而 Chromium 设计了一套允许不同 share group
并且跨进程的 Texture 共享机制。
Chromium 中有新旧两套共享 Texture 的机制,一套是 Mailbox 机制,一套是 SharedImage 机制。
1. Mailbox 机制
Mailbox 机制由 CHROMIUM_texture_mailbox
扩展提供,它定义了一种在不同Context之间共享 Texture 对象中的图片数据的方式,不管这些Context是否处于相同的share group
。
它定义了2个方法:
glProduceTextureDirectCHROMIUM
方法传入一个当前Context中已经存在的 texture
对象,然后返回一个指向该texture的 mailbox
。后续可以在其他的Context中使用 glCreateAndConsumeTextureCHROMIUM
方法通过这个 mailbox
创建一个新的 texture
对象,新对象存在于新的 Context 中。结合 Command Buffer,可以实现跨进程共享Texture的效果。
Mailbox
类本身是一个定长的字节数组,作为资源的唯一标识符,默认是16字节,系统全局唯一,可以跨进程。
Mailbox 机制使用起来非常方便,但是它对 service 端的运行环境依赖非常严重,比如要求 service 端的所有 Context 都必须属于相同 share group,这导致service端在某些平台上需要使用Virtual Context或者很多的同步机制才能实现,而这些会导致性能损失。再加上这种机制基于GL,无法很好的支持Vulkan,因此 Mailbox 机制已经被标记为 deprecated
,在当前的 Chromium 中只有 media 模块还在使用。新代码应该使用 SharedImage
机制。
2. SharedImage 机制
ShareImage 机制从2018年开始引入,设计用来取代 Mailbox 机制并且支持 Vulkan。它引入了一套 client 端的 SharedImage 接口以及一个新的GL扩展 CHROMIUM_shared_image
。
主要接口为 SharedImageInterface
,用来创建 shared images,定义如下:
这是一个 client 端的接口,可以通过 gpu::GpuChannelHost
来获取到。对它的调用会通过 IPC 接口发送到 service 端,service 端会使用合适的机制来存储 SharedImage 的数据,比如GL Texture,GMB(GpuMemoryBuffer)等。
CreateSharedImage
方法创建一个新的 SharedImage 并返回一个 mailbox 指向它。UpdateSharedImage
方法更新指定的 SharedImage 的属性。DestroySharedImage
销毁指定的 SharedImage,释放相关内存。
在client端,通过 CHROMIUM_shared_image
扩展提供的方法来读写 SharedImage 数据。Mailbox
机制中 CHROMIUM_texture_mailbox
扩展提供的方法也可以用来访问 SharedImage
,因为 SharedImage
机制兼容了 Mailbox
机制。但应该尽量比避免这样使用,因为 Mailbox 机制已经过时了。在 service 端也可以用这种方法来访问 ShareImage。
在servcie端,SharedImage
实现了大概3类存储机制,分别为 GLTexture/EGLImage,GMB 和 VulkanImage,这三大类又被抽象为了很多种小类。下面这些都是 SharedImage
可能的存储后端:
其中 gpu::SharedImageBackingGLTexture
使用 GL Texture 来存储 SharedImage 数据。gpu::SharedImageBackingEglImage
使用 EGLImage 来存储数据。gpu::SharedImageBackingAHB
仅用于 Android 平台,使用 Android 提供的 AHardwareBuffer 来存储数据。gpu::ExternalVkImageBacking
对接 Vulkan。gpu::SharedImageBackingGLImage
比较特殊,它表示使用 gpu::GLImage
类来进行存储,gpu::GLImage
又抽象了不同的存储后端,最终也可能使用 GL Texture。
SharedImage 机制本质上抽象了 GPU 的数据存储能力。即允许应用直接把数据存储到 GPU (GPU 能访问到的内存)中,以及直接从 GPU 中读取数据,并且允许跨过shared group
边界。理解了这一点,应该比较容易想到哪些场景可以使用 SharedImage 机制,下面这些是 Chromium 中使用 SharedImage 机制的一些场景:
- CC模块: 先将画面 Raster 到 SharedImage,然后再发送给 Viz 进行合成。
- OffscreenCanvas: 先将 Canvas 的内容 Raster 到 SharedImage,然后再发送给 Viz 进行合成。
- 图片处理/渲染: 一个线程将图片解码到 GPU 中,另一个线程使用 GPU 来修改或者渲染图片。
- 视频播放: 一个线程将视频解码到 GPU 中,另一个线程来渲染。
下面介绍2个操作 ShareImage 的扩展。需要注意的是在使用这些扩展方法之前都先要有一个指向 SharedImage 的 mailbox,可以使用 SharedImageInterface
接口创建,也可以是从其他地方传过来。
4. CHROMIUM_shared_image 扩展
CHROMIUM_SHARED_IMAGE 扩展定义了以下4个方法:
glCreateAndTexStorage2DSharedImageCHROMIUM*
方法根据传入的 mailbox
创建一个新的 Texture 对象。然后应用可以使用 glBeginSharedImageAccessDirectCHROMIUM
方法获取读/写 texture
对象的权限,然后使用常规的读写texture的GL命令访问texture的内容,比如glGetTexImage
,glReadPixels
,glTexImage2D
等或者使用skia来间接访问texture的内容。操作结束之后,调用 glEndSharedImageAccessDirectCHROMIUM
方法释放权限。
这些接口用于 GPU-R
机制下的 Raster,这种 Raster 机制已经被 OOP-R
Raster 机制替代,并且在2022年2月份被移除,这里只用于演示旧版本 GPU-R
方式的 Raster:
5. CHROMIUM_raster_transport
glBeginRasterCHROMIUM
方法表示要开始执行 Raster 操作了,Raster的结果存放到传入的 mailbox
对应的 SharedImage 中。glRasterCHROMIUM
将 cc::DisplayItemList
序列化后发送到service端。参数raster_shm_id
指向存储 cc::DisplayItemList
序列化数据的共享内存。glEndRasterCHROMIUM
结束 Raster 操作。
这些接口用于 OOP-R(Out-Of-Process Raster)
机制下的 Raster。关于 OOP-R 见后续文档, 下面的代码演示使用 OOP-R 接口创建 SharedImage:
6. SharedImage 架构设计
SharedImage 被设计用于多进程架构,Client 端可以有多个,比如 Browser/Render/Gpu 进程都可以作为 Client 端,Service 端只能有一个,它运行在 Gpu 进程中。Client 和 Servcie 通过 IPC 进行通信。Client 端的接口主要包括 SharedImageInterface 和 2 个扩展。Service 端将数据存储在基于不同技术实现的 SharedImageBacking 中。
7. SharedImage 实现原理
8. 总结
在当前的 Chromium 中,Mailbox 机制是建立在 SharedImage 机制之上的。旧的 Mailbox 机制的接口正在被废弃(Mailbox 类本身并不会被废弃),在新的代码中应该使用新的 SharedImage 接口。
在所有需要“分阶段”渲染的场合都可以使用 SharedImage 机制,在需要从 GPU 读取数据的场合也可以使用 SharedImage 机制。SharedImage 机制只提供内存的管理,应用可以使用常规的读写GPU数据的方式来读写SharedImage中的数据。
9. 参考文献
Chromium GPU资源共享的更多相关文章
- QtWebEngine性能问题
目录 1. 概述 2. 详论 2.1. 图形属性设置 2.2. 硬件加速设置 2.3. Qt6 3. 参考 1. 概述 Qt的Qt WebEngine模块是基于Chromium项目,但是本人在使用QW ...
- Chromium的GPU进程启动流程
转载请注明出处:http://www.cnblogs.com/fangkm/p/3960327.html 硬件渲染依赖计算机的GPU,GPU种类繁多,兼容这么多种类的硬件,稳定性是个大问题,虽然Chr ...
- 【Chromium】GPU进程启动流程
本篇文档以gpu进程的创建和启动为例,讲述chormium如何启动一个browser进程的子进程 PS:本文使用的chromium代码版本为71 前言 GPU进程的启动时机是由browser进程负责的 ...
- Chromium Graphics : GPU Accelerated Compositing in Chrome
GPU Accelerated Compositing in Chrome Tom Wiltzius, Vangelis Kokkevis & the Chrome Graphics team ...
- chromium for android GPU进程结构分析
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/jaylinzhou/article/details/27517471 GPU进程的client(Br ...
- Chromium硬件加速渲染的UI合成过程分析
在Chromium中.Render端和WebGL端绘制出来的UI终于是通过Browser端显示在屏幕上的.换句话说.就是Browser端负责合成Render端和WebGL端的UI.这涉及到不同Open ...
- Chromium Graphics: Android L平台上WebView的变化及其对浏览器厂商的影响分析
原创文章.转载请以链接形式注明原始出处为http://blog.csdn.net/hongbomin/article/details/40799167. 摘要:Google近期公布的Android L ...
- CSS动画与GPU
写在前面 满世界的动画性能优化技巧,例如: 只允许改变transform.opacity,其它属性不要动,避免重新计算布局(reflow) 对动画元素应用transform: translate3d( ...
- 浏览器-02 Chromium的多线程
Chromium 的多线程机制 概述 每个进程都有很多的线程; 多线程主要是为了保证UI线程(chrome 线程,主线程)不会被任何其它费时的操作阻碍而影响对用户的响应; 为了解决多线程通信和同步问题 ...
- Debugging Chromium on Windows
转自:https://www.chromium.org/developers/how-tos/debugging-on-windows For Developers > How-Tos & ...
随机推荐
- Nacos服务发现与注册源码剖析
为什么要看源码: 1.提升技术功底:学习源码里的优秀设计思想,比如一些疑难问题的解决思路,还有一些优秀的设计模式,整体提升自己的技术功底2.深度掌握技术框架:源码看多了,对于一个新技术或框架的掌握速度 ...
- Java使用qq邮箱发送邮件(可做验证码使用)
pom.xml中导入发邮件需要的jar包 <!-- 邮箱 --> <dependency> <groupId>javax.mail</groupId> ...
- Vue-Element UI 文件上传与下载
项目结构 后端 前端 效果演示 上传文件 下载文件 Code 后端代码 跨域 /** * 跨域配置 * @author Louis * @date Jan 12, 2019 */ @Configura ...
- selenium 根据期刊信息获取知网文献信息 pt.1
哈喽大家好,我是咸鱼 之前写过一篇获取知网文献信息的文章(关于<爬取知网文献信息>中代码的一些优化),看了下后台数据还挺不错 所以咸鱼决定再写一篇知网文献信息爬取的文章 需要注意的是文章只 ...
- 如何在 Windows Server 2022 阿里云服务器上搭建自己的 MQTT 服务器。
一.简介 最近,在做一个项目的时候,需要在线管理网络继电器,以前也做过硬件的项目,但是这样的项目不多.现在我想实现一个在线可以接受网络继电器发送的信号,也可以向网络继电器发送命令,控制其的运行.这个功 ...
- Python安装time库失败?不是吧阿sir你还不知道内置模块不用下载吧
嗨嗨,今天给python安装time库,一直报错,换源等办法都试过了 直到我看到 Python中有以下常用模块不用单独安装 random模块 sys模块 time模块 os系统操作 re正则操作 js ...
- Mysql基础5-用户及权限管理
一.介绍 DCL:Data Control Language(数据控制语言),用来管理数据库用户,控制数据库的访问,权限. 二.用户管理 1.查询用户 语法: 1.use mysql; 2.selec ...
- linux内核vmlinux的编译过程之 --- $(kallsyms.o)详解(九)
在编译完依赖 vmlinux.o 后,链接 vmlinux 之前,构建系统还要编译依赖目标 $(kallsyms.o).接下来就对 kallsyms 进行一个简单的解释. 一. 引言 1.符号的概念 ...
- IIC总线学习笔记
IIC(Inter-Integrated Circuit)其实是IICBus简称,所以中文应该叫集成电路总线,它是一种串行通信总线,使用多主从架构,由飞利浦公司在1980年代为了让主板.嵌入式系统或手 ...
- Spring Secriuty登录失败错误状态999重定向302
原因是login.html登录页面有不能加载的静态资源,找出来去掉就好了,比如 bootstrap.min.css 环境 使用Spring Boot Security 3做一个登录功能,使用了一个教程 ...