OpenGL 中的共享上下文

OpenGL 渲染中有一个线程相关的上下文 (Context), OpenGL 所创建的资源,其实对程序员可见的仅仅是上下文ID 而已,其内容依赖于这个上下文,有时候为了方便起见,在某个线程中创建了上下文之后,所有的 OpenGL 操作都转到此线程来调用。这样在简单的 2d/3d 渲染中尚可,但是如果涉及复杂的 OpenGL 渲染时,这样就未必足够, 事实上 OpenGL 已经考虑到这一点, 上下文是可以在多个线程间共享的,在使用 glXCreateContexteglCreateContext 时, 可以传入一个已创建成功的上下文, 这样就可以得到一个共享的上下文 (Shared Context).

OpenGL 的绘制命令都是作用在当前的 Context 上,这个 Current Context 是一个线程私有(thread-local)的变量,也就是说如果我们在线程中绘制,那么需要为该线程制定一个 Current Context 的,当多个线程参与绘制任务时,需要原线程解绑再重新绑定新的线程。多个线程不能同时指定同一个 Context 为 Current Context,否则会导致崩溃。

共享上下文

一个是进程可以创建多个 Context,它们可以分别描绘出不同的图形界面,就像一个应用程序可以打开多个窗口一样。每个 OpenGL Context 是相互独立的,它们都有自己的 OpenGL 对象集。但有时会有场景需要多个上下文使用同一份纹理资源的情况,创建 Context,意味着系统资源的占用,同一份纹理重复申请会造成资源浪费,因此 OpenGL 上下文允许共享一部分资源。大部分 OpenGL Objects 是可以共享的,包括 Sync ObjectGLSL ObjectsContainer ObjectsQuery Objects 是不能共享的。例如纹理、shader、Buffer 等资源是可以共享的,但 Frame Buffer Object (FBO)、Vertex Array Object(VAO)等容器对象不可共享,但可将共享的纹理和 VBO 绑定到各自上下文的容器对象上。

  • 共享资源: 纹理shaderBuffer
  • 不共享资源: FBO, VAO

EGL Context

EGLContext eglCreateContext(EGLDisplay display,
  	                        EGLConfig config,
  	                        EGLContext share_context,
  	                        EGLint const * attrib_list);

GLX Context

GLXContext glXCreateContext(Display * dpy,
 	                        XVisualInfo * vis,
 	                        GLXContext shareList,
 	                        Bool direct);

GLX 创建共享上下文:

GLXContext currctx = glXGetCurrentContext();
GLXFBConfig* fb_config;
int fb_config_id;
int nelements;
int res;

XInitThreads();

Display* dpy = XOpenDisplay(NULL);
assert(dpy != NULL)

res = glXQueryContext(dpy, currctx, GLX_FBCONFIG_ID, &fb_config_id);
assert(res);

int visual_attribs[] = {
    GLX_FBCONFIG_ID, fb_config_id,
    None
};
fb_config = glXChooseFBConfig(dpy, DefaultScreen(dpy), visual_attribs, &nelements);
assert(fb_config);

int context_attribs[] = {
    GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
    GLX_CONTEXT_MINOR_VERSION_ARB, 0,
    GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
    None
};
GLXContext glx_share_context = glXCreateContextAttribsARB(dpy, fb_config[0], currctx,
        True, context_attribs);
assert(glx_share_context);

上下文切换

在执行 OpenGL 函数之前,必须将切换到其当前的上下文进行处理

EGL

EGLBoolean eglMakeCurrent(EGLDisplay display,
  	                      EGLSurface draw,
  	                      EGLSurface read,
  	                      EGLContext context);
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, context);

GLX

Bool glXMakeCurrent(Display * dpy,
 	                GLXDrawable drawable,
 	                GLXContext ctx);

参考

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值