OpenGL 上下文
OpenGL 的上下文(OpenGL context)是一个 OpenGL 绘图环境的抽象概念,它包括了所有 OpenGL 状态信息和资源,以便OpenGL能够正确地渲染图形。
OpenGL 在渲染的时候需要一个 Context 来记录了 OpenGL 渲染需要的所有信息和状态,可以把它理解成一个大的结构体,它里面记录了当前使用 OpenGL 函数调用设置的状态和状态属性。
OpenGL 是个状态机,OpenGL采用了客户端-服务器模式,我们可以认为每一个硬件 GPU 相当于一台服务器,可对应多个客户端即上下文,一个客户端维护着一组状态机。
大部分的 OpenGL 命令都是异步的,不代表真正地执行,只是客户端向服务器发送了一些命令(同时有一些API可实现同步功能)。
申请绘制上下文,意味着系统资源的申请,每个绘制上下文还是需要不少资源的,所有的OpenGL 调用,都需要指定是在哪个上下文环境下调用的。
渲染上下文和线程
OpenGL 的绘制命令都是作用在当前的 Context 上,上下文是线程私有的,可以为同一个线程创建多个上下文,但是一次只能指定一个。
多个线程不能同时指定同一个 Context ,否则会导致崩溃。当有需要多个并行的绘制任务时,则要创建多个 Context,为并行的线程分别绑定不同的上下文。
可以通过共享上下文的方式为别的线程创建上下文,这些线程之间可以共享一部分资源。
共享上下文
一个是进程可以创建多个 Context,它们可以分别描绘出不同的图形界面,就像一个应用程序可以打开多个窗口一样。每个 OpenGL Context 是相互独立的,它们都有自己的 OpenGL 对象集。
但有时会有场景需要多个上下文使用同一份纹理资源的情况,创建 Context,意味着系统资源的占用,同一份纹理重复申请会造成资源浪费,因此 OpenGL 上下文允许共享一部分资源。
大部分 OpenGL Objects 是可以共享的,包括 Sync Object 和 GLSL Objects。
Container Objects 和 Query Objects 是不能共享的。例如纹理、shader、Buffer 等资源是可以共享的,但 Frame Buffer Object (FBO)、Vertex Array Object(VAO)等容器对象不可共享,但可将共享的纹理和 VBO 绑定到各自上下文的容器对象上。
可以共享的资源:
- 纹理;
- shader;
- program 着色器程序;
- buffer 类对象,如 VBO、 EBO、 RBO 等 。
不可以共享的资源:
- FBO 帧缓冲区对象(不属于 buffer 类);
- VAO 顶点数组对象(不属于 buffer 类)。
这里解释下,在不可以共享的资源中,FBO 和 VAO 属于资源管理型对象,FBO 负责管理几种缓冲区,本身不占用资源,VAO 负责管理 VBO 或 EBO ,本身也不占用资源。
参考文章
https://blog.csdn.net/shenyi0_0/article/details/109382509
https://www.cnblogs.com/liuwq/p/5444641.html
OpenGL ES 共享上下文实现多线程渲染
-- END --