Part of the Khronos Group

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: Sharing contexts with GLX for multithreaded app

  1. #1
    Junior Member Newbie
    Join Date
    Nov 2012

    Sharing contexts with GLX for multithreaded app

    Hello everyone.

    I'm programming a flight simulator app and I have data for the whole world.
    Then, there is a lot of textures and geometry to load so I made a background thread that dynamically load all that data depending on my position on Earth.
    Since I'm using SOIL to load my textures, I need to create a 2nd context for that background thread that will share OpenGL data with the main thread's context.

    I use GLX to manage my window and I didn't find any example of this. I just know which functions to use but I'm facing some problems.

    Here's what I do:

    - init XLib thread support
    - create the foreground context
    - create the background context with the foreground one as shareList
    - make the foreground context current for the rendering thread
    - create the loader thread passing a structure containing the Display, the Window and the background context
    - in the loader thread, make the background context current

    It crashes with a segfault on the last step, when I call glXMakeCurrent with the Display, the Window and the thread context...

    I'm doing something wrong but I don't know what and can't find solutions on forums.
    Do you have any idea ?

    Thank you for your help !

    Here's my full code :

    Code :
    Display *dpy;
    Window win;
    GLXContext foregroundCtx, backgroundCtx;
    int32_t main(int32_t argc, char** argv) 
        //init my own stuff (data paths, ini...)
        initVisualSystem(argc, argv);
        //create the window
        //init my openGL stuff and create background thread
        init(dpy, &backgroundCtx, &win, argc, argv);
        event_loop(dpy, win);
        glXDestroyContext(dpy, foregroundCtx);
        glXDestroyContext(dpy, backgroundCtx);
        XDestroyWindow(dpy, win);
        return 0;

    Code :
    void initXDisplay()
        dpy = XOpenDisplay(NULL);
        if (!dpy) 
            cerr << "Error: couldn't open display" << endl;
        uint32_t width = renderer.getView()->getWidth();
        uint32_t height = renderer.getView()->getHeight();
        make_window(dpy, "XN3", 0, 0, width, height, &win, &foregroundCtx, &backgroundCtx);
        XMapWindow(dpy, win);
        [b]glXMakeCurrent(dpy, win, foregroundCtx);[/b]
        if (FULLSCREEN) 
            makeFullscreen(dpy, win);
        hideCursor(dpy, win);
    static void make_window( Display *dpy, const char *name,
                 int x, int y, int width, int height,
                 Window *winRet, GLXContext *foregroundCtxRet, GLXContext *backgroundCtxRet)
            putenv( (char *) "__GL_SYNC_TO_VBLANK=1" );
            putenv( (char *) "__GL_SYNC_TO_VBLANK=0" );
        int attrib[] = { GLX_RGBA,
                         GLX_RED_SIZE, 1,
                         GLX_GREEN_SIZE, 1,
                         GLX_BLUE_SIZE, 1,
                         GLX_DEPTH_SIZE, 24,
                         GLX_SAMPLE_BUFFERS  , 1*MULTISAMPLING,      // <-- MSAA
                         GLX_SAMPLES         , 4*MULTISAMPLING,      // <-- MSAA
                         None };
        int scrnum;
        XSetWindowAttributes attr;
        unsigned long mask;
        Window root;
        Window win;
        GLXContext foregroundCtx, backgroundCtx;
        XVisualInfo *visinfo;
        scrnum = DefaultScreen( dpy );
        root = RootWindow( dpy, scrnum );
        visinfo = glXChooseVisual( dpy, scrnum, attrib );
        if (!visinfo) {
           printf("Error: couldn't get an RGB, Double-buffered visual\n");
        /* window attributes */
        attr.background_pixel = 0;
        attr.border_pixel = 0;
        attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
        attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPress | PointerMotionMask;
        mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
        win = XCreateWindow( dpy, root, 0, 0, width, height,
                             0, visinfo->depth, InputOutput,
                             visinfo->visual, mask, &attr );
        /* set hints and properties */
           XSizeHints sizehints;
           sizehints.x = x;
           sizehints.y = y;
           sizehints.width  = width;
           sizehints.height = height;
           sizehints.flags = USSize | USPosition;
           XSetNormalHints(dpy, win, &sizehints);
           XSetStandardProperties(dpy, win, name, name,
                                   None, (char **)NULL, 0, &sizehints);
        foregroundCtx = glXCreateContext( dpy, visinfo, NULL, True );
        if (!foregroundCtx) {
           printf("Error: glXCreateContext for mainCtx failed\n");
        backgroundCtx = glXCreateContext( dpy, visinfo, foregroundCtx, True );
        if (!backgroundCtx) {
           printf("Error: glXCreateContext for threadCtx failed\n");
        *winRet = win;
        *foregroundCtxRet = foregroundCtx;
        *backgroundCtxRet = backgroundCtx;

    Code :
    void init(Display *dpy, GLXContext* backgroundCtx, Window* win, int32_t argc, char** argv)
        //init my OpenGL stuff (shaders...)
        SLoaderThread sLoaderThread;
        sLoaderThread.pBV3DManager = renderer.getBV3DManager();
        sLoaderThread.dpy = dpy;
        sLoaderThread.backgroundCtx = backgroundCtx; = win;
        pthread_create(&loaderThread, NULL, startLoaderThread, (void*)&sLoaderThread);
    struct SLoaderThread
        CBV3DManager* pBV3DManager;    //manages my world geometries and textures
        Display *dpy;
        GLXContext* backgroundCtx;
        Window* win;
    void* startLoaderThread(void* data)
        SLoaderThread* pSLoaderThread = (SLoaderThread*)data;
        glXMakeCurrent(pSLoaderThread->dpy, *pSLoaderThread->win, *pSLoaderThread->backgroundCtx);    //Crashes here with a segfault
        return NULL;
    Last edited by Vylsain; 05-15-2013 at 02:09 AM.

  2. #2
    Member Regular Contributor
    Join Date
    Dec 2009
    You pass the address of a stack-allocated structure to pthread_create, this will be destroyed as soon as the main thread leaves init(), so probably before the loader thread has a chance to read the stuff. Pass the data in static or malloc()ed memory.

  3. #3
    Junior Member Newbie
    Join Date
    Nov 2012
    Oh ok. That's the first time I use theads and even though that's completely logical and the first thing to check, I missed that !

    Thank you for your help mbentrup !

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts