From 97218b88af9113740b3704a3666d7356cdc83cd0 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Mon, 28 Nov 2011 03:06:13 +0100 Subject: Fix Bug 527: Creating a context w/ shared context, while the latter is in use (threading) Bug 527 describes the situation where wglShareLists() fails (throws exception) while the shared context is in use by another thread (some Animator). It was reported by Jerome Jouvie. The exception happens not everytime, but at least around 20% on manual tests I have performed on the Windows platform. The context in question are all JOGL's GL2, which natively where bound to an OpenGL 3.0 profile. The WGL_ARB_create_context spec says http://www.opengl.org/registry/specs/ARB/wgl_create_context.txt: +++ Future versions of OpenGL may only support being added to a share group at context creation time. Specifying such a version of a context as either the or arguments to wglShareLists will fail. wglShareLists will return FALSE, and GetLastError will return ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB. +++ Hence the 1st patch was to remove 'wglShareLists()' usage in case we use the new WGL_ARB_create_context context creation method. Even though this is a desired change, and works in general, it didn't fix the issue. It seems that the shared context, which is passed @ new context creation, cannot be used while it is in use itself in another thread. This conclusion leads to the actual fix, ie. locking the shared context while creating the new context which shares it. Manual tests using this patch could not reproduce this issue (40 attempts). Test: TestSharedContextListNEWT2 --- src/jogl/classes/jogamp/opengl/egl/EGLContext.java | 34 ++++++++++++---------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'src/jogl/classes/jogamp/opengl/egl') diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java index 7c72e0d29..6af35e3aa 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java @@ -35,17 +35,20 @@ package jogamp.opengl.egl; -import javax.media.opengl.*; +import java.nio.ByteBuffer; +import java.util.Map; -import jogamp.opengl.*; +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; + +import jogamp.opengl.GLContextImpl; +import jogamp.opengl.GLDrawableImpl; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; -import java.nio.*; -import java.util.*; - -import javax.media.nativewindow.AbstractGraphicsConfiguration; -import javax.media.nativewindow.AbstractGraphicsDevice; public abstract class EGLContext extends GLContextImpl { private boolean eglQueryStringInitialized; @@ -135,12 +138,12 @@ public abstract class EGLContext extends GLContextImpl { // FIXME } - protected boolean createImpl() throws GLException { + protected boolean createImpl(GLContextImpl shareWith) throws GLException { long eglDisplay = ((EGLDrawable)drawable).getDisplay(); EGLGraphicsConfiguration config = ((EGLDrawable)drawable).getGraphicsConfiguration(); GLProfile glProfile = drawable.getGLProfile(); long eglConfig = config.getNativeConfig(); - long shareWith = EGL.EGL_NO_CONTEXT; + long shareWithHandle = EGL.EGL_NO_CONTEXT; if (eglDisplay == 0) { throw new GLException("Error: attempted to create an OpenGL context without a display connection"); @@ -160,10 +163,9 @@ public abstract class EGLContext extends GLContextImpl { } } - EGLContext other = (EGLContext) GLContextShareSet.getShareContext(this); - if (other != null) { - shareWith = other.getHandle(); - if (shareWith == 0) { + if (shareWith != null) { + shareWithHandle = shareWith.getHandle(); + if (shareWithHandle == 0) { throw new GLException("GLContextShareSet returned an invalid OpenGL context"); } } @@ -179,10 +181,10 @@ public abstract class EGLContext extends GLContextImpl { } else { throw new GLException("Error creating OpenGL context - invalid GLProfile: "+glProfile); } - contextHandle = EGL.eglCreateContext(eglDisplay, eglConfig, shareWith, contextAttrs, 0); + contextHandle = EGL.eglCreateContext(eglDisplay, eglConfig, shareWithHandle, contextAttrs, 0); if (contextHandle == 0) { throw new GLException("Error creating OpenGL context: eglDisplay "+toHexString(eglDisplay)+ - ", eglConfig "+config+", "+glProfile+", shareWith "+toHexString(shareWith)+", error "+toHexString(EGL.eglGetError())); + ", eglConfig "+config+", "+glProfile+", shareWith "+toHexString(shareWithHandle)+", error "+toHexString(EGL.eglGetError())); } if (DEBUG) { System.err.println(getThreadName() + ": !!! Created OpenGL context 0x" + @@ -190,7 +192,7 @@ public abstract class EGLContext extends GLContextImpl { ",\n\twrite surface 0x" + Long.toHexString(drawable.getHandle()) + ",\n\tread surface 0x" + Long.toHexString(drawableRead.getHandle())+ ",\n\t"+this+ - ",\n\tsharing with 0x" + Long.toHexString(shareWith)); + ",\n\tsharing with 0x" + Long.toHexString(shareWithHandle)); } if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(), drawable.getHandle(), -- cgit v1.2.3