Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 为每个线程创建EAGLContext可以吗?_Ios_Objective C_Opengl Es_Opengl Es 2.0_Grand Central Dispatch - Fatal编程技术网

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

Ios 为每个线程创建EAGLContext可以吗?,ios,objective-c,opengl-es,opengl-es-2.0,grand-central-dispatch,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] threadDictiona

我想在并发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渲染的最佳实践是什么?

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

只要GL在管道中有一个尚未完成的命令,修改该命令使用的资源的任何尝试都将被阻止,直到该命令完成。更好的解决方案是将资源缓冲区加倍,使用一个副本进行渲染,使用另一个副本进行更新。完成更新后,下次图形线程使用该资源时,请让它交换用于更新和绘制的缓冲区。这将减少驱动程序将工作线程与绘图线程同步的时间


现在,如果您在这里建议您要从多个线程中提取,那么您应该重新考虑您的策略。OpenGL通常不会从多线程发出draw命令中获益,它只是创建了一个同步噩梦。多线程主要用于在多个窗口上控制VSYNC(可能不是在ES中遇到的)或在后台流式处理资源数据。

我只将后台用于纹理加载。但我希望在并发队列中执行此操作(一次加载多个纹理)。这个案子可以吗?EagleContext是否有一些内存开销?我可以创建任意数量的EAGLContexts吗?最后一个问题是具体实现的,但我怀疑您是否能够创建足够的上下文,以在任何合理编写的软件中达到任何限制。至于其他两个,如果您创建共享上下文,那么它们将共享相同的纹理内存。如果您所做的只是在其他线程中加载新纹理,那么这是多线程中共享上下文的一个很好的用例。如果您试图更新已用于绘制内容的纹理中的数据,则会创建隐式驱动程序同步源,这可能会影响性能。实际上,如果多个纹理从同一设备加载(即同一闪存、同一硬盘驱动器等)您可能看不到多个后台线程同时加载它们的好处,因为在对单个设备执行I/O操作时,它们最终将序列化。如果您正在进行某种CPU密集型后处理,可能会有一些好处,但如果多个并发后台加载的性能优于单个后台线程上多个纹理的串行加载,我会感到惊讶。@ipmcc:我怀疑嵌入式设备上您是否有空闲时间存储未压缩的资源。通常,这就是您选择多线程的原因-磁盘I/O的竞争肯定会由操作系统安排(在这种情况下希望是FCFS),但在一个线程等待I/O完成的过程中,另一个线程可能正忙于解压缩刚刚完成读取的资源。尽管如此,如果平台本机支持KTX或PVR压缩纹理图像,您肯定可以避免所有这些废话,并将压缩图像直接流式传输到GL。解压缩可能符合“CPU密集型后处理”的要求,但任务调度涉及到非零开销,而且解压需要比开销更多的时间才能成功。如果您真的想优化,您可以序列化读取并并行化解压缩。不管怎样,总是要测量。你不能改进你没有衡量的东西。