SharedDrawable resets States?

Started by Protoreality, April 23, 2014, 21:18:41

Previous topic - Next topic

Protoreality

I'm using a SharedDrawable to give access to OpenGL functions in other threads.
However, on using the SharedDrawable.makeCurrent(), all my OpenGL states are reset and I have to set them again, which seems kind of expensive to do on every switch.
I'd like to know, if there is any way to stop the context from resetting.
This is the code, I'm using:

public final class SharedContext 
{
    private static SharedDrawable Drawable;
    private static volatile boolean lock;
    private static volatile long threadid;
    
    public SharedContext()
    {
        try {
            Drawable = new SharedDrawable(Display.getDrawable());
        } catch (LWJGLException ex) {
           System.err.println("Could  not create a shared context!");
           ex.printStackTrace();
        }
        lock = false;
        threadid = -1;
    }
    
    private static synchronized boolean lock()
    {
        if(lock)
        {
            return false;
        }
        
        try {
            Drawable.makeCurrent();
            lock = true;
            threadid = Thread.currentThread().getId();
        } catch (LWJGLException ex) {
            lock = false;
            threadid = -1;
            System.err.println("Failed to make context current! Thread: " + Thread.currentThread().getName());
            return false;
        }

        return true;
    }
    
    private static synchronized boolean unlock()
    {
        try {
            Drawable.releaseContext();
            lock = false;
            threadid = -1;
        } catch (LWJGLException ex) {
            System.err.println("Failed to release context! Thread: " + Thread.currentThread().getName());
            return false;
        }
        return true;
    }
    
    public static void setContext()
    {
        if(lock && threadid == Thread.currentThread().getId())
        {       
            return;
        }
        
        while(!lock())
            Thread.yield();
    }
    
    public static void releaseContext()
    {
        if(lock && threadid == Thread.currentThread().getId())
        {
            while(!unlock())
                Thread.yield();
        }
    }
}


Best Regards

spasi

That shouldn't happen. Each context has its own state and that state cannot change unless you make it current first. Please check for OpenGL errors or other bugs in your code.

In any case, it's very likely that what you're trying to do can be done more efficiently without context switches. The threads that require OpenGL access can pass data to the rendering thread(s) using a concurrent data structure and all GL calls should happen in those threads. Most rendering systems (e.g. Swing, JavaFX)  work that way, because it's less costly than makeCurrent (which can kill performance even with a few calls per frame).