Strange (and new!) openGL multithreaded behavior (Mac)

Started by
-1 comments, last by Raptisoft 10 years, 6 months ago

Hi all,

I have some code that worked last time I used it. I have recently come back to it, and without changing anything at all, it behaves oddly.

First off, it's OpenGL-- loading textures in a secondary thread so that a progress bar can display during load, and so that lower priority graphics can continue to load while the player ponders the menu screens.

Before I attempt to load anything, I call this:


void EnableThreadGraphics()
{
    if (gOpenGLThreading==0)
    {
        CGLError aError=(CGLError)0;
        gOpenGLContext=CGLGetCurrentContext();
        aError=CGLEnable(gOpenGLContext,kCGLCEMPEngine);
        if (aError!=kCGLNoError) printf("*** Enabling Multithreaded OpenGL not supported ***\n");
        else printf("*** OpenGL Multithreading started... ***\n");
        
        CGLContextObj aCurrentContext;
        aCurrentContext=CGLGetCurrentContext();
    }
    gOpenGLThreading++;
    CGLSetCurrentContext(gOpenGLContext);
}

...and that is working correctly. I.E. I get the right message printed out.
That call gets called first in the main thread (meaning gOpenGLThreading is zero then, so it enables the multithreading) and then gets called in the loading thread, at which time it only hits the last two lines, since it's not the first enabling.

Late, I call, simply:


	GLuint aTexture;
	glGenTextures(1,&aTexture);

...and glGenTextures crashes *exactly* as it would if I had not enabled the openGL context.

(A further note: Yes, I am thread locking with GLLockContext during draws and other concurrent operations, to make sure they don't step on eachother's toes)

Fiddling around, I found that if I put this:


CGLGetCurrentContext();

...right before glGenTextures, it will not crash, but all my textures come in pure white.

Can anyone shed any light on this? I'm tearing my hair out here, especially since this code worked just fine, exact same code, a month and a half ago. No idea what the difference is here.

Thanks!

Advertisement

What is CGLEnable(gOpenGLContext,kCGLCEMPEngine); doing, or supposed to do? You enable a feature with the GL enumeration constant equal to the current context handle? Or something? What's that supposed to do?

Also, you seem to use only a single context which you make current in your loader thread. This does not make much sense, and it is probably the reason for the crash, too. To parallelize loading textures, you either only do OpenGL calls from one thread and do the disk work and shuffling data into buffer objects in another thread (passing mapped buffer object pointers between threads, never any actual OpenGL object!), or you use two shared contexts, one bound to each thread.

You will never want to do anything else, because not only will it not be running concurrently (even though adding complexity due to multithreading) but also because it will likely end up with one thread calling an OpenGL function without a valid context at some point.

This topic is closed to new replies.

Advertisement