Chromium Graphics: 3D上下文及其虚拟化 - Part I

在页面渲染过程中,Chromium需要创建多个3D上下文的实例,这些上下文实例彼此之间不但需要共享资源,并且必须在同一个线程中执行GL操作,这就要求Chromium能够有效地处理多个上下文之间的切换。然而,并不是所有的GPU设备都能够很好的支持多个3D,虚拟化3D上下文(Context Virtualization)就是为了解决多这个问题而引入的,核心思想是通过虚拟化3D上下文,使得多个虚拟的上下文可以共享同一个真实的3D上下文,虚拟上下文的切换并不一定导致真实上下文的切换,从而减少真实上下文的个数,避免不必要的切换。本文介绍OpenGL上下文等基本概念,以及Chromium需要创建多个3D上下文的原因。

OpenGL上下文和渲染表面

OpenGL上下文是对OpenGL运行时渲染状态的抽象。OpenGL运行时的每个实例都可以看做是一台“状态机”,GL命令实际上是在操纵这台状态机,更新其内部的渲染状态。

每个GL命令只会作用于“当前”(current)上下文,而绑定当前上下文的工作则需要通过窗口系统的OpenGL扩展接口完成的,OpenGLAPI本身没有提供这样的接口。不同的窗口系统为支持OpenGL都会定义一套扩展接口标准,例如X11Windows系统的GLX标准,其首要目的就是要定义渲染上下文(renderingcontext),以及如何创建OpenGL上下文和绑定当前上下文。为了存储OpenGL的渲染结果,这些标准还定义了特定于窗口系统的渲染表面(drawingsurface)。一般至少有两种类型的渲染表面可供使用:

  • 屏上(onscreen)渲染表面,具有前后双缓冲区,前缓冲区用于显示,后缓冲区用于GL渲染,执行缓冲区交换(SwapBuffer)可以将在后缓冲区中渲染的内容显示在屏幕的窗口上。窗口系统中每个窗口都可以创建一个与之关联的onscreen渲染表面,将GL的渲染结果显示在这个窗口中。
  • 离屏(offscreen)渲染表面,如PBuffer渲染表面,只有后缓冲区,GL命令只能将内容渲染到后缓冲区,在屏幕上是不可见的, 窗口系统无关的Framebuffer 对象通常会使用这个表面将内容渲染到Texture中。

以EGL为例,标准中定义了eglCreateContext接口用以创建一个封装了OpenGL上下文的EGLContext,然后指定一个与之兼容(具有相同类型和深度的颜色缓冲区)的渲染表面,通过eglMakeCurrent将这个EGLContext和绑定为当前的上下文,拥有一个OpenGL状态机,为GL命令提供执行环境。

Chromium为什么需要多个3D上下文

Chromium图形栈是一个复杂的系统,所解决的问题也很复杂:

  • 普通页面的GPU渲染和加速合成;
  • 对硬件加速Canvas 2D、视频解码以及WebGL的支持;
  • Native Client应用的3D渲染;
  • 将页面的合成工作和浏览器界面的合成工作合二为一;
  • 进程外(out of process)Iframe的独立渲染;

显然,Chromium运行时需要创建多个OpenGL上下文。以Android平台上Chromium渲染一个简单的WebGL页面http://get.webgl.org 为例,在委托渲染器模式(--enable-delegated-renderer)开启的情况下,Chromium至少需要创建两个3D上下文,分别用于browser进程端的合成器(Compositor)和Renderer进程端的WebGL渲染,简单的来说,

  • Browser进程端的Compositor需要通过GPU将浏览器界面元素(例如地址栏等)和页面内容元素(包括普通内容的Tile块,WebGL等,这些元素信息由Renderer进程生成,然后通过IPC以资源的形式转交给Browser进程)进行合成
  • Renderer进程端的WebGL需要执行GL命令并通过Framebuffer对象将内容渲染到Texture(这个Texture会通过Mailbox方式转交给Browser进程用于最终的屏幕合成)

显然,上述两者需要两个独立的OpenGL上下文,而且这两个上下文之间还必须能够共享资源,因为Browser端的Compositor的上下文需要能够直接访问WebGL上下文中用于存放离屏渲染内容的Texture对象,用于最终的合成操作。

从Chromium进程架构来看,出于安全和稳定性的考虑,所有GPU操作都在同一个线程(GPU线程)中执行,并通过应用层的命令缓冲区(CommandBuffer)将GPU操作设计成Client/Server模式,Client端(可能是Browser进程,也可能是Renderer进程)发起GPU操作请求,Server端GPU进程收到请求后向图形驱动器请求执行实际的GL操作。GPU进程收到的GL操作请求可能来自不同进程,这些操作请求都会根据消息到达时间戳按顺序执行(确切地说,是根据IPC消息GpuCommandBufferMsg_OnAsyncFlush送达GPU进程的时间决定的),因此每次执行GL操作之前, GPU进程必须确保已经切换正确的上下文。

这种请求/响应的异步模式,导致GPU线程中3D上下文之间频繁切换,因此 Chromium必须能够准确、有效地处理多个上下文切换的情况。

未完待续...下节将分析为什么Chromium会引入虚拟化上下文(Context Virtualization),敬请关注。

时间: 2024-10-06 01:10:15

Chromium Graphics: 3D上下文及其虚拟化 - Part I的相关文章

Chromium Graphics: 3D上下文及其虚拟化 - Part II

Part I介绍了OpenGL上下文和绘制表面等基本概念,以及Chromium为什么需要多个3D上下文.本文将继续这个话题,探讨Chromium为什么引入虚拟3D上下文,以及虚拟上下文之间切换有何不同. 多个3D上下文的限制 Chromium需要使用多个3D上下文,并且这些上下文能够共享资源.然而,目前图形驱动对多个3D上下文的支持存在不同程度的问题,尤其是在移动设备上,例如(参见http://crbug.com/155557 ): 有些驱动一旦使用多个上下文就会暴露这样或那样的问题: 有些驱动

Chromium Graphics: 再谈Chromium WebView硬件渲染模式的演进

摘要:从Android KitKat系统第一个采用Chromium内核的WebView开始,Android WebView一直在持续演进中,自Chromium M38开始,WebView在硬件渲染模式方面发生了较大的变化,最明显的变化莫过于WebGL的支持以及ubercompositor的使用,同时为了吻合Android L的渲染模型变化,DrawGL函数是在Android系统的渲染线程中执行的. Android 4.4系统WebView的硬件渲染 对于Chromium WebView来说,首先

PPAPI中使用Chromium的3D图形接口

使用PPAPI的Graphics 3D接口做了一个小示例,鼠标点击插件区域,绘制颜色,效果与ppapi_simple类似. foruok原创,如需转载请关注foruok的微信订阅号"程序视界"联系foruok. 项目 项目与VS2013编译最简单的PPAPI插件这篇文章里说的ppapi_simple类似. 附加包含路径有些不同,如下: E:\sources\CEF\2526\chromium\src\ E:\sources\CEF\2526\chromium\src\ppapi\lib

Chromium Graphics: GPU客户端之间同步机制的原理和实现分析-Part I

摘要:Chromium中GPU进程架构导致多个GPU客户端会同时访问GPU服务,而多个GPU客户端可能存在数据依赖关系,例如渲染WebGL页面时,因此需要提供一种同步机制保证GPU操作的先后次序.本文讨论的就是多进程架构下GPU客户端之间的同步问题,以及同步点(SyncPoint)机制的基本原理. GPU进程架构等基本概念 我们知道,Chromium是一个多进程架构的软件系统.出于安全和稳定性方面的考虑,Chromium有个专门的进程(或者线程)和GPU设备进行交互,执行GL操作,也就是说,任何

Chromium Graphics: GPU客户端之间同步机制的原理和实现分析-Part II

摘要:Part I分析了GPU客户端之间存在的同步问题,以及Chromium的GL扩展同步点机制的基本原理.本文将源代码的角度剖析同步点(SyncPoint)机制的实现方式.同步点机制的实现主要涉及到是如何跨进程实现两个GL扩展接口InsertSyncPointCHROMIUM和WaitSyncPointCHROMIUM的实现方式,以及如何实现GPU服务端的同步点等待. GPU客户端 GPU客户端将所有的GL命令都封装在GLES2Implementation中,GLES2Implementati

Chromium Graphics Update in 2014(幻灯片)

摘要:Chromium图形栈在2014年有多项改进,在图形性能和资源消耗方面做了进一步提升,例如ubercompositor的使用,GPU加速的光栅化,零拷贝(zero-copy)的支持,Android WebView的渲染模型改进等.这个幻灯片尝试列举Chromium在图形栈方面一些变化,以及Chromium渲染流水线的总体框架,并对WebGL性能慢于OpenGL原生应用的原因做了一定的推测.

Chromium on Android: Android L平台上WebView的变化及其对浏览器厂商的影响分析

摘要:Android L平台在图形渲染方面有一项重要的改进,它引入了一个专门的线程用于执行渲染工作,UI线程负责生成的显示列表(DisplayList),渲染线程负责重放(playback)这个显示列表绘制最终的内容,因此Chromium WebView在图形栈的实现方面也作了相应的调整,以支持Android L系统上新的渲染线程模型.本文将深度分析Chromium WebView的渲染流水线是如何无缝整合到Android L系统的渲染模型中,以及对目前市场主流浏览器厂商将会产生什么样影响等问题

Chromium插件(Plugin)执行3D渲染的过程分析

Chromium为网页的<embed>标签创建了Plugin之后,Plugin就负责渲染<embed>标签的内容.Chromium为Plugin提供了OpenGL接口,使得Plugin可在网页上渲染3D内容.当然,我们也可通过WebGL接口在网页上渲染3D内容.不过,前者渲染效率会更高些,因为它是Native接口,后者是JavaScript接口.本文接下来就详细分析Plugin执行3D渲染的过程. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注

Chromium插件(Plugin)模块(Module)加载过程分析

在Chromium中,每一个Plugin都对应一个Module,称为Plugin Module.一个Plugin Module可创建多个Plugin Instance.每一个Plugin Instance对应于网页中的一个<embed>标签.在为<embed>标签创建Plugin Instance之前,先要加载其对应的Plugin Module.本文接下来分析Plugin Module的加载过程. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注