Siarhei Fedartsou
Siarhei Fedartsou

Reputation: 1873

Is it ok to create EAGLContext for each thread?

I want to do some work in my OpenGL ES project in concurrent GCD queues. Is it ok if to create EAGLContext for each thread? I'm going to do it with such way:

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];
    }

});

If it is not correct what is the best practice to parallelize OpenGL rendering?

Upvotes: 2

Views: 1102

Answers (1)

Andon M. Coleman
Andon M. Coleman

Reputation: 43319

Not only is it okay, this is the only way you can share OpenGL resources between multiple threads. Note that shareable resources are typically limited to resources that allocate memory (e.g. buffer objects, textures, shaders). They do not include objects that merely store state (e.g. the global state machine, Framebuffer Objects or Vertex Array Objects). But if you are considering modifying data that you are using for rendering, I would strongly advise against this.

Whenever GL has a command in the pipeline that has not finished, any attempt to modify a resource used by that command will block until the command finishes. A better solution would be to double-buffer your resources, have a copy you use for rendering and a separate copy you use for updating. When you finish updating, the next time your drawing thread uses that resource, have it swap the buffers used for updating and drawing. This will reduce the amount of time the driver has to synchronize your worker threads with the drawing thread.

Now, if you are suggesting here that you want to draw from multiple threads, then you should re-think your strategy. OpenGL generally does not benefit from issuing draw commands from multiple threads, it just creates a synchronization nightmare. Multi-threading is useful mostly for controlling VSYNC on multiple windows (probably not something you will ever encounter in ES) or streaming resource data in the background.

Upvotes: 2

Related Questions