diff options
Diffstat (limited to 'src/jogl/classes/jogamp/opengl')
5 files changed, 89 insertions, 75 deletions
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java index af8282752..7fd9970a4 100644 --- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java @@ -286,7 +286,7 @@ public abstract class GLContextImpl extends GLContext { throw new GLException("XXX: "+lock); } if (DEBUG || TRACE_SWITCH) { - System.err.println(getThreadName() + ": GLContextImpl.destroy.0 - "+Thread.currentThread().getName()+": " + toHexString(contextHandle) + + System.err.println(getThreadName() + ": GLContextImpl.destroy.0: " + toHexString(contextHandle) + ", isShared "+GLContextShareSet.isShared(this)+" - "+lock); } if (contextHandle != 0) { @@ -661,7 +661,10 @@ public abstract class GLContextImpl extends GLContext { } if ( !GLContext.getAvailableGLVersionsSet(device) ) { - mapGLVersions(device); + if(!mapGLVersions(device)) { + // none of the ARB context creation calls was successful, bail out + return 0; + } } int reqMajor; @@ -690,19 +693,26 @@ public abstract class GLContextImpl extends GLContext { return _ctx; } - private final void mapGLVersions(AbstractGraphicsDevice device) { + private final boolean mapGLVersions(AbstractGraphicsDevice device) { synchronized (GLContext.deviceVersionAvailable) { + boolean success = false; // Following GLProfile.GL_PROFILE_LIST_ALL order of profile detection { GL4bc, GL3bc, GL2, GL4, GL3, GL2GL3, GLES2, GL2ES2, GLES1, GL2ES1 } - createContextARBMapVersionsAvailable(4, true /* compat */); // GL4bc - createContextARBMapVersionsAvailable(3, true /* compat */); // GL3bc - createContextARBMapVersionsAvailable(2, true /* compat */); // GL2 - createContextARBMapVersionsAvailable(4, false /* core */); // GL4 - createContextARBMapVersionsAvailable(3, false /* core */); // GL3 - GLContext.setAvailableGLVersionsSet(device); + success |= createContextARBMapVersionsAvailable(4, true /* compat */); // GL4bc + success |= createContextARBMapVersionsAvailable(3, true /* compat */); // GL3bc + success |= createContextARBMapVersionsAvailable(2, true /* compat */); // GL2 + success |= createContextARBMapVersionsAvailable(4, false /* core */); // GL4 + success |= createContextARBMapVersionsAvailable(3, false /* core */); // GL3 + if(success) { + // only claim GL versions set [and hence detected] if ARB context creation was successful + GLContext.setAvailableGLVersionsSet(device); + } else if (DEBUG) { + System.err.println(getThreadName() + ": createContextARB-MapVersions NONE for :"+device); + } + return success; } } - private final void createContextARBMapVersionsAvailable(int reqMajor, boolean compat) { + private final boolean createContextARBMapVersionsAvailable(int reqMajor, boolean compat) { long _context; int reqProfile = compat ? CTX_PROFILE_COMPAT : CTX_PROFILE_CORE ; int ctp = CTX_IS_ARB_CREATED | CTX_PROFILE_CORE; // default @@ -725,8 +735,10 @@ public abstract class GLContextImpl extends GLContext { majorMax=3; minorMax=GLContext.getMaxMinor(majorMax); majorMin=3; minorMin=1; } else /* if( glp.isGL2() ) */ { + // our minimum desktop OpenGL runtime requirements are 1.1, + // nevertheless we restrict ARB context creation to 2.0 to spare us futile attempts majorMax=3; minorMax=0; - majorMin=1; minorMin=1; // our minimum desktop OpenGL runtime requirements + majorMin=2; minorMin=0; } _context = createContextARBVersions(0, true, ctp, /* max */ majorMax, minorMax, @@ -734,8 +746,8 @@ public abstract class GLContextImpl extends GLContext { /* res */ major, minor); if(0==_context && !compat) { - ctp &= ~CTX_PROFILE_COMPAT ; - ctp |= CTX_PROFILE_CORE ; + // try w/ FORWARD instead of CORE + ctp &= ~CTX_PROFILE_CORE ; ctp |= CTX_OPTION_FORWARD ; _context = createContextARBVersions(0, true, ctp, /* max */ majorMax, minorMax, @@ -744,8 +756,8 @@ public abstract class GLContextImpl extends GLContext { if(0==_context) { // Try a compatible one .. even though not requested .. last resort ctp &= ~CTX_PROFILE_CORE ; - ctp |= CTX_PROFILE_COMPAT ; ctp &= ~CTX_OPTION_FORWARD ; + ctp |= CTX_PROFILE_COMPAT ; _context = createContextARBVersions(0, true, ctp, /* max */ majorMax, minorMax, /* min */ majorMin, minorMin, @@ -757,23 +769,19 @@ public abstract class GLContextImpl extends GLContext { // ctxMajorVersion, ctxMinorVersion, ctxOptions is being set by // createContextARBVersions(..) -> setGLFunctionAvailbility(..) -> setContextVersion(..) GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile, ctxMajorVersion, ctxMinorVersion, ctxOptions); - /** - * TODO: GLES2_TRUE_DESKTOP (see: GLContextImpl, GLProfile) - * Hack to enable GLES2 for desktop profiles w/ ES2 compatibility, - * however .. a consequent implementation would need to have all GL2ES2 - * implementing profile to also implement GLES2! - * Let's rely on GL2ES2 and let the user/impl. query isGLES2Compatible() - if( isGLES2Compatible() && null == GLContext.getAvailableGLVersion(device, 2, GLContext.CTX_PROFILE_ES) ) { - GLContext.mapAvailableGLVersion(device, 2, GLContext.CTX_PROFILE_ES, ctxMajorVersion, ctxMinorVersion, ctxOptions); - }*/ destroyContextARBImpl(_context); if (DEBUG) { System.err.println(getThreadName() + ": createContextARB-MapVersionsAvailable HAVE: " +reqMajor+"."+reqProfile+ " -> "+getGLVersion()); } - } else if (DEBUG) { - System.err.println(getThreadName() + ": createContextARB-MapVersionsAvailable NOPE: "+reqMajor+"."+reqProfile); + // only reset [and hence modify] this context state if ARB context creation was successful + resetStates(); + return true; + } else { + if (DEBUG) { + System.err.println(getThreadName() + ": createContextARB-MapVersionsAvailable NOPE: "+reqMajor+"."+reqProfile); + } + return false; } - resetStates(); } private final long createContextARBVersions(long share, boolean direct, int ctxOptionFlags, @@ -1126,7 +1134,8 @@ public abstract class GLContextImpl extends GLContext { } else { isHardwareRasterizer = ! ( glRendererLowerCase.contains("software") /* Mesa3D */ || glRendererLowerCase.contains("mesa x11") /* Mesa3D*/ || - glRendererLowerCase.contains("softpipe") /* Gallium */ + glRendererLowerCase.contains("softpipe") /* Gallium */ || + glRendererLowerCase.contains("llvmpipe") /* Gallium */ ); } return isHardwareRasterizer; diff --git a/src/jogl/classes/jogamp/opengl/GLWorkerThread.java b/src/jogl/classes/jogamp/opengl/GLWorkerThread.java index ac9655fbb..e717ec64c 100644 --- a/src/jogl/classes/jogamp/opengl/GLWorkerThread.java +++ b/src/jogl/classes/jogamp/opengl/GLWorkerThread.java @@ -40,8 +40,10 @@ package jogamp.opengl; import java.lang.reflect.InvocationTargetException; -import java.util.*; -import javax.media.opengl.*; +import java.util.ArrayList; +import java.util.List; + +import javax.media.opengl.GLContext; /** Singleton thread upon which all OpenGL work is performed by default. Unfortunately many vendors' OpenGL drivers are not really @@ -64,7 +66,7 @@ public class GLWorkerThread { // The Runnable to execute immediately on the worker thread private static volatile Runnable work; // Queue of Runnables to be asynchronously invoked - private static List queue = new LinkedList(); + private static List<Runnable> queue = new ArrayList<Runnable>(); /** Should only be called by Threading class if creation of the GLWorkerThread was requested via the opengl.1thread system @@ -141,7 +143,7 @@ public class GLWorkerThread { */ } else { - throw new RuntimeException("Should not start GLWorkerThread twice"); + throw new RuntimeException(getThreadName()+": Should not start GLWorkerThread twice"); } } } @@ -150,7 +152,7 @@ public class GLWorkerThread { public static void invokeAndWait(Runnable runnable) throws InvocationTargetException, InterruptedException { if (!started) { - throw new RuntimeException("May not invokeAndWait on worker thread without starting it first"); + throw new RuntimeException(getThreadName()+": May not invokeAndWait on worker thread without starting it first"); } Object lockTemp = lock; @@ -177,7 +179,7 @@ public class GLWorkerThread { public static void invokeLater(Runnable runnable) { if (!started) { - throw new RuntimeException("May not invokeLater on worker thread without starting it first"); + throw new RuntimeException(getThreadName()+": May not invokeLater on worker thread without starting it first"); } Object lockTemp = lock; @@ -208,6 +210,10 @@ public class GLWorkerThread { return (Thread.currentThread() == thread); } + protected static String getThreadName() { + return Thread.currentThread().getName(); + } + static class WorkerRunnable implements Runnable { public void run() { // Notify starting thread that we're ready @@ -252,10 +258,10 @@ public class GLWorkerThread { while (!queue.isEmpty()) { try { - Runnable curAsync = (Runnable) queue.remove(0); + Runnable curAsync = queue.remove(0); curAsync.run(); } catch (Throwable t) { - System.err.println("Exception occurred on JOGL OpenGL worker thread:"); + System.err.println(getThreadName()+": Exception occurred on JOGL OpenGL worker thread:"); t.printStackTrace(); } } diff --git a/src/jogl/classes/jogamp/opengl/ThreadingImpl.java b/src/jogl/classes/jogamp/opengl/ThreadingImpl.java index 07d5c3402..0ba86870d 100644 --- a/src/jogl/classes/jogamp/opengl/ThreadingImpl.java +++ b/src/jogl/classes/jogamp/opengl/ThreadingImpl.java @@ -47,13 +47,20 @@ import javax.media.opengl.GLProfile; /** Implementation of the {@link javax.media.opengl.Threading} class. */ public class ThreadingImpl { - public static final int AWT = 1; - public static final int WORKER = 2; + public enum Mode { + MT(0), ST_AWT(1), ST_WORKER(2); + + public final int id; + + Mode(int id){ + this.id = id; + } + } protected static final boolean DEBUG = Debug.debug("Threading"); private static boolean singleThreaded = true; - private static int mode; + private static Mode mode = Mode.MT; private static boolean hasAWT; // We need to know whether we're running on X11 platforms to change // our behavior when the Java2D/JOGL bridge is active @@ -65,7 +72,11 @@ public class ThreadingImpl { threadingPlugin = AccessController.doPrivileged(new PrivilegedAction<ThreadingPlugin>() { public ThreadingPlugin run() { - String workaround = Debug.getProperty("jogl.1thread", true); + final String workaround; + { + final String w = Debug.getProperty("jogl.1thread", true); + workaround = null != w ? w.toLowerCase() : null; + } ClassLoader cl = ThreadingImpl.class.getClassLoader(); // Default to using the AWT thread on all platforms except // Windows. On OS X there is instability apparently due to @@ -80,50 +91,48 @@ public class ThreadingImpl { String osType = NativeWindowFactory.getNativeWindowType(false); _isX11 = NativeWindowFactory.TYPE_X11.equals(osType); - int defaultMode = ( hasAWT ? AWT : WORKER ); - - mode = defaultMode; + mode = ( hasAWT ? Mode.ST_AWT : Mode.ST_WORKER ); // default + if (workaround != null) { - workaround = workaround.toLowerCase(); if (workaround.equals("true") || workaround.equals("auto")) { // Nothing to do; singleThreaded and mode already set up } else if (workaround.equals("worker")) { singleThreaded = true; - mode = WORKER; + mode = Mode.ST_WORKER; } else if (hasAWT && workaround.equals("awt")) { singleThreaded = true; - mode = AWT; + mode = Mode.ST_AWT; } else { singleThreaded = false; + mode = Mode.MT; } } - printWorkaroundNotice(); - + ThreadingPlugin threadingPlugin=null; - if(hasAWT) { + if(Mode.ST_AWT == mode) { // try to fetch the AWTThreadingPlugin Exception error=null; try { threadingPlugin = (ThreadingPlugin) ReflectionUtil.createInstance("jogamp.opengl.awt.AWTThreadingPlugin", cl); } catch (JogampRuntimeException jre) { error = jre; } - if(AWT == mode && null==threadingPlugin) { + if(null==threadingPlugin) { throw new GLException("Mode is AWT, but class 'jogamp.opengl.awt.AWTThreadingPlugin' is not available", error); } } + if(DEBUG) { + System.err.println("Threading: jogl.1thread "+workaround+", singleThreaded "+singleThreaded+", hasAWT "+hasAWT+", mode "+mode+", plugin "+threadingPlugin); + } return threadingPlugin; } }); - if(DEBUG) { - System.err.println("Threading: hasAWT "+hasAWT+", mode "+((mode==AWT)?"AWT":"WORKER")+", plugin "+threadingPlugin); - } } /** No reason to ever instantiate this class */ private ThreadingImpl() {} public static boolean isX11() { return _isX11; } - public static int getMode() { return mode; } + public static Mode getMode() { return mode; } /** If an implementation of the javax.media.opengl APIs offers a multithreading option but the default behavior is single-threading, @@ -165,9 +174,9 @@ public class ThreadingImpl { } switch (mode) { - case AWT: + case ST_AWT: throw new InternalError(); - case WORKER: + case ST_WORKER: return GLWorkerThread.isWorkerThread(); default: throw new InternalError("Illegal single-threading mode " + mode); @@ -198,10 +207,10 @@ public class ThreadingImpl { } switch (mode) { - case AWT: + case ST_AWT: throw new InternalError(); - case WORKER: + case ST_WORKER: GLWorkerThread.start(); // singleton start via volatile-dbl-checked-locking try { GLWorkerThread.invokeAndWait(r); @@ -220,14 +229,6 @@ public class ThreadingImpl { /** This is a workaround for AWT-related deadlocks which only seem to show up in the context of applets */ public static boolean isAWTMode() { - return (mode == AWT); - } - - private static void printWorkaroundNotice() { - if (singleThreaded && Debug.verbose()) { - System.err.println("Using " + - (mode == AWT ? "AWT" : "OpenGL worker") + - " thread for performing OpenGL work in javax.media.opengl implementation"); - } + return (mode == Mode.ST_AWT); } } diff --git a/src/jogl/classes/jogamp/opengl/awt/AWTThreadingPlugin.java b/src/jogl/classes/jogamp/opengl/awt/AWTThreadingPlugin.java index dd493f5ee..901146fc4 100644 --- a/src/jogl/classes/jogamp/opengl/awt/AWTThreadingPlugin.java +++ b/src/jogl/classes/jogamp/opengl/awt/AWTThreadingPlugin.java @@ -42,8 +42,6 @@ package jogamp.opengl.awt; import javax.media.opengl.*; -import java.awt.event.*; - import java.awt.EventQueue; import java.lang.reflect.InvocationTargetException; @@ -55,14 +53,14 @@ public class AWTThreadingPlugin implements ThreadingPlugin { public boolean isOpenGLThread() throws GLException { switch (ThreadingImpl.getMode()) { - case ThreadingImpl.AWT: + case ST_AWT: // FIXME: See the FIXME below in 'invokeOnOpenGLThread' if (Java2D.isOGLPipelineActive() && !ThreadingImpl.isX11()) { return Java2D.isQueueFlusherThread(); } else { return EventQueue.isDispatchThread(); } - case ThreadingImpl.WORKER: + case ST_WORKER: if (Java2D.isOGLPipelineActive()) { // FIXME: ideally only the QFT would be considered to be the // "OpenGL thread", but we can not currently run all of @@ -80,7 +78,7 @@ public class AWTThreadingPlugin implements ThreadingPlugin { public void invokeOnOpenGLThread(Runnable r) throws GLException { switch (ThreadingImpl.getMode()) { - case ThreadingImpl.AWT: + case ST_AWT: // FIXME: ideally should run all OpenGL work on the Java2D QFT // thread when it's enabled, but unfortunately there are // deadlock issues on X11 platforms when making our @@ -102,7 +100,7 @@ public class AWTThreadingPlugin implements ThreadingPlugin { } break; - case ThreadingImpl.WORKER: + case ST_WORKER: GLWorkerThread.start(); // singleton start via volatile-dbl-checked-locking try { GLWorkerThread.invokeAndWait(r); diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java index 08e064da5..f4ab92a04 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java @@ -262,7 +262,7 @@ public abstract class X11GLXContext extends GLContextImpl { protected boolean createImpl(GLContextImpl shareWith) { // covers the whole context creation loop incl createContextARBImpl and destroyContextARBImpl - X11Util.setX11ErrorHandler(true, true); + X11Util.setX11ErrorHandler(true, DEBUG ? false : true); try { return createImplRaw(shareWith); } finally { @@ -399,7 +399,7 @@ public abstract class X11GLXContext extends GLContextImpl { long dpy = drawable.getNativeSurface().getDisplayHandle(); if (GLX.glXGetCurrentContext() != contextHandle) { - X11Util.setX11ErrorHandler(true, true); + X11Util.setX11ErrorHandler(true, DEBUG ? false : true); try { if (!glXMakeContextCurrent(dpy, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { throw new GLException("Error making context current: "+this); @@ -412,7 +412,7 @@ public abstract class X11GLXContext extends GLContextImpl { protected void releaseImpl() throws GLException { long display = drawable.getNativeSurface().getDisplayHandle(); - X11Util.setX11ErrorHandler(true, true); + X11Util.setX11ErrorHandler(true, DEBUG ? false : true); try { if (!glXMakeContextCurrent(display, 0, 0, 0)) { throw new GLException("Error freeing OpenGL context"); |