Ricardo Sanchez-Saez
Ricardo Sanchez-Saez

Reputation: 9566

glGetError() doesn't work until next frame

I'm trying to debug this rendering loop that I didn't write. There's an error somewhere that makes the program to crash, but glGetError() seems to be acting funny.

This in on iOS, and I'm using GLKViewController, GLKView and EAGLContext to draw.

A much summarized version of the render loop is something like this:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
   // At this point, GLKView's EAGLContext should be the active context

   checkGlGetError();

   if (!isTextureInit || geometryChanged)
   {
        setupRenderTextureAndRenderbuffer();
   } 
    glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_originalFramebufferId);
    glBindFramebuffer(GL_FRAMEBUFFER, _framebufferId);

    // a. Some complex operations
    // b. Some rendering on the texture framebuffer

    glBindFramebuffer(GL_FRAMEBUFFER, _originalFramebufferId);

    // c. Some additional complex operations
    // d. Render the texture on screen

    checkGlGetError();
}

This makes the app crash. The problem is that the last checkGlGetError() call of the first rendered frame, doesn't produce any error (and nothing shows on the screen).

The first checkGlGetError() call of the second rendered frame gives a cryptic GL_INVALID_ENUM, and shortly thereafter the app crashes.

If I replace my render loop by this:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    checkGlGetError();

    // a. Some complex operations
    // b. Some rendering on the screen

    checkGlGetError();
}

Everything works, and no errors are reported. But: why doesn't glGetError() catches the error immediately after the erroneous OpenGL call? Why does it only report it at the start of the next frame?

The code with the error is quite long, and without any more indications of where exactly the error is, it's being quite difficult to debug.


UPDATE

I uploaded all the code here. It's a work-in-progress port of Google's CardboardSDK (decompiled) from Java to Objective-C++ that I'm trying to complete.

The main render loop is on the CardboardViewController class. The OpenGL command causing the crash should be on the DistortionRenderer class (whose function is to take the plain stereoscopic viewports and render them on a texture, in order to apply the lens distortion to each).

If you set CardboardViewController's distortionCorrectionEnabled to NO, the crash goes away.

Upvotes: 1

Views: 744

Answers (1)

rickster
rickster

Reputation: 126107

There's not enough info in here to debug your problem, so instead, a general note about debugging...

glGetError is a poor way to debug GL issues in general, but especially in iOS, and even more so when you're using GLKView or other systems that do GL work on your behalf. Quite possibly you're setting some state that doesn't lead to an error until GLKView starts committing stuff to the GPU (when your drawRect:/glkView:drawInRect: returns).

Try using the Xcode Frame Capture tool instead. Instead of requiring you to paste glGetError checks all over your code (and make sure they're disabled in release builds) and then try to make sense of the results, it shows you the errors (with at least some level of explanation) for each call, including those made on your behalf in system code. And it shows the complete state graph, and snapshots of the frame being rendered call by call, so you can tell earlier if you're setting some state that's causing a problem.


Okay, one thought that might be specific to your problem: try using bindDrawable on the GLKView instead of directly re-binding its framebuffer with glBindFramebuffer.

Upvotes: 3

Related Questions