摘要:Part I和Part II分别从实现原理的角度介绍了3D上下文和渲染表面等基本概念,阐述了Chromium需要创建多个上下文的内部逻辑,以及如何借助虚拟上下文解决GPU设备对多上下文支持方面的不足之处。Part III将深度解读Chromium源代码是如何抽象多上下文支持及其虚拟化的。
上下文和渲染表面的抽象和实现
先看看Chromium是如何抽象上下文和渲染表面。
Chromium定义了两个C++抽象类:GLContext和GLSurface,分别用来封装OpenGL上下文和可以使用GL命令渲染的表面,这两者都隐藏了平台相关的细节,为所有不同平台操作OpenGL上下文和渲染表面提供了统一的接口规范。此外,GLContext和GLSurface都继承自base::RefCounted<T>模板类,表明这两者的实例都可以启用了引用计数,可以在client代码中可安全的引用它们。
Chromium是一个跨平台的系统,支持Windows,Mac,Linux和Android等系统,相应地,Chromium提供了支持多平台的GLContext和GLSurface具体实现版本,例如用于X11Window系统的GLContextGLX和GLSurfaceGLX,用于MacOS上的GLContextCGL和GLSurfaceCGL,虚拟上下文GLContextVirtual也实现了GLContext。下图给出了GLContext和GLSurface的类层次图:
除了隐藏平台相关的实现细节,GLContext和GLSurface还分别定义创建上下文和渲染表面的工厂方法,并实现在平台相关的源代码文件中,如gl_context_android.cc和gl_surface_android.cc.
创建GLContext的工厂方法
static scoped_refptr<GLContext> CreateGLContext(
GLShareGroup* share_group,
GLSurface* compatible_surface,
GpuPreference gpu_preference);
CreateGLContext从给定的3个参数创建一个GLContext实例,
第一个参数share_group指定了新上下文的共享组,如果不为空,表明这个新创建的上下文将会被添加到这个共享组中,与共享组其他的上下文进行资源的共享。
第二个参数compatible_surface指定了用于初始化GLContext实例的渲染表面,仅当这个渲染表面的配置信息与待创建的GLContext实例兼容时,例如对于EGL来说,兼容的渲染表面要求其颜色缓冲区具有相同的类型和深度,否则创建上下文失败,函数返回空。
第三个参数gpu_preference针对双GPU系统指定了使用集成显卡还是使用独立显卡的偏好,例如为WebGL创建上下文倾向于使用独立显卡。目前只有MacOSX平台会关心这个使用偏好(因为MacPro机器支持双GPU设备切换,当电量不足时用集成显卡,电量状况良好时用独立