可以为每个线程创建EAGLContext吗?

时间:2013-12-18 18:08:46

标签: ios objective-c opengl-es opengl-es-2.0 grand-central-dispatch

我想在并发GCD队列中的OpenGL ES项目中做一些工作。是否可以为每个线程创建EAGLContext?我打算这样做:

queue_ = dispatch_queue_create("test.queue", DISPATCH_QUEUE_CONCURRENT);


    dispatch_async(queue_, ^{
    NSMutableDictionary* threadDictionary = [[NSThread currentThread] threadDictionary];
    EAGLContext* context = threadDictionary[@"context"];
    if (!context) {
        context = /* creating EAGLContext with sharegroup */;
        threadDictionary[@"context"] = context;
    }

    if ([EAGLContext setCurrentContext:context]) {
        // rendering
        [EAGLContext setCurrentContext:nil];
    }

});

如果不正确,并行化OpenGL渲染的最佳做法是什么?

1 个答案:

答案 0 :(得分:1)

不仅可以,这是 唯一 方式,您可以在多个线程之间共享OpenGL资源。请注意,可共享资源通常仅限于分配内存的资源(例如缓冲区对象,纹理,着色器)。它们不包括仅存储状态的对象(例如,全局状态机,帧缓冲对象或顶点阵列对象)。但是,如果您正在考虑修改用于渲染的数据,我强烈建议不要这样做。

每当GL在管道中有一个尚未完成的命令时,任何修改该命令使用的资源的尝试都将阻塞,直到命令完成。更好的解决方案是双重缓冲资源,拥有用于渲染的副本以及用于更新的单独副本。完成更新后,下次绘图线程使用该资源时,让它交换用于更新和绘图的缓冲区。这将减少驱动程序将工作线程与绘图线程同步的时间。

现在,如果您在此建议您想要从多个线程中进行绘制,那么您应该重新考虑您的策略。 OpenGL通常不会从多个线程发出绘图命令中受益,它只会造成同步噩梦。多线程主要用于控制多个窗口上的VSYNC(可能不是您在ES中遇到的东西)或后台流式传输资源数据。