aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/jogamp/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/jogamp/opengl')
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java63
-rw-r--r--src/jogl/classes/jogamp/opengl/GLWorkerThread.java22
-rw-r--r--src/jogl/classes/jogamp/opengl/ThreadingImpl.java63
-rw-r--r--src/jogl/classes/jogamp/opengl/awt/AWTThreadingPlugin.java10
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java6
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");