How to draw for GLKit OpenGL ES context asynchronously from Grand Central Dispatch Queue on iOS

I am trying to move long OpenGL drawing operations into a GCD queue so that I can get other things when the GPU is grinding. I would prefer to do this with GCD and adding real threads to my application. Literally all I want to do is

  • Do not block the glDrawArrays () call, so the rest of the user interface may remain responsive when GL rendering becomes very slow.
  • Drop glDrawArrays () calls when we don’t finish them (don’t create a frame queue that just grows and grows)

On the Apple website, the docs say:

GCD and NSOperationQueue objects can do your tasks in a thread of your choice. They can create a stream specifically for this task or can reuse an existing stream. But in any case, you cannot guarantee which thread is performing the task. For an OpenGL ES application, this means:

  • Each task must establish a context before executing any OpenGL ES commands.
  • Two tasks that access the same context may never be performed at the same time.
  • Each task must clear the thread context before exiting.

That sounds pretty simple.

Apple , " " "OpenGL ES". , , , .

GCD. ViewController.m:

dispatch_queue_t openGLESDrawQueue;

ViewController viewDidLoad:

openGLESDrawQueue = dispatch_queue_create("GLDRAWINGQUEUE", NULL);

, drawInRect, CADisplayLink:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
void (^glDrawBlock)(void) = ^{
    [EAGLContext setCurrentContext:self.context];
    glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindVertexArrayOES(_vertexArray);

    // Render the object with GLKit
    [self.effect prepareToDraw];

    glDrawArrays(GL_TRIANGLES, 0, 36);

    // Render the object again with ES2
    glUseProgram(_program);

    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);

    glDrawArrays(GL_TRIANGLES, 0, 36);
};
dispatch_async(openGLESDrawQueue, glDrawBlock);
}

. . dispatch_sync() .

Apple:

  • OpenGL ES.
    • Ok. . Objective-C , , , . , , . , dispatch_sync, . .
  • , , .
    • , GL , - , , , . , - . , synchronized(self.context){}, . , , , , ( NSLog(), ), . , , GLKit, , , . , , synchronized() , OpenGL Profiler .
  • .

:

dispatch_async(openGLESContextQueue, ^{
    [EAGLContext setCurrentContext:context];        
    GLfloat currentModelViewMatrix[9];
    [self convert3DTransform:&currentCalculatedMatrix to3x3Matrix:currentModelViewMatrix];
    CATransform3D inverseMatrix = CATransform3DInvert(currentCalculatedMatrix);
    GLfloat inverseModelViewMatrix[9];
    [self convert3DTransform:&inverseMatrix to3x3Matrix:inverseModelViewMatrix];

    GLfloat currentTranslation[3];
    currentTranslation[0] = accumulatedModelTranslation[0];
    currentTranslation[1] = accumulatedModelTranslation[1];
    currentTranslation[2] = accumulatedModelTranslation[2];

    GLfloat currentScaleFactor = currentModelScaleFactor;

    [self precalculateAOLookupTextureForInverseMatrix:inverseModelViewMatrix];
    [self renderDepthTextureForModelViewMatrix:currentModelViewMatrix translation:currentTranslation scale:currentScaleFactor];
    [self renderRaytracedSceneForModelViewMatrix:currentModelViewMatrix inverseMatrix:inverseModelViewMatrix translation:currentTranslation scale:currentScaleFactor];

    const GLenum discards[]  = {GL_DEPTH_ATTACHMENT};
    glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards);

    [self presentRenderBuffer];

    dispatch_semaphore_signal(frameRenderingSemaphore);
});

, . , , . - , , GL, GCD. , , .

, , GLKit. ( , ) GLKit.

: 1. , GCD OpenGL ES. 2. GLKit GLKViewController GLKView EAGLContext drawInRect. drawInRect , , . 3. , - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect, . : ", CADisplayLink, , , . , . , glDrawArrays. , framebuffer CGImageRef, , . GL. , . , , . , drawStuff, drawRect :

[NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(drawStuff) userInfo:nil repeats:NO];

, glClear 'd , . .

, , , :

. , , OpenGL . glGetError() , , . , , glkView OpenGL . , .

, . :

  • , , , Objective-C .
  • , .
  • getGLError() GL , .
  • dispatch_sync.
  • , drawInRect ivar, NSTimer drawStuff. drawStuff . .

NSTimer , , AFAIK NSTimer runloop. .

- , ?

+4
1

, , borrrden, GLKit presentRenderbuffer: - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect.

, drawStuff . - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect , , 10 , drawInRect:. , 10 , - .

, GLKit . runloop, CADisplayLink runloop, . GLKViewController runloop , , .

GL GL " " .

+5

All Articles