aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2010-11-14 09:04:45 +0100
committerSven Gothel <[email protected]>2010-11-14 09:04:45 +0100
commit83d3a3f2ea8dc328e621b3abbe671f46379c7e65 (patch)
treeb7fafe2ef1610a6be0723316ae5bf5938b9f222d /src
parentc3bfb82614e9fa0f8ea7169cd412a6f0c71973e0 (diff)
JOGL: Complete eager and lazy mapping of GLProfiles in respect to multiple device.
AbstractGraphicsDevice's 'connection' and 'type' attribute is used as a unique key to map GLProfiles and GLContext's major/profile -> major/minor/profile mapping. Eager initialiaztion as well as lazy is supported to maintain a simple API. This is currently tested on X11, where one app display NEWT/GL window and content on the local and remote device. See TestRemoteWindow01NEWT.java and TestRemoteGLWindows01NEWT.java
Diffstat (limited to 'src')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/JoglVersion.java14
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java293
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/awt/Java2D.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java16
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java39
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java16
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java38
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java91
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java168
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java18
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java82
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java356
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java2
-rw-r--r--src/jogl/classes/javax/media/opengl/GLCapabilities.java2
-rw-r--r--src/jogl/classes/javax/media/opengl/GLContext.java347
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawableFactory.java52
-rw-r--r--src/jogl/classes/javax/media/opengl/GLProfile.java646
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java12
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java2
-rw-r--r--src/junit/com/jogamp/test/junit/newt/TestGLWindows00NEWT.java132
-rw-r--r--src/junit/com/jogamp/test/junit/newt/TestRemoteGLWindows01NEWT.java161
-rw-r--r--src/junit/com/jogamp/test/junit/newt/TestRemoteWindow01NEWT.java146
24 files changed, 1975 insertions, 664 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
index 86fbece4f..ee9d36147 100644
--- a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
+++ b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
@@ -57,8 +57,8 @@ public class JoglVersion extends JogampVersion {
return jogampCommonVersionInfo;
}
- public StringBuffer getInfo(GL gl, StringBuffer sb) {
- sb = super.getInfo(sb);
+ public StringBuffer toStringBuffer(GL gl, StringBuffer sb) {
+ sb = super.toStringBuffer(sb);
getGLInfo(gl, sb);
sb.append("-----------------------------------------------------------------------------------------------------");
@@ -67,12 +67,18 @@ public class JoglVersion extends JogampVersion {
return sb;
}
+ public String toString(GL gl) {
+ return toStringBuffer(gl, null).toString();
+ }
+
public static StringBuffer getGLInfo(GL gl, StringBuffer sb) {
if(null==sb) {
sb = new StringBuffer();
}
- sb.append(GLProfile.glAvailabilityToString());
+ sb.append("Default Desktop ").append(GLProfile.getDefaultDesktopDevice().getConnection()).append(": ").append(GLProfile.glAvailabilityToString(GLProfile.getDefaultDesktopDevice()));
+ sb.append(Platform.getNewline());
+ sb.append("Default EGL ").append(GLProfile.getDefaultEGLDevice().getConnection()).append(": ").append(GLProfile.glAvailabilityToString(GLProfile.getDefaultEGLDevice()));
sb.append(Platform.getNewline());
sb.append("Swap Interval ").append(gl.getSwapInterval());
sb.append(Platform.getNewline());
@@ -93,7 +99,7 @@ public class JoglVersion extends JogampVersion {
}
public static void main(String args[]) {
- System.err.println(JoglVersion.getInstance().getInfo(null));
+ System.err.println(JoglVersion.getInstance());
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java
index ca689ed81..6c15a2d92 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java
@@ -41,20 +41,37 @@
package com.jogamp.opengl.impl;
import com.jogamp.common.os.DynamicLookupHelper;
-import java.nio.*;
-import java.util.*;
-
-import javax.media.opengl.*;
-import javax.media.nativewindow.*;
-import com.jogamp.gluegen.runtime.*;
-import com.jogamp.gluegen.runtime.opengl.*;
import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.gluegen.runtime.FunctionAddressResolver;
+import com.jogamp.gluegen.runtime.ProcAddressTable;
+import com.jogamp.gluegen.runtime.opengl.GLExtensionNames;
+import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
public abstract class GLContextImpl extends GLContext {
- protected GLContextLock lock = new GLContextLock();
protected static final boolean DEBUG = Debug.debug("GLContext");
protected static final boolean VERBOSE = Debug.verbose();
+ protected GLContextLock lock = new GLContextLock();
+
+ /**
+ * Context full qualified name: display_type + display_connection + major + minor + ctp.
+ * This is the key for all cached ProcAddressTables, etc, to support multi display/device setups.
+ */
+ protected String contextFQN;
+
// Cache of the functions that are available to be called at the current
// moment in time
protected ExtensionAvailabilityCache extensionAvailability;
@@ -73,15 +90,25 @@ public abstract class GLContextImpl extends GLContext {
protected GL gl;
+ protected static final Object mappedContextTypeObjectLock;
+ protected static final HashMap mappedExtensionAvailabilityCache;
+ protected static final HashMap mappedGLProcAddress;
+ protected static final HashMap mappedGLXProcAddress;
+
+ static {
+ mappedContextTypeObjectLock = new Object();
+ mappedExtensionAvailabilityCache = new HashMap();
+ mappedGLProcAddress = new HashMap();
+ mappedGLXProcAddress = new HashMap();
+ }
+
public GLContextImpl(GLDrawableImpl drawable, GLDrawableImpl drawableRead, GLContext shareWith) {
- extensionAvailability = new ExtensionAvailabilityCache(this);
+ super();
+
if (shareWith != null) {
GLContextShareSet.registerSharing(this, shareWith);
}
GLContextShareSet.registerForBufferObjectSharing(shareWith, this);
- // This must occur after the above calls into the
- // GLContextShareSet, which set up state needed by the GL object
- setGL(createGL(drawable.getGLProfile()));
this.drawable = drawable;
setGLDrawableRead(drawableRead);
@@ -91,6 +118,32 @@ public abstract class GLContextImpl extends GLContext {
this(drawable, null, shareWith);
}
+ protected void resetStates() {
+ // Because we don't know how many other contexts we might be
+ // sharing with (and it seems too complicated to implement the
+ // GLObjectTracker's ref/unref scheme for the buffer-related
+ // optimizations), simply clear the cache of known buffers' sizes
+ // when we destroy contexts
+ if (bufferSizeTracker != null) {
+ bufferSizeTracker.clearCachedBufferSizes();
+ }
+
+ if (bufferStateTracker != null) {
+ bufferStateTracker.clearBufferObjectState();
+ }
+
+ if (glStateTracker != null) {
+ glStateTracker.clearStates(false);
+ }
+
+ extensionAvailability = null;
+ glProcAddressTable = null;
+ gl = null;
+ contextFQN = null;
+
+ super.resetStates();
+ }
+
public void setGLDrawableRead(GLDrawable read) {
boolean lockHeld = lock.isHeld();
if(lockHeld) {
@@ -185,24 +238,7 @@ public abstract class GLContextImpl extends GLContext {
}
}
*/
-
- // Because we don't know how many other contexts we might be
- // sharing with (and it seems too complicated to implement the
- // GLObjectTracker's ref/unref scheme for the buffer-related
- // optimizations), simply clear the cache of known buffers' sizes
- // when we destroy contexts
- if (bufferSizeTracker != null) {
- bufferSizeTracker.clearCachedBufferSizes();
- }
- if (bufferStateTracker != null) {
- bufferStateTracker.clearBufferObjectState();
- }
-
- if (glStateTracker != null) {
- glStateTracker.clearStates(false);
- }
-
if (contextHandle != 0) {
int lockRes = drawable.lockSurface();
if (NativeSurface.LOCK_SURFACE_NOT_READY == lockRes) {
@@ -220,6 +256,8 @@ public abstract class GLContextImpl extends GLContext {
} finally {
lock.unlock();
}
+
+ resetStates();
}
protected abstract void destroyImpl() throws GLException;
@@ -364,6 +402,8 @@ public abstract class GLContextImpl extends GLContext {
}
boolean newCreated = false;
if (!isCreated()) {
+ GLProfile.initProfiles(
+ getGLDrawable().getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice());
newCreated = createImpl(); // may throws exception if fails!
if (DEBUG) {
if(newCreated) {
@@ -401,6 +441,8 @@ public abstract class GLContextImpl extends GLContext {
* The implementation shall verify this context with a
* <code>MakeContextCurrent</code> call.<br>
*
+ * The implementation shall leave the context current.<br>
+ *
* @param share the shared context or null
* @param direct flag if direct is requested
* @param ctxOptionFlags <code>ARB_create_context</code> related, see references below
@@ -444,6 +486,8 @@ public abstract class GLContextImpl extends GLContext {
* This method will also query all available native OpenGL context when first called,<br>
* usually the first call should happen with the shared GLContext of the DrawableFactory.<br>
*
+ * The implementation makes the context current, if successful<br>
+ *
* @see #makeCurrentImpl
* @see #create
* @see #createContextARB
@@ -454,14 +498,16 @@ public abstract class GLContextImpl extends GLContext {
int major[], int minor[], int ctp[])
{
AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsDevice device = config.getScreen().getDevice();
GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities();
GLProfile glp = glCaps.getGLProfile();
if (DEBUG) {
- System.err.println(getThreadName() + ": !!! createContextARB: mappedVersionsAvailableSet "+ mappedVersionsAvailableSet);
+ System.err.println(getThreadName() + ": !!! createContextARB: mappedVersionsAvailableSet("+device.getConnection()+"): "+
+ GLContext.getAvailableGLVersionsSet(device));
}
- mapGLVersions();
+ mapGLVersions(device);
int reqMajor;
if(glp.isGL4()) {
@@ -471,47 +517,44 @@ public abstract class GLContextImpl extends GLContext {
} else /* if (glp.isGL2()) */ {
reqMajor=2;
}
+
boolean compat = glp.isGL2(); // incl GL3bc and GL4bc
-
- int key = compose8bit(reqMajor, compat?CTX_PROFILE_COMPAT:CTX_PROFILE_CORE, 0, 0);
- int val;
- synchronized(mappedVersionsAvailableLock) {
- val = mappedVersionsAvailable.get( key );
- }
+ int _major[] = { 0 };
+ int _minor[] = { 0 };
+ int _ctp[] = { 0 };
long _ctx = 0;
- if(val>0) {
- int _major = getComposed8bit(val, 1);
- int _minor = getComposed8bit(val, 2);
- int _ctp = getComposed8bit(val, 3);
- _ctx = createContextARBImpl(share, direct, _ctp, _major, _minor);
+ if( GLContext.getAvailableGLVersion(device, reqMajor, compat?CTX_PROFILE_COMPAT:CTX_PROFILE_CORE,
+ _major, _minor, _ctp)) {
+ _ctx = createContextARBImpl(share, direct, _ctp[0], _major[0], _minor[0]);
if(0!=_ctx) {
- setGLFunctionAvailability(true, _major, _minor, _ctp);
+ setGLFunctionAvailability(true, _major[0], _minor[0], _ctp[0]);
}
}
return _ctx;
}
- private void mapGLVersions() {
- if (!mappedVersionsAvailableSet) {
- synchronized (mappedVersionsAvailableLock) {
- if (!mappedVersionsAvailableSet) {
- createContextARBMapVersionsAvailable(2, true /* compat */); // GL2
- createContextARBMapVersionsAvailable(3, true /* compat */); // GL3bc
- createContextARBMapVersionsAvailable(3, false /* core */); // GL3
- createContextARBMapVersionsAvailable(4, true /* compat */); // GL4bc
- createContextARBMapVersionsAvailable(4, false /* core */); // GL4
- mappedVersionsAvailableSet = true;
- if (DEBUG) {
- System.err.println(getThreadName() + ": !!! createContextARB: SET mappedVersionsAvailableSet " + mappedVersionsAvailableSet);
- }
- }
+ private final void mapGLVersions(AbstractGraphicsDevice device) {
+ if ( !GLContext.getAvailableGLVersionsSet(device) ) {
+ synchronized (GLContext.deviceVersionAvailable) {
+ createContextARBMapVersionsAvailable(4, false /* core */); // GL4
+ createContextARBMapVersionsAvailable(4, true /* compat */); // GL4bc
+ createContextARBMapVersionsAvailable(3, false /* core */); // GL3
+ createContextARBMapVersionsAvailable(3, true /* compat */); // GL3bc
+ createContextARBMapVersionsAvailable(2, true /* compat */); // GL2
+ GLContext.setAvailableGLVersionsSet(device);
+ }
+ } else {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": no mapping, all versions set "+device.getConnection());
}
}
}
private final void createContextARBMapVersionsAvailable(int reqMajor, boolean compat)
{
+ resetStates();
+
long _context;
int reqProfile = compat ? CTX_PROFILE_COMPAT : CTX_PROFILE_CORE ;
int ctp = CTX_IS_ARB_CREATED | CTX_PROFILE_CORE | CTX_OPTION_ANY; // default
@@ -570,11 +613,14 @@ public abstract class GLContextImpl extends GLContext {
}
}
if(0!=_context) {
- destroyContextARBImpl(_context);
- mapVersionAvailable(reqMajor, reqProfile, major[0], minor[0], ctp);
+ AbstractGraphicsDevice device = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
+ GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile, major[0], minor[0], ctp);
setGLFunctionAvailability(true, major[0], minor[0], ctp);
+ destroyContextARBImpl(_context);
+ resetStates();
if (DEBUG) {
- System.err.println(getThreadName() + ": !!! createContextARBMapVersionsAvailable HAVE: "+getGLVersionAvailable(reqMajor, reqProfile));
+ System.err.println(getThreadName() + ": !!! createContextARBMapVersionsAvailable HAVE: "+
+ GLContext.getAvailableGLVersionAsString(device, reqMajor, reqProfile));
}
} else if (DEBUG) {
System.err.println(getThreadName() + ": !!! createContextARBMapVersionsAvailable NOPE: "+reqMajor+"."+reqProfile);
@@ -615,7 +661,7 @@ public abstract class GLContextImpl extends GLContext {
* If major==0 && minor == 0 : Use GL_VERSION
* Otherwise .. don't touch ..
*/
- protected final void setContextVersion(int major, int minor, int ctp) {
+ private final void setContextVersion(int major, int minor, int ctp) {
if (0==ctp) {
throw new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
}
@@ -643,6 +689,13 @@ public abstract class GLContextImpl extends GLContext {
if (version.isValid()) {
ctxMajorVersion = version.getMajor();
ctxMinorVersion = version.getMinor();
+ // We cannot promote a non ARB context to >= 3.1,
+ // reduce it to 3.0 then.
+ if ( ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=1 )
+ && 0 == (ctxOptions & CTX_IS_ARB_CREATED) ) {
+ ctxMajorVersion = 3;
+ ctxMinorVersion = 0;
+ }
ctxVersionString = getGLVersion(ctxMajorVersion, ctxMinorVersion, ctxOptions, versionStr);
return;
}
@@ -750,13 +803,17 @@ public abstract class GLContextImpl extends GLContext {
* the cache of which GL functions are available for calling through this
* context. See {@link #isFunctionAvailable(String)} for more information on
* the definition of "available".
+ * <br>
+ * All ProcaddressTables are being determined, the GL version is being set
+ * and the extension cache is determined as well.
*
* @param force force the setting, even if is already being set.
- * This might be usefull if you change the OpenGL implementation.
+ * This might be useful if you change the OpenGL implementation.
*
* @see #setContextVersion
*/
- protected void setGLFunctionAvailability(boolean force, int major, int minor, int ctp) {
+
+ protected final void setGLFunctionAvailability(boolean force, int major, int minor, int ctp) {
if(null!=this.gl && null!=glProcAddressTable && !force) {
return; // already done and not forced
}
@@ -764,37 +821,34 @@ public abstract class GLContextImpl extends GLContext {
setGL(createGL(getGLDrawable().getGLProfile()));
}
- updateGLProcAddressTable(major, minor, ctp);
- }
+ AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
+ contextFQN = getContextFQN(adevice, major, minor, ctp);
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Context FQN: "+contextFQN);
+ }
- /**
- * Updates the cache of which GL functions are available for calling through this
- * context. See {@link #isFunctionAvailable(String)} for more information on
- * the definition of "available".
- *
- * @see #setContextVersion
- */
- protected void updateGLProcAddressTable(int major, int minor, int ctp) {
+ updateGLXProcAddressTable(major, minor, ctp);
+
+ //
+ // UpdateGLProcAddressTable functionality
+ //
if(null==this.gl) {
throw new GLException("setGLFunctionAvailability not called yet");
}
- if (DEBUG) {
- System.err.println(getThreadName() + ": !!! Initializing OpenGL extension address table for " + this);
- }
- int key = compose8bit(major, minor, ctp, 0);
ProcAddressTable table = null;
- synchronized(mappedProcAddressLock) {
- table = (ProcAddressTable) mappedGLProcAddress.get( key );
+ synchronized(mappedContextTypeObjectLock) {
+ table = (ProcAddressTable) mappedGLProcAddress.get( contextFQN );
if(null != table && !verifyInstance(gl.getGLProfile(), "ProcAddressTable", table)) {
- throw new InternalError("GLContext GL ProcAddressTable mapped key("+major+","+minor+","+ctp+") -> "+
+ throw new InternalError("GLContext GL ProcAddressTable mapped key("+contextFQN+") -> "+
table.getClass().getName()+" not matching "+gl.getGLProfile().getGLImplBaseClassName());
}
}
if(null != table) {
glProcAddressTable = table;
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext GL ProcAddressTable reusing key("+major+","+minor+","+ctp+") -> "+table.hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext GL ProcAddressTable reusing key("+contextFQN+") -> "+table.hashCode());
}
} else {
if (glProcAddressTable == null) {
@@ -803,20 +857,52 @@ public abstract class GLContextImpl extends GLContext {
new Object[] { new GLProcAddressResolver() } );
}
resetProcAddressTable(getGLProcAddressTable());
- synchronized(mappedProcAddressLock) {
- mappedGLProcAddress.put(key, getGLProcAddressTable());
+ synchronized(mappedContextTypeObjectLock) {
+ mappedGLProcAddress.put(contextFQN, getGLProcAddressTable());
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext GL ProcAddressTable mapping key("+major+","+minor+","+ctp+") -> "+getGLProcAddressTable().hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext GL ProcAddressTable mapping key("+contextFQN+") -> "+getGLProcAddressTable().hashCode());
}
}
}
+
+ //
+ // Set GL Version
+ //
setContextVersion(major, minor, ctp);
- extensionAvailability.reset();
+ //
+ // Update ExtensionAvailabilityCache
+ //
+ ExtensionAvailabilityCache eCache;
+ synchronized(mappedContextTypeObjectLock) {
+ eCache = (ExtensionAvailabilityCache) mappedExtensionAvailabilityCache.get( contextFQN );
+ }
+ if(null != eCache) {
+ extensionAvailability = eCache;
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": !!! GLContext GL ExtensionAvailabilityCache reusing key("+contextFQN+") -> "+eCache.hashCode());
+ }
+ } else {
+ if(null==extensionAvailability) {
+ extensionAvailability = new ExtensionAvailabilityCache(this);
+ }
+ extensionAvailability.reset();
+ synchronized(mappedContextTypeObjectLock) {
+ mappedExtensionAvailabilityCache.put(contextFQN, extensionAvailability);
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": !!! GLContext GL ExtensionAvailabilityCache mapping key("+contextFQN+") -> "+extensionAvailability.hashCode());
+ }
+ }
+ }
hasNativeES2Methods = isGLES2() || isExtensionAvailable("GL_ARB_ES2_compatibility") ;
}
+ /**
+ * Updates the platform's 'GLX' function cache
+ */
+ protected abstract void updateGLXProcAddressTable(int major, int minor, int ctp);
+
protected boolean hasNativeES2Methods = false;
public final boolean hasNativeES2Methods() { return hasNativeES2Methods; }
@@ -833,23 +919,26 @@ public abstract class GLContextImpl extends GLContext {
* javax.media.opengl.GL#glPolygonOffset(float,float)} is available).
*/
public boolean isFunctionAvailable(String glFunctionName) {
- if(isCreated()) {
- // Check GL 1st (cached)
- ProcAddressTable pTable = getGLProcAddressTable();
+ // Check GL 1st (cached)
+ ProcAddressTable pTable = getGLProcAddressTable(); // null if ctx not created once
+ if(null!=pTable) {
try {
if(0!=pTable.getAddressFor(glFunctionName)) {
return true;
}
} catch (Exception e) {}
+ }
- // Check platform extensions 2nd (cached)
- pTable = getPlatformExtProcAddressTable();
+ // Check platform extensions 2nd (cached) - had to be enabled once
+ pTable = getPlatformExtProcAddressTable(); // null if ctx not created once
+ if(null!=pTable) {
try {
if(0!=pTable.getAddressFor(glFunctionName)) {
return true;
}
} catch (Exception e) {}
}
+
// dynamic function lookup at last incl name aliasing (not cached)
DynamicLookupHelper dynLookup = getDrawableImpl().getGLDynamicLookupHelper();
String tmpBase = GLExtensionNames.normalizeVEN(GLExtensionNames.normalizeARB(glFunctionName, true), true);
@@ -878,19 +967,31 @@ public abstract class GLContextImpl extends GLContext {
* "GL_VERTEX_PROGRAM_ARB").
*/
public boolean isExtensionAvailable(String glExtensionName) {
- return extensionAvailability.isExtensionAvailable(mapToRealGLExtensionName(glExtensionName));
+ if(null!=extensionAvailability) {
+ return extensionAvailability.isExtensionAvailable(mapToRealGLExtensionName(glExtensionName));
+ }
+ return false;
}
public String getPlatformExtensionsString() {
- return extensionAvailability.getPlatformExtensionsString();
+ if(null!=extensionAvailability) {
+ return extensionAvailability.getPlatformExtensionsString();
+ }
+ return null;
}
public String getGLExtensions() {
- return extensionAvailability.getGLExtensions();
+ if(null!=extensionAvailability) {
+ return extensionAvailability.getGLExtensions();
+ }
+ return null;
}
public boolean isExtensionCacheInitialized() {
- return extensionAvailability.isInitialized();
+ if(null!=extensionAvailability) {
+ return extensionAvailability.isInitialized();
+ }
+ return false;
}
/** Indicates which floating-point pbuffer implementation is in
@@ -909,10 +1010,6 @@ public abstract class GLContextImpl extends GLContext {
/** Only called for offscreen contexts; needed by glReadPixels */
public abstract int getOffscreenContextPixelDataType();
- protected static String getThreadName() {
- return Thread.currentThread().getName();
- }
-
//----------------------------------------------------------------------
// Helpers for buffer object optimizations
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
index 6837949d3..43f705e34 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
@@ -225,8 +225,6 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
//
// GLDrawableFactoryImpl details
//
- protected abstract GLDrawableImpl getSharedDrawable();
- protected abstract GLContextImpl getSharedContext();
protected void maybeDoSingleThreadedWorkaround(Runnable action) {
if (Threading.isSingleThreaded() &&
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2D.java b/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2D.java
index d8f83a5f7..5566a3a4a 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2D.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2D.java
@@ -558,7 +558,7 @@ public class Java2D {
}
invokeWithOGLSharedContextCurrent(device.getDefaultConfiguration(), new Runnable() {
public void run() {
- j2dFBOShareContext = GLDrawableFactory.getFactory(GLProfile.getDefault()).createExternalGLContext();
+ j2dFBOShareContext = GLDrawableFactory.getFactory(GLProfile.getDefault(GLProfile.getDefaultDesktopDevice())).createExternalGLContext();
}
});
if (DEBUG) {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java
index d8b5b78f2..d95a9e3ff 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java
@@ -192,22 +192,21 @@ public abstract class EGLContext extends GLContextImpl {
return true;
}
- protected void updateGLProcAddressTable(int major, int minor, int ctp) {
+ protected final void updateGLXProcAddressTable(int major, int minor, int ctp) {
if (DEBUG) {
System.err.println(getThreadName() + ": !!! Initializing EGL extension address table");
}
eglQueryStringInitialized = false;
eglQueryStringAvailable = false;
- int key = compose8bit(major, minor, ctp, 0);
EGLExtProcAddressTable table = null;
- synchronized(mappedProcAddressLock) {
- table = (EGLExtProcAddressTable) mappedGLXProcAddress.get( key );
+ synchronized(mappedContextTypeObjectLock) {
+ table = (EGLExtProcAddressTable) mappedGLXProcAddress.get( contextFQN );
}
if(null != table) {
eglExtProcAddressTable = table;
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext EGL ProcAddressTable reusing key("+major+","+minor+","+ctp+") -> "+table.hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext EGL ProcAddressTable reusing key("+contextFQN+") -> "+table.hashCode());
}
} else {
if (eglExtProcAddressTable == null) {
@@ -216,14 +215,13 @@ public abstract class EGLContext extends GLContextImpl {
eglExtProcAddressTable = new EGLExtProcAddressTable(new GLProcAddressResolver());
}
resetProcAddressTable(getEGLExtProcAddressTable());
- synchronized(mappedProcAddressLock) {
- mappedGLXProcAddress.put(key, getEGLExtProcAddressTable());
+ synchronized(mappedContextTypeObjectLock) {
+ mappedGLXProcAddress.put(contextFQN, getEGLExtProcAddressTable());
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext EGL ProcAddressTable mapping key("+major+","+minor+","+ctp+") -> "+getEGLExtProcAddressTable().hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext EGL ProcAddressTable mapping key("+contextFQN+") -> "+getEGLExtProcAddressTable().hashCode());
}
}
}
- super.updateGLProcAddressTable(major, minor, ctp);
}
public synchronized String getPlatformExtensionsString() {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java
index deb659ddf..6ebd3938a 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java
@@ -42,6 +42,8 @@ import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.util.*;
import com.jogamp.opengl.impl.*;
import com.jogamp.nativewindow.impl.ProxySurface;
+import java.util.HashMap;
+import javax.media.nativewindow.egl.EGLGraphicsDevice;
public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@@ -93,6 +95,39 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
public EGLDrawableFactory() {
super();
+ /** FIXME:
+ * find out the Windows semantics of a device connection {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection()}
+ * to actually use multiple devices.
+ */
+ defaultDevice = new EGLGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION);
+ }
+
+ static class SharedResource {
+ private EGLDrawable drawable;
+ private EGLContext context;
+
+ SharedResource(EGLDrawable draw, EGLContext ctx) {
+ drawable = draw;
+ context = ctx;
+ }
+ }
+ HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
+ EGLGraphicsDevice defaultDevice;
+
+ public final AbstractGraphicsDevice getDefaultDevice() {
+ return defaultDevice;
+ }
+
+ public final boolean getIsDeviceCompatible(AbstractGraphicsDevice device) {
+ if(device instanceof EGLGraphicsDevice) {
+ return true;
+ }
+ return false;
+ }
+
+ protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) {
+ // FIXME: not implemented .. needs a dummy EGL surface
+ return null;
}
public GLDynamicLookupHelper getGLDynamicLookupHelper(int esProfile) {
@@ -112,8 +147,6 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
protected void shutdownInstance() {}
- protected final GLDrawableImpl getSharedDrawable() { return null; }
- protected final GLContextImpl getSharedContext() { return null; }
protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) {
if (target == null) {
@@ -141,7 +174,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
protected GLContext createExternalGLContextImpl() {
- AbstractGraphicsScreen absScreen = DefaultGraphicsScreen.createScreenDevice(0);
+ AbstractGraphicsScreen absScreen = DefaultGraphicsScreen.createScreenDevice(AbstractGraphicsDevice.EXTERNAL_CONNECTION, 0);
return new EGLExternalContext(absScreen);
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java
index f9934fe20..e9b543721 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java
@@ -224,19 +224,18 @@ public abstract class MacOSXCGLContext extends GLContextImpl
}
}
- protected void updateGLProcAddressTable(int major, int minor, int ctp) {
+ protected final void updateGLXProcAddressTable(int major, int minor, int ctp) {
if (DEBUG) {
System.err.println(getThreadName() + ": !!! Initializing CGL extension address table");
}
- int key = compose8bit(major, minor, ctp, 0);
CGLExtProcAddressTable table = null;
- synchronized(mappedProcAddressLock) {
- table = (CGLExtProcAddressTable) mappedGLXProcAddress.get( key );
+ synchronized(mappedContextTypeObjectLock) {
+ table = (CGLExtProcAddressTable) mappedGLXProcAddress.get( contextFQN );
}
if(null != table) {
cglExtProcAddressTable = table;
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext CGL ProcAddressTable reusing key("+major+","+minor+","+ctp+") -> "+table.hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext CGL ProcAddressTable reusing key("+contextFQN+") -> "+table.hashCode());
}
} else {
if (cglExtProcAddressTable == null) {
@@ -245,14 +244,13 @@ public abstract class MacOSXCGLContext extends GLContextImpl
cglExtProcAddressTable = new CGLExtProcAddressTable(new GLProcAddressResolver());
}
resetProcAddressTable(getCGLExtProcAddressTable());
- synchronized(mappedProcAddressLock) {
- mappedGLXProcAddress.put(key, getCGLExtProcAddressTable());
+ synchronized(mappedContextTypeObjectLock) {
+ mappedGLXProcAddress.put(contextFQN, getCGLExtProcAddressTable());
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext CGL ProcAddressTable mapping key("+major+","+minor+","+ctp+") -> "+getCGLExtProcAddressTable().hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext CGL ProcAddressTable mapping key("+contextFQN+") -> "+getCGLExtProcAddressTable().hashCode());
}
}
}
- super.updateGLProcAddressTable(major, minor, ctp);
}
public String getPlatformExtensionsString()
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java
index 9a02e55ee..f41b68d31 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -47,6 +47,8 @@ import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.util.*;
import com.jogamp.opengl.impl.*;
import com.jogamp.nativewindow.impl.ProxySurface;
+import java.util.HashMap;
+import javax.media.nativewindow.macosx.MacOSXGraphicsDevice;
public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
private static final DesktopGLDynamicLookupHelper macOSXCGLDynamicLookupHelper;
@@ -83,11 +85,43 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
null, getClass().getClassLoader());
} catch (JogampRuntimeException jre) { /* n/a .. */ }
}
+
+ /** FIXME:
+ * find out the Windows semantics of a device connection {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection()}
+ * to actually use multiple devices.
+ */
+ defaultDevice = new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION);
+ }
+
+ static class SharedResource {
+ private MacOSXCGLDrawable drawable;
+ private MacOSXCGLContext context;
+
+ SharedResource(MacOSXCGLDrawable draw, MacOSXCGLContext ctx) {
+ drawable = draw;
+ context = ctx;
+ }
+ }
+ HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
+ MacOSXGraphicsDevice defaultDevice;
+
+ public final AbstractGraphicsDevice getDefaultDevice() {
+ return defaultDevice;
+ }
+
+ public final boolean getIsDeviceCompatible(AbstractGraphicsDevice device) {
+ if(device instanceof MacOSXGraphicsDevice) {
+ return true;
+ }
+ return false;
+ }
+
+ protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) {
+ // FIXME: not implemented .. needs a dummy OSX surface
+ return null;
}
protected void shutdownInstance() {}
- protected final GLDrawableImpl getSharedDrawable() { return null; }
- protected final GLContextImpl getSharedContext() { return null; }
protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) {
if (target == null) {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java
index c9a12c85b..7be597dcc 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java
@@ -49,12 +49,12 @@ import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
public class WindowsWGLContext extends GLContextImpl {
+ private static final Map/*<String, String>*/ functionNameMap;
+ private static final Map/*<String, String>*/ extensionNameMap;
private boolean wglGetExtensionsStringEXTInitialized;
private boolean wglGetExtensionsStringEXTAvailable;
private boolean wglMakeContextCurrentInitialized;
private boolean wglMakeContextCurrentAvailable;
- private static final Map/*<String, String>*/ functionNameMap;
- private static final Map/*<String, String>*/ extensionNameMap;
private WGLExt wglExt;
// Table that holds the addresses of the native C-language entry points for
// WGL extension functions.
@@ -80,6 +80,15 @@ public class WindowsWGLContext extends GLContextImpl {
GLContext shareWith) {
this(drawable, null, shareWith);
}
+
+ protected void resetState() {
+ wglGetExtensionsStringEXTInitialized=false;
+ wglGetExtensionsStringEXTAvailable=false;
+ wglMakeContextCurrentInitialized=false;
+ wglMakeContextCurrentAvailable=false;
+ // no inner state wglExt=null;
+ wglExtProcAddressTable=null;
+ }
public Object getPlatformGLExtensions() {
return getWGLExt();
@@ -120,17 +129,20 @@ public class WindowsWGLContext extends GLContextImpl {
protected Map/*<String, String>*/ getExtensionNameMap() { return extensionNameMap; }
protected void destroyContextARBImpl(long context) {
- WGL.wglMakeCurrent(0, 0);
+ wglMakeContextCurrent(0, 0, 0);
WGL.wglDeleteContext(context);
}
protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) {
WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl();
+ AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsDevice device = config.getScreen().getDevice();
+ WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device);
WGLExt wglExt;
- if(null==factory.getSharedContext()) {
+ if(null==sharedContext) {
wglExt = getWGLExt();
} else {
- wglExt = ((WindowsWGLContext)factory.getSharedContext()).getWGLExt();
+ wglExt = sharedContext.getWGLExt();
}
boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
@@ -171,22 +183,32 @@ public class WindowsWGLContext extends GLContextImpl {
}
}
- ctx = wglExt.wglCreateContextAttribsARB(drawable.getHandle(), share, attribs, 0);
- if(DEBUG) {
- System.err.println("WindowsWGLContext.createContextARB success: "+(0!=ctx)+" - "+getGLVersion(major, minor, ctp, "@creation")+", bwdCompat "+ctBwdCompat+", fwdCompat "+ctFwdCompat);
+ try {
+ ctx = wglExt.wglCreateContextAttribsARB(drawable.getHandle(), share, attribs, 0);
+ } catch (RuntimeException re) {
+ if(DEBUG) {
+ Throwable t = new Throwable("Info: WindowWGLContext.createContextARBImpl wglCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re);
+ t.printStackTrace();
+ }
}
+
if(0!=ctx) {
- // In contrast to GLX no verification with a drawable binding, ie default framebuffer, is necessary,
- // if no 3.2 is available creation fails already!
- // Nevertheless .. we do it ..
- if (!WGL.wglMakeCurrent(drawable.getHandle(), ctx)) {
+ if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), ctx)) {
if(DEBUG) {
System.err.println("WindowsWGLContext.createContextARB couldn't make current "+getGLVersion(major, minor, ctp, "@creation"));
}
WGL.wglMakeCurrent(0, 0);
WGL.wglDeleteContext(ctx);
ctx = 0;
+ } else {
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": createContextARBImpl: OK "+getGLVersion(major, minor, ctp, "@creation")+", share "+share+", direct "+direct+", hasSharedContext "+(null!=sharedContext));
+ }
+ // the following is issued by the caller 'GLContextImpl.createContextARB()'
+ // setGLFunctionAvailability(true, major, minor, ctp);
}
+ } else if (DEBUG) {
+ System.err.println(getThreadName() + ": createContextARBImpl: NO "+getGLVersion(major, minor, ctp, "@creation"));
}
return ctx;
}
@@ -197,6 +219,9 @@ public class WindowsWGLContext extends GLContextImpl {
*/
protected boolean createImpl() {
WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl();
+ AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsDevice device = config.getScreen().getDevice();
+ WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device);
GLCapabilities glCaps = drawable.getChosenGLCapabilities();
// Windows can set up sharing of display lists after creation time
@@ -215,7 +240,7 @@ public class WindowsWGLContext extends GLContextImpl {
boolean createContextARBTried = false;
// utilize the shared context's GLXExt in case it was using the ARB method and it already exists
- if( null!=factory.getSharedContext() && factory.getSharedContext().isCreatedWithARBMethod() ) {
+ if( null!=sharedContext && sharedContext.isCreatedWithARBMethod() ) {
contextHandle = createContextARB(share, true, major, minor, ctp);
createContextARBTried = true;
if (DEBUG && 0!=contextHandle) {
@@ -235,16 +260,24 @@ public class WindowsWGLContext extends GLContextImpl {
throw new GLException("Error making temp context current: 0x" + toHexString(temp_ctx) + ", werr: 0x"+Integer.toHexString(GDI.GetLastError()));
}
setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION
+ boolean isCreateContextAttribsARBAvailable = isFunctionAvailable("wglCreateContextAttribsARB");
WGL.wglMakeCurrent(0, 0); // release temp context
- if( !createContextARBTried &&
- isFunctionAvailable("wglCreateContextAttribsARB") &&
- isExtensionAvailable("WGL_ARB_create_context") ) {
- // initial ARB context creation
- contextHandle = createContextARB(share, true, major, minor, ctp);
- createContextARBTried=true;
- if (DEBUG && 0!=contextHandle) {
- System.err.println(getThreadName() + ": createImpl: OK (ARB, initial) share "+share);
+ if( !createContextARBTried) {
+ if(isCreateContextAttribsARBAvailable &&
+ isExtensionAvailable("WGL_ARB_create_context") ) {
+ // initial ARB context creation
+ contextHandle = createContextARB(share, true, major, minor, ctp);
+ createContextARBTried=true;
+ if (DEBUG) {
+ if(0!=contextHandle) {
+ System.err.println(getThreadName() + ": createContextImpl: OK (ARB, initial) share "+share);
+ } else {
+ System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - creation failed - share "+share);
+ }
+ }
+ } else if (DEBUG) {
+ System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - extension not available - share "+share);
}
}
}
@@ -328,7 +361,7 @@ public class WindowsWGLContext extends GLContextImpl {
}
}
- protected void updateGLProcAddressTable(int major, int minor, int ctp) {
+ protected final void updateGLXProcAddressTable(int major, int minor, int ctp) {
if (DEBUG) {
System.err.println(getThreadName() + ": !!! Initializing WGL extension address table for " + this);
}
@@ -337,15 +370,14 @@ public class WindowsWGLContext extends GLContextImpl {
wglMakeContextCurrentInitialized=false;
wglMakeContextCurrentAvailable=false;
- int key = compose8bit(major, minor, ctp, 0);
WGLExtProcAddressTable table = null;
- synchronized(mappedProcAddressLock) {
- table = (WGLExtProcAddressTable) mappedGLXProcAddress.get( key );
+ synchronized(mappedContextTypeObjectLock) {
+ table = (WGLExtProcAddressTable) mappedGLXProcAddress.get( contextFQN );
}
if(null != table) {
wglExtProcAddressTable = table;
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable reusing key("+major+","+minor+","+ctp+") -> "+table.hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable reusing key("+contextFQN+") -> "+table.hashCode());
}
} else {
if (wglExtProcAddressTable == null) {
@@ -354,14 +386,13 @@ public class WindowsWGLContext extends GLContextImpl {
wglExtProcAddressTable = new WGLExtProcAddressTable(new GLProcAddressResolver());
}
resetProcAddressTable(getWGLExtProcAddressTable());
- synchronized(mappedProcAddressLock) {
- mappedGLXProcAddress.put(key, getWGLExtProcAddressTable());
+ synchronized(mappedContextTypeObjectLock) {
+ mappedGLXProcAddress.put(contextFQN, getWGLExtProcAddressTable());
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable mapping key("+major+","+minor+","+ctp+") -> "+getWGLExtProcAddressTable().hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable mapping key("+contextFQN+") -> "+getWGLExtProcAddressTable().hashCode());
}
}
}
- super.updateGLProcAddressTable(major, minor, ctp);
}
public String getPlatformExtensionsString() {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java
index cea176b1f..f8405961f 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -48,6 +48,7 @@ import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.util.*;
import com.jogamp.opengl.impl.*;
import com.jogamp.nativewindow.impl.ProxySurface;
+import javax.media.nativewindow.windows.WindowsGraphicsDevice;
public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
private static final boolean VERBOSE = Debug.verbose();
@@ -86,57 +87,112 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
} catch (JogampRuntimeException jre) { /* n/a .. */ }
}
- NativeWindowFactory.getDefaultToolkitLock().lock(); // OK
- try {
- sharedDrawable = new WindowsDummyWGLDrawable(this, null);
- WindowsWGLContext ctx = (WindowsWGLContext) sharedDrawable.createContext(null);
- ctx.makeCurrent();
- canCreateGLPbuffer = ctx.getGL().isExtensionAvailable("GL_ARB_pbuffer");
- ctx.release();
- sharedContext = ctx;
- } catch (Throwable t) {
- throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources", t);
- } finally {
- NativeWindowFactory.getDefaultToolkitLock().unlock(); // OK
- }
- if(null==sharedContext) {
- throw new GLException("WindowsWGLDrawableFactory - Shared Context is null");
- }
- if (DEBUG) {
- System.err.println("!!! SharedContext: "+sharedContext+", pbuffer supported "+canCreateGLPbuffer);
- }
+ /** FIXME:
+ * find out the Windows semantics of a device connection {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection()}
+ * to actually use multiple devices.
+ */
+ defaultDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION);
}
- WindowsDummyWGLDrawable sharedDrawable=null;
- WindowsWGLContext sharedContext=null;
- boolean canCreateGLPbuffer = false;
+ static class SharedResource {
+ private WindowsDummyWGLDrawable drawable;
+ private WindowsWGLContext context;
+ private boolean canCreateGLPbuffer;
+
+ SharedResource(WindowsDummyWGLDrawable draw, WindowsWGLContext ctx, boolean canPbuffer) {
+ drawable = draw;
+ context = ctx;
+ canCreateGLPbuffer = canPbuffer;
+ }
+ }
+ HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
+ WindowsGraphicsDevice defaultDevice;
+
+ public final AbstractGraphicsDevice getDefaultDevice() {
+ return defaultDevice;
+ }
- protected final GLDrawableImpl getSharedDrawable() {
- return sharedDrawable;
+ public final boolean getIsDeviceCompatible(AbstractGraphicsDevice device) {
+ if(device instanceof WindowsGraphicsDevice) {
+ return true;
+ }
+ return false;
}
- protected final GLContextImpl getSharedContext() {
- return sharedContext;
+ HashSet devicesTried = new HashSet();
+ private final boolean getDeviceTried(String connection) {
+ synchronized(devicesTried) {
+ return devicesTried.contains(connection);
+ }
+ }
+ private final void addDeviceTried(String connection) {
+ synchronized(devicesTried) {
+ devicesTried.add(connection);
+ }
+ }
+
+ protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) {
+ String connection = device.getConnection();
+ SharedResource sr;
+ synchronized(sharedMap) {
+ sr = (SharedResource) sharedMap.get(connection);
+ }
+ if(null==sr && !getDeviceTried(connection)) {
+ addDeviceTried(connection);
+ NativeWindowFactory.getDefaultToolkitLock().lock(); // OK
+ try {
+ WindowsDummyWGLDrawable sharedDrawable = new WindowsDummyWGLDrawable(this, null);
+ WindowsWGLContext ctx = (WindowsWGLContext) sharedDrawable.createContext(null);
+ ctx.makeCurrent();
+ boolean canCreateGLPbuffer = ctx.getGL().isExtensionAvailable("GL_ARB_pbuffer");
+ ctx.release();
+ sr = new SharedResource(sharedDrawable, ctx, canCreateGLPbuffer);
+ synchronized(sharedMap) {
+ sharedMap.put(device.getConnection(), sr);
+ }
+ if (DEBUG) {
+ System.err.println("!!! SharedContext: "+ctx+", pbuffer supported "+canCreateGLPbuffer);
+ }
+
+ } catch (Throwable t) {
+ throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources", t);
+ } finally {
+ NativeWindowFactory.getDefaultToolkitLock().unlock(); // OK
+ }
+ }
+ if(null!=sr) {
+ return sr.context;
+ }
+ return null;
}
protected void shutdownInstance() {
- if (DEBUG) {
+ if (DEBUG) {
+ Exception e = new Exception("Debug");
+ e.printStackTrace();
+ }
+ Collection/*<SharedResource>*/ sharedResources = sharedMap.values();
+ for(Iterator iter=sharedResources.iterator(); iter.hasNext(); ) {
+ SharedResource sr = (SharedResource) iter.next();
+
+ if (DEBUG) {
System.err.println("!!! Shutdown Shared:");
- System.err.println("!!! CTX : "+sharedContext);
- System.err.println("!!! Drawable: "+sharedDrawable);
- Exception e = new Exception("Debug");
- e.printStackTrace();
- }
- // don't free native resources from this point on,
- // since we might be in a critical shutdown hook sequence
- if(null!=sharedContext) {
- // may cause deadlock: sharedContext.destroy(); // implies release, if current
- sharedContext=null;
- }
- if(null!=sharedDrawable) {
- // may cause deadlock: sharedDrawable.destroy();
- sharedDrawable=null;
- }
+ System.err.println("!!! Drawable: "+sr.drawable);
+ System.err.println("!!! CTX : "+sr.context);
+ }
+
+ if (null != sr.context) {
+ // may cause JVM SIGSEGV: sharedContext.destroy();
+ sr.context = null;
+ }
+
+ if (null != sr.drawable) {
+ // may cause JVM SIGSEGV: sharedDrawable.destroy();
+ sr.drawable = null;
+ }
+
+ }
+ sharedMap.clear();
}
protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) {
@@ -154,13 +210,29 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
}
public boolean canCreateGLPbuffer(AbstractGraphicsDevice device) {
- return canCreateGLPbuffer;
+ SharedResource sr;
+ synchronized(sharedMap) {
+ sr = (SharedResource) sharedMap.get(device.getConnection());
+ }
+ if(null!=sr) {
+ return sr.canCreateGLPbuffer;
+ }
+ return false;
}
protected GLDrawableImpl createGLPbufferDrawableImpl(final NativeSurface target) {
if (target == null) {
throw new IllegalArgumentException("Null target");
}
+ final AbstractGraphicsDevice device = target.getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
+
+ final SharedResource sr;
+ synchronized(sharedMap) {
+ sr = (SharedResource) sharedMap.get(device.getConnection());
+ }
+ if(null==sr) {
+ return null;
+ }
final List returnList = new ArrayList();
Runnable r = new Runnable() {
public void run() {
@@ -168,16 +240,16 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
if (lastContext != null) {
lastContext.release();
}
- synchronized(WindowsWGLDrawableFactory.this.sharedContext) {
- WindowsWGLDrawableFactory.this.sharedContext.makeCurrent();
+ synchronized(sr.context) {
+ sr.context.makeCurrent();
try {
- WGLExt wglExt = WindowsWGLDrawableFactory.this.sharedContext.getWGLExt();
+ WGLExt wglExt = sr.context.getWGLExt();
GLDrawableImpl pbufferDrawable = new WindowsPbufferWGLDrawable(WindowsWGLDrawableFactory.this, target,
- WindowsWGLDrawableFactory.this.sharedDrawable,
+ sr.drawable,
wglExt);
returnList.add(pbufferDrawable);
} finally {
- WindowsWGLDrawableFactory.this.sharedContext.release();
+ sr.context.release();
if (lastContext != null) {
lastContext.makeCurrent();
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java
index 8744b7a37..619034da4 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -65,7 +65,7 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio
throw new GLException("Invalid pixelformat id "+pfdID);
}
if(null==glp) {
- glp = GLProfile.getDefault();
+ glp = GLProfile.getDefault(screen.getDevice());
}
PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor();
if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
index 317751725..d34467fb1 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -98,8 +98,13 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio
throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
}
- boolean choosenBywGLPixelFormat = false;
WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsDevice device = config.getScreen().getDevice();
+ WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device);
+ if(null==sharedContext) {
+ throw new InternalError("SharedContext is null: "+device);
+ }
+ boolean choosenBywGLPixelFormat = false;
GLCapabilities capabilities = (GLCapabilities) config.getRequestedCapabilities();
boolean onscreen = capabilities.isOnscreen();
boolean usePBuffer = capabilities.isPBuffer();
@@ -138,12 +143,11 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio
// Produce a recommended pixel format selection for the GLCapabilitiesChooser.
// Use wglChoosePixelFormatARB if user requested multisampling and if we have it available
int recommendedPixelFormat = pixelFormat; // 1-based pixel format
- boolean gotAvailableCaps = false;
- synchronized(factory.sharedContext) {
- factory.sharedContext.makeCurrent();
+ boolean gotAvailableCaps = false;
+ synchronized(sharedContext) {
+ sharedContext.makeCurrent();
try {
- WGLExt wglExt = factory.sharedContext.getWGLExt();
-
+ WGLExt wglExt = sharedContext.getWGLExt();
boolean haveWGLChoosePixelFormatARB = false;
if (wglExt != null) {
haveWGLChoosePixelFormatARB = wglExt.isExtensionAvailable("WGL_ARB_pixel_format");
@@ -198,7 +202,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio
}
}
} finally {
- factory.sharedContext.release();
+ sharedContext.release();
}
} // synchronized(factory.sharedContext)
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java
index d80da1dd4..75e523cbc 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java
@@ -48,14 +48,15 @@ import com.jogamp.opengl.impl.*;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
import com.jogamp.nativewindow.impl.x11.X11Util;
+import javax.media.nativewindow.x11.X11GraphicsDevice;
public abstract class X11GLXContext extends GLContextImpl {
protected static final boolean TRACE_CONTEXT_CURRENT = false; // true;
- private boolean glXQueryExtensionsStringInitialized;
- private boolean glXQueryExtensionsStringAvailable;
private static final Map/*<String, String>*/ functionNameMap;
private static final Map/*<String, String>*/ extensionNameMap;
+ private boolean glXQueryExtensionsStringInitialized;
+ private boolean glXQueryExtensionsStringAvailable;
private GLXExt glXExt;
// Table that holds the addresses of the native C-language entry points for
// GLX extension functions.
@@ -87,6 +88,15 @@ public abstract class X11GLXContext extends GLContextImpl {
this(drawable, null, shareWith);
}
+ protected void resetState() {
+ glXQueryExtensionsStringInitialized=false;
+ glXQueryExtensionsStringAvailable=false;
+ // no inner state glXExt=null;
+ glXExtProcAddressTable = null;
+ hasSwapIntervalSGI = 0;
+ isDirect = false;
+ }
+
public final ProcAddressTable getPlatformExtProcAddressTable() {
return getGLXExtProcAddressTable();
}
@@ -145,13 +155,15 @@ public abstract class X11GLXContext extends GLContextImpl {
X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl();
X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
- long display = config.getScreen().getDevice().getHandle();
+ AbstractGraphicsDevice device = config.getScreen().getDevice();
+ X11GLXContext sharedContext = (X11GLXContext) factory.getOrCreateSharedContextImpl(device);
+ long display = device.getHandle();
GLXExt glXExt;
- if(null==factory.getSharedContext()) {
+ if(null==sharedContext) {
glXExt = getGLXExt();
} else {
- glXExt = ((X11GLXContext)factory.getSharedContext()).getGLXExt();
+ glXExt = sharedContext.getGLXExt();
}
boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
@@ -192,7 +204,11 @@ public abstract class X11GLXContext extends GLContextImpl {
}
try {
+ // critical path, a remote display might not support this command,
+ // hence we need to catch the X11 Error within this block.
+ X11Util.XSync(display, false);
ctx = glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs, 0);
+ X11Util.XSync(display, false);
} catch (RuntimeException re) {
if(DEBUG) {
Throwable t = new Throwable("Info: X11GLXContext.createContextARBImpl glXCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re);
@@ -210,8 +226,10 @@ public abstract class X11GLXContext extends GLContextImpl {
ctx = 0;
} else {
if (DEBUG) {
- System.err.println(getThreadName() + ": createContextARBImpl: OK "+getGLVersion(major, minor, ctp, "@creation")+", share "+share+", direct "+direct+", hasSharedContext "+(null!=factory.getSharedContext()));
+ System.err.println(getThreadName() + ": createContextARBImpl: OK "+getGLVersion(major, minor, ctp, "@creation")+", share "+share+", direct "+direct+", hasSharedContext "+(null!=sharedContext));
}
+ // the following is issued by the caller 'GLContextImpl.createContextARB()'
+ // setGLFunctionAvailability(true, major, minor, ctp);
}
} else if (DEBUG) {
System.err.println(getThreadName() + ": createContextARBImpl: NO "+getGLVersion(major, minor, ctp, "@creation"));
@@ -236,7 +254,9 @@ public abstract class X11GLXContext extends GLContextImpl {
X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl();
X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
- long display = config.getScreen().getDevice().getHandle();
+ AbstractGraphicsDevice device = config.getScreen().getDevice();
+ X11GLXContext sharedContext = (X11GLXContext) factory.getOrCreateSharedContextImpl(device);
+ long display = device.getHandle();
X11GLXContext other = (X11GLXContext) GLContextShareSet.getShareContext(this);
long share = 0;
@@ -250,7 +270,7 @@ public abstract class X11GLXContext extends GLContextImpl {
GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities();
GLProfile glp = glCaps.getGLProfile();
- isVendorATI = factory.isVendorATI();
+ isVendorATI = factory.isVendorATI(device);
if(config.getFBConfigID()<0) {
// not able to use FBConfig
@@ -278,7 +298,7 @@ public abstract class X11GLXContext extends GLContextImpl {
boolean createContextARBTried = false;
// utilize the shared context's GLXExt in case it was using the ARB method and it already exists
- if(null!=factory.getSharedContext() && factory.getSharedContext().isCreatedWithARBMethod()) {
+ if(null!=sharedContext && sharedContext.isCreatedWithARBMethod()) {
contextHandle = createContextARB(share, direct, major, minor, ctp);
createContextARBTried = true;
if (DEBUG && 0!=contextHandle) {
@@ -298,16 +318,24 @@ public abstract class X11GLXContext extends GLContextImpl {
throw new GLException("Error making temp context(1) current: display "+toHexString(display)+", context "+toHexString(temp_ctx)+", drawable "+drawable);
}
setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION
+ boolean isCreateContextAttribsARBAvailable = isFunctionAvailable("glXCreateContextAttribsARB");
glXMakeContextCurrent(display, 0, 0, 0); // release temp context
- if( !createContextARBTried &&
- isFunctionAvailable("glXCreateContextAttribsARB") &&
- isExtensionAvailable("GLX_ARB_create_context") ) {
- // initial ARB context creation
- contextHandle = createContextARB(share, direct, major, minor, ctp);
- createContextARBTried=true;
- if (DEBUG && 0!=contextHandle) {
- System.err.println(getThreadName() + ": createContextImpl: OK (ARB, initial) share "+share);
+ if( !createContextARBTried ) {
+ if ( isCreateContextAttribsARBAvailable &&
+ isExtensionAvailable("GLX_ARB_create_context") ) {
+ // initial ARB context creation
+ contextHandle = createContextARB(share, direct, major, minor, ctp);
+ createContextARBTried=true;
+ if (DEBUG) {
+ if(0!=contextHandle) {
+ System.err.println(getThreadName() + ": createContextImpl: OK (ARB, initial) share "+share);
+ } else {
+ System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - creation failed - share "+share);
+ }
+ }
+ } else if (DEBUG) {
+ System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - extension not available - share "+share);
}
}
}
@@ -407,36 +435,34 @@ public abstract class X11GLXContext extends GLContextImpl {
// Should check for X errors and raise GLException
}
- protected void updateGLProcAddressTable(int major, int minor, int ctp) {
+ protected final void updateGLXProcAddressTable(int major, int minor, int ctp) {
if (DEBUG) {
System.err.println(getThreadName() + ": !!! Initializing GLX extension address table");
}
glXQueryExtensionsStringInitialized = false;
glXQueryExtensionsStringAvailable = false;
- int key = compose8bit(major, minor, ctp, 0);
GLXExtProcAddressTable table = null;
- synchronized(mappedProcAddressLock) {
- table = (GLXExtProcAddressTable) mappedGLXProcAddress.get( key );
+ synchronized(mappedContextTypeObjectLock) {
+ table = (GLXExtProcAddressTable) mappedGLXProcAddress.get( contextFQN );
}
if(null != table) {
glXExtProcAddressTable = table;
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext GLX ProcAddressTable reusing key("+major+","+minor+","+ctp+") -> "+table.hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext GLX ProcAddressTable reusing key("+contextFQN+") -> "+table.hashCode());
}
} else {
if (glXExtProcAddressTable == null) {
glXExtProcAddressTable = new GLXExtProcAddressTable(new GLProcAddressResolver());
}
resetProcAddressTable(getGLXExtProcAddressTable());
- synchronized(mappedProcAddressLock) {
- mappedGLXProcAddress.put(key, getGLXExtProcAddressTable());
+ synchronized(mappedContextTypeObjectLock) {
+ mappedGLXProcAddress.put(contextFQN, getGLXExtProcAddressTable());
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext GLX ProcAddressTable mapping key("+major+","+minor+","+ctp+") -> "+getGLXExtProcAddressTable().hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext GLX ProcAddressTable mapping key("+contextFQN+") -> "+getGLXExtProcAddressTable().hashCode());
}
}
}
- super.updateGLProcAddressTable(major, minor, ctp);
}
public synchronized String getPlatformExtensionsString() {
@@ -476,8 +502,8 @@ public abstract class X11GLXContext extends GLContextImpl {
try {
hasSwapIntervalSGI = glXExt.isExtensionAvailable("GLX_SGI_swap_control")?1:-1;
} catch (Throwable t) { hasSwapIntervalSGI=1; }
- }
- if (hasSwapIntervalSGI>0) {
+ }
+ if (hasSwapIntervalSGI>0) {
try {
if( 0 == glXExt.glXSwapIntervalSGI(interval) ) {
currentSwapInterval = interval;
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
index 5b5c07a61..7efbc6ed7 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
@@ -47,6 +47,10 @@ import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.util.*;
import com.jogamp.nativewindow.impl.ProxySurface;
import com.jogamp.nativewindow.impl.x11.*;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
@@ -83,43 +87,61 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
} catch (JogampRuntimeException jre) { /* n/a .. */ }
}
+ defaultDevice = new X11GraphicsDevice(X11Util.getNullDisplayName());
+
// Init shared resources via own thread
// Will be released via ShutdownHook
sharedResourcesRunner = new SharedResourcesRunner();
sharedResourcesThread = new Thread(sharedResourcesRunner, Thread.currentThread().getName()+"-SharedResourcesRunner");
sharedResourcesThread.setDaemon(true); // Allow JVM to exit, even if this one is running
sharedResourcesThread.start();
- sharedResourcesRunner.waitUntilInitialized();
-
- if (DEBUG) {
- System.err.println("!!! Vendor: "+vendorName+", ATI: "+isVendorATI+", NV: "+isVendorNVIDIA);
- System.err.println("!!! SharedScreen: "+sharedScreen);
- System.err.println("!!! SharedContext: "+sharedContext);
- }
}
class SharedResourcesRunner implements Runnable {
- boolean initialized = false;
+ boolean ready = false;
boolean released = false;
boolean shouldRelease = false;
+ String initConnection = null;
+ SharedResource result = null;
- public void waitUntilInitialized() {
+ public final void initializeAndWait(String connection) {
+ // wait until thread becomes ready to init new device,
+ // pass the device and release the sync
+ String threadName = Thread.currentThread().getName();
+ if (DEBUG) {
+ System.err.println(threadName+ " initializeAndWait START: "+connection);
+ }
synchronized (this) {
- while (!this.initialized) {
+ while (!ready) {
try {
this.wait();
- } catch (InterruptedException ex) {
- }
+ } catch (InterruptedException ex) { }
+ }
+ if (DEBUG) {
+ System.err.println(threadName+ " initializeAndWait set command: "+connection);
+ }
+ initConnection = connection;
+ this.notifyAll();
+
+ // wait until thread has initialized the device
+ while (!ready || null != initConnection) {
+ try {
+ this.wait();
+ } catch (InterruptedException ex) { }
+ }
+ if (DEBUG) {
+ System.err.println(threadName+ " initializeAndWait done: "+connection);
}
}
+ // done
}
- public void releaseAndWait() {
+ public final void releaseAndWait() {
synchronized (this) {
- this.shouldRelease = true;
+ shouldRelease = true;
this.notifyAll();
- while (!this.released) {
+ while (!released) {
try {
this.wait();
} catch (InterruptedException ex) {
@@ -128,118 +150,244 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
}
- public void run() {
+ public final void run() {
String threadName = Thread.currentThread().getName();
- X11GraphicsDevice sharedDevice;
+
synchronized (this) {
if (DEBUG) {
- System.err.println(threadName+ " initializing START");
+ System.err.println(threadName+ " STARTED -> ready");
}
- sharedDevice = new X11GraphicsDevice(X11Util.createDisplay(null));
- sharedDevice.setCloseDisplay(true);
- X11Util.lockDefaultToolkit(sharedDevice.getHandle()); // OK
- try {
- vendorName = GLXUtil.getVendorName(sharedDevice.getHandle());
- isVendorATI = GLXUtil.isVendorATI(vendorName);
- isVendorNVIDIA = GLXUtil.isVendorNVIDIA(vendorName);
- sharedScreen = new X11GraphicsScreen(sharedDevice, 0);
- sharedDrawable = new X11DummyGLXDrawable(sharedScreen, X11GLXDrawableFactory.this, GLProfile.getDefault());
- if (null == sharedScreen || null == sharedDrawable) {
- throw new GLException("Couldn't init shared screen(" + sharedScreen + ")/drawable(" + sharedDrawable + ")");
- }
+
+ while (!shouldRelease) {
try {
- X11GLXContext ctx = (X11GLXContext) sharedDrawable.createContext(null);
- ctx.makeCurrent();
- ctx.release();
- sharedContext = ctx;
- } catch (Throwable t) {
- throw new GLException("X11GLXDrawableFactory - Could not initialize shared resources", t);
- }
- if (null == sharedContext) {
- throw new GLException("X11GLXDrawableFactory - Shared Context is null");
+ // wait for stop or init
+ ready = true;
+ this.wait();
+ } catch (InterruptedException ex) { }
+ ready = false;
+
+ if(!shouldRelease && null!=initConnection) {
+ if (DEBUG) {
+ System.err.println(threadName+ " create Shared for: "+initConnection);
+ }
+ SharedResource sr = createSharedResource(initConnection);
+ if(null!=sr) {
+ synchronized(sharedMap) {
+ sharedMap.put(initConnection, sr);
+ }
+ }
+ if (DEBUG) {
+ String msg = "Info: (" + threadName + ") initializedSharedResource for device connection: "+initConnection+" -> ready";
+ System.err.println(msg);
+ Throwable t = new Throwable(msg);
+ t.printStackTrace();
+ }
}
- } finally {
- X11Util.unlockDefaultToolkit(sharedDevice.getHandle()); // OK
+ initConnection = null;
+ notifyAll();
}
if (DEBUG) {
- System.err.println(threadName+ " initializing DONE");
+ System.err.println(threadName+ " release START");
+ }
+
+ releaseSharedResources();
+
+ if (DEBUG) {
+ System.err.println(threadName+ " release END");
}
- initialized = true;
+
+ released = true;
+ ready = false;
notifyAll();
}
-
- if (DEBUG) {
- System.err.println(threadName+ " release WAIT");
+ }
+
+ private final SharedResource createSharedResource(String connection) {
+ X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.createDisplay(connection));
+ sharedDevice.setCloseDisplay(true);
+ X11Util.lockDefaultToolkit(sharedDevice.getHandle()); // OK
+ try {
+ String vendorName = GLXUtil.getVendorName(sharedDevice.getHandle());
+ X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, 0);
+ X11DummyGLXDrawable sharedDrawable = new X11DummyGLXDrawable(sharedScreen, X11GLXDrawableFactory.this, GLProfile.getDefault(sharedDevice));
+ if (null == sharedScreen || null == sharedDrawable) {
+ throw new GLException("Couldn't init shared screen(" + sharedScreen + ")/drawable(" + sharedDrawable + ")");
+ }
+ X11GLXContext sharedContext;
+ try {
+ X11GLXContext ctx = (X11GLXContext) sharedDrawable.createContext(null);
+ ctx.makeCurrent();
+ ctx.release();
+ sharedContext = ctx;
+ } catch (Throwable t) {
+ throw new GLException("X11GLXDrawableFactory - Could not initialize shared resources", t);
+ }
+ if (null == sharedContext) {
+ throw new GLException("X11GLXDrawableFactory - Shared Context is null");
+ }
+ if (DEBUG) {
+ System.err.println("!!! SharedDevice: "+sharedDevice);
+ System.err.println("!!! SharedScreen: "+sharedScreen);
+ System.err.println("!!! SharedContext: "+sharedContext);
+ System.err.println("!!! Vendor: "+vendorName);
+ }
+ return new SharedResource(sharedDevice, sharedScreen, sharedDrawable, sharedContext, vendorName);
+ } finally {
+ X11Util.unlockDefaultToolkit(sharedDevice.getHandle()); // OK
}
+ }
+
+ private final void releaseSharedResources() {
+ Collection/*<SharedResource>*/ sharedResources = sharedMap.values();
+ for(Iterator iter=sharedResources.iterator(); iter.hasNext(); ) {
+ SharedResource sr = (SharedResource) iter.next();
- synchronized(this) {
- while (!this.shouldRelease) {
- try {
- this.wait();
- } catch (InterruptedException ex) {
- }
- }
if (DEBUG) {
- System.err.println(threadName+ " release START");
+ System.err.println("!!! Shutdown Shared:");
+ System.err.println("!!! Device : "+sr.device);
+ System.err.println("!!! Screen : "+sr.screen);
+ System.err.println("!!! Drawable: "+sr.drawable);
+ System.err.println("!!! CTX : "+sr.context);
}
- if (null != sharedContext) {
+
+ if (null != sr.context) {
// may cause JVM SIGSEGV: sharedContext.destroy();
- sharedContext = null;
+ sr.context = null;
}
- if (null != sharedDrawable) {
+ if (null != sr.drawable) {
// may cause JVM SIGSEGV: sharedDrawable.destroy();
- sharedDrawable = null;
- }
-
- if (null != sharedScreen) {
- sharedScreen = null;
+ sr.drawable = null;
}
- if (null != sharedDevice) {
- sharedDevice.close();
- sharedDevice = null;
+ if (null != sr.screen) {
+ sr.screen = null;
}
- if (DEBUG) {
- System.err.println(threadName+ " release END");
+ if (null != sr.device) {
+ sr.device.close();
+ sr.device=null;
}
- released = true;
- notifyAll();
}
+ sharedMap.clear();
}
}
-
Thread sharedResourcesThread = null;
SharedResourcesRunner sharedResourcesRunner=null;
- private X11GraphicsScreen sharedScreen=null;
- private X11DummyGLXDrawable sharedDrawable=null;
- private X11GLXContext sharedContext=null;
- private String vendorName;
- private boolean isVendorATI;
- private boolean isVendorNVIDIA;
-
- protected String getVendorName() { return vendorName; }
- protected boolean isVendorATI() { return isVendorATI; }
- protected boolean isVendorNVIDIA() { return isVendorNVIDIA; }
-
- protected final GLDrawableImpl getSharedDrawable() {
- return sharedDrawable;
+
+ static class SharedResource {
+ private X11GraphicsDevice device;
+ private X11GraphicsScreen screen;
+ private X11DummyGLXDrawable drawable;
+ private X11GLXContext context;
+ private String vendorName;
+ private boolean isVendorATI;
+ private boolean isVendorNVIDIA;
+
+ SharedResource(X11GraphicsDevice dev, X11GraphicsScreen scrn, X11DummyGLXDrawable draw, X11GLXContext ctx, String vendor) {
+ device = dev;
+ screen = scrn;
+ drawable = draw;
+ context = ctx;
+ vendorName = vendor;
+ isVendorATI = GLXUtil.isVendorATI(vendorName);
+ isVendorNVIDIA = GLXUtil.isVendorNVIDIA(vendorName);
+ }
}
+ HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
+ SharedResource defaultShare;
+ X11GraphicsDevice defaultDevice;
- protected final GLContextImpl getSharedContext() {
- return sharedContext;
+ public final AbstractGraphicsDevice getDefaultDevice() {
+ return defaultDevice;
}
- protected void shutdownInstance() {
+ public final boolean getIsDeviceCompatible(AbstractGraphicsDevice device) {
+ if(device instanceof X11GraphicsDevice) {
+ return true;
+ }
+ return false;
+ }
+
+ HashSet devicesTried = new HashSet();
+ private final boolean getDeviceTried(String connection) {
+ synchronized(devicesTried) {
+ return devicesTried.contains(connection);
+ }
+ }
+ private final void addDeviceTried(String connection) {
+ synchronized(devicesTried) {
+ devicesTried.add(connection);
+ }
+ }
+
+ protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) {
+ String connection = device.getConnection();
+ boolean deviceTried = getDeviceTried(connection);
+ SharedResource sr;
+ synchronized(sharedMap) {
+ sr = (SharedResource) sharedMap.get(connection);
+ }
+
if (DEBUG) {
- System.err.println("!!! Shutdown Shared:");
- System.err.println("!!! CTX : "+sharedContext);
- System.err.println("!!! Drawable: "+sharedDrawable);
- System.err.println("!!! Screen : "+sharedScreen);
+ System.err.println("getOrCreateSharedContext() "+connection+": has shared "+(null!=sr)+", already tried "+deviceTried);
}
+ if(null==sr && !deviceTried) {
+ if (DEBUG) {
+ System.err.println("getOrCreateSharedContext() "+connection+": trying");
+ }
+ addDeviceTried(connection);
+ sharedResourcesRunner.initializeAndWait(connection);
+ synchronized(sharedMap) {
+ sr = (SharedResource) sharedMap.get(connection);
+ }
+ if(DEBUG) {
+ Throwable t = new Throwable("getOrCreateSharedContextImpl() "+connection+": done");
+ t.printStackTrace();
+ }
+ }
+ if(null!=sr) {
+ return sr.context;
+ }
+ return null;
+ }
+
+ protected final String getVendorName(AbstractGraphicsDevice device) {
+ SharedResource sr;
+ synchronized(sharedMap) {
+ sr = (SharedResource) sharedMap.get(device.getConnection());
+ }
+ if(null!=sr) {
+ return sr.vendorName;
+ }
+ return null;
+ }
+
+ protected final boolean isVendorATI(AbstractGraphicsDevice device) {
+ SharedResource sr;
+ synchronized(sharedMap) {
+ sr = (SharedResource) sharedMap.get(device.getConnection());
+ }
+ if(null!=sr) {
+ return sr.isVendorATI;
+ }
+ return false;
+ }
+
+ protected final boolean isVendorNVIDIA(AbstractGraphicsDevice device) {
+ SharedResource sr;
+ synchronized(sharedMap) {
+ sr = (SharedResource) sharedMap.get(device.getConnection());
+ }
+ if(null!=sr) {
+ return sr.isVendorNVIDIA;
+ }
+ return false;
+ }
+
+ protected void shutdownInstance() {
sharedResourcesRunner.releaseAndWait();
X11Util.shutdown( true, DEBUG );
@@ -268,7 +416,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
protected final boolean glxVersionGreaterEqualThan(AbstractGraphicsDevice device, int majorReq, int minorReq) {
if (!glxVersionsQueried) {
if(null == device) {
- device = (X11GraphicsDevice) sharedScreen.getDevice();
+ device = (X11GraphicsDevice) defaultShare.screen.getDevice();
}
if(null == device) {
throw new GLException("FIXME: No AbstractGraphicsDevice (passed or shared-device");
@@ -302,19 +450,26 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
GLDrawableImpl pbufferDrawable;
+ AbstractGraphicsConfiguration config = target.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsDevice device = config.getScreen().getDevice();
+
/**
* Due to the ATI Bug https://bugzilla.mozilla.org/show_bug.cgi?id=486277,
* we need to have a context current on the same Display to create a PBuffer.
* The dummy context shall also use the same Display,
* since switching Display in this regard is another ATI bug.
*/
- if( isVendorATI() && null == GLContext.getCurrent() ) {
- synchronized(sharedContext) {
- sharedContext.makeCurrent();
+ SharedResource sr;
+ synchronized(sharedMap) {
+ sr = (SharedResource) sharedMap.get(device.getConnection());
+ }
+ if( sr.isVendorATI && null == GLContext.getCurrent() ) {
+ synchronized(sr.context) {
+ sr.context.makeCurrent();
try {
pbufferDrawable = new X11PbufferGLXDrawable(this, target);
} finally {
- sharedContext.release();
+ sr.context.release();
}
}
} else {
@@ -325,7 +480,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
protected NativeSurface createOffscreenSurfaceImpl(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) {
- ProxySurface ns = new ProxySurface(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capabilities, chooser, sharedScreen));
+ ProxySurface ns = new ProxySurface(
+ X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capabilities, chooser, defaultShare.screen));
if(ns != null) {
ns.setSize(width, height);
}
@@ -364,7 +520,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
return gammaRampLength;
}
- long display = sharedScreen.getDevice().getHandle();
+ long display = defaultShare.screen.getDevice().getHandle();
int[] size = new int[1];
boolean res = X11Util.XF86VidModeGetGammaRampSize(display,
@@ -385,7 +541,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
rampData[i] = (short) (ramp[i] * 65535);
}
- long display = sharedScreen.getDevice().getHandle();
+ long display = defaultShare.screen.getDevice().getHandle();
boolean res = X11Util.XF86VidModeSetGammaRamp(display,
X11Util.DefaultScreen(display),
rampData.length,
@@ -407,7 +563,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
rampData.position(2 * size);
rampData.limit(3 * size);
ShortBuffer blueRampData = rampData.slice();
- long display = sharedScreen.getDevice().getHandle();
+ long display = defaultShare.screen.getDevice().getHandle();
boolean res = X11Util.XF86VidModeGetGammaRamp(display,
X11Util.DefaultScreen(display),
size,
@@ -438,7 +594,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
rampData.position(2 * size);
rampData.limit(3 * size);
ShortBuffer blueRampData = rampData.slice();
- long display = sharedScreen.getDevice().getHandle();
+ long display = defaultShare.screen.getDevice().getHandle();
X11Util.XF86VidModeSetGammaRamp(display,
X11Util.DefaultScreen(display),
size,
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java
index 3df9ee541..8661fba5e 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -67,7 +67,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
throw new GLException("FBConfig null of "+toHexString(fbcfgID));
}
if(null==glp) {
- glp = GLProfile.getDefault();
+ glp = GLProfile.getDefault(x11Screen.getDevice());
}
GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display));
if(null==caps) {
diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilities.java b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
index 4368add3f..d48b95c79 100644
--- a/src/jogl/classes/javax/media/opengl/GLCapabilities.java
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
@@ -81,7 +81,7 @@ public class GLCapabilities extends Capabilities implements Cloneable {
* @param glp GLProfile, or null for the default GLProfile
*/
public GLCapabilities(GLProfile glp) {
- glProfile = (null!=glp)?glp:GLProfile.getDefault();
+ glProfile = (null!=glp)?glp:GLProfile.getDefault(GLProfile.getDefaultDevice());
}
public Object clone() {
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index 2f63d5c8e..34ac8e93b 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -40,9 +40,10 @@
package javax.media.opengl;
+import com.jogamp.opengl.impl.Debug;
import java.util.HashMap;
-import com.jogamp.common.util.IntIntHashMap;
-import com.jogamp.common.util.IntObjectHashMap;
+import java.util.HashSet;
+import javax.media.nativewindow.AbstractGraphicsDevice;
/** Abstraction for an OpenGL rendering context. In order to perform
OpenGL rendering, a context must be "made current" on the current
@@ -56,8 +57,9 @@ import com.jogamp.common.util.IntObjectHashMap;
process is handled by the implementation, and the GLContext
abstraction provides a stable object which clients can use to
refer to a given context. */
-
public abstract class GLContext {
+ protected static final boolean DEBUG0 = Debug.debug("GLContext");
+
/** Indicates that the context was not made current during the last call to {@link #makeCurrent makeCurrent}. */
public static final int CONTEXT_NOT_CURRENT = 0;
/** Indicates that the context was made current during the last call to {@link #makeCurrent makeCurrent}. */
@@ -65,6 +67,21 @@ public abstract class GLContext {
/** Indicates that a newly-created context was made current during the last call to {@link #makeCurrent makeCurrent}. */
public static final int CONTEXT_CURRENT_NEW = 2;
+ /** <code>ARB_create_context</code> related: created via ARB_create_context */
+ protected static final int CTX_IS_ARB_CREATED = 1 << 0;
+ /** <code>ARB_create_context</code> related: compatibility profile */
+ protected static final int CTX_PROFILE_COMPAT = 1 << 1;
+ /** <code>ARB_create_context</code> related: core profile */
+ protected static final int CTX_PROFILE_CORE = 1 << 2;
+ /** <code>ARB_create_context</code> related: ES profile */
+ protected static final int CTX_PROFILE_ES = 1 << 3;
+ /** <code>ARB_create_context</code> related: flag forward compatible */
+ protected static final int CTX_OPTION_FORWARD = 1 << 4;
+ /** <code>ARB_create_context</code> related: not flag forward compatible */
+ protected static final int CTX_OPTION_ANY = 1 << 5;
+ /** <code>ARB_create_context</code> related: flag debug */
+ protected static final int CTX_OPTION_DEBUG = 1 << 6;
+
private static ThreadLocal currentContext = new ThreadLocal();
private HashMap/*<int, Object>*/ attachedObjects = new HashMap();
@@ -72,6 +89,26 @@ public abstract class GLContext {
/** The underlying native OpenGL context */
protected long contextHandle;
+ protected GLContext() {
+ resetStates();
+ }
+
+ protected int ctxMajorVersion;
+ protected int ctxMinorVersion;
+ protected int ctxOptions;
+ protected String ctxVersionString;
+
+ protected void resetStates() {
+ ctxMajorVersion=-1;
+ ctxMinorVersion=-1;
+ ctxOptions=0;
+ ctxVersionString=null;
+ if(null!=attachedObjects) {
+ attachedObjects.clear();
+ }
+ contextHandle=0;
+ }
+
/**
* Returns the GLDrawable to which this context may be used to
* draw.
@@ -225,6 +262,8 @@ public abstract class GLContext {
/**
* Returns the GL pipeline object for this GLContext.
+ *
+ * @return the aggregated GL instance, or null if this context was not yet made current.
*/
public abstract GL getGL();
@@ -371,41 +410,26 @@ public abstract class GLContext {
return ctxVersionString;
}
- protected int ctxMajorVersion=-1;
- protected int ctxMinorVersion=-1;
- protected int ctxOptions=0;
- protected String ctxVersionString=null;
-
- /** <code>ARB_create_context</code> related: created via ARB_create_context */
- protected static final int CTX_IS_ARB_CREATED = 1 << 0;
- /** <code>ARB_create_context</code> related: compatibility profile */
- protected static final int CTX_PROFILE_COMPAT = 1 << 1;
- /** <code>ARB_create_context</code> related: core profile */
- protected static final int CTX_PROFILE_CORE = 1 << 2;
- /** <code>ARB_create_context</code> related: ES profile */
- protected static final int CTX_PROFILE_ES = 1 << 3;
- /** <code>ARB_create_context</code> related: flag forward compatible */
- protected static final int CTX_OPTION_FORWARD = 1 << 4;
- /** <code>ARB_create_context</code> related: not flag forward compatible */
- protected static final int CTX_OPTION_ANY = 1 << 5;
- /** <code>ARB_create_context</code> related: flag debug */
- protected static final int CTX_OPTION_DEBUG = 1 << 6;
-
-
public final boolean isGL4bc() {
- return ctxMajorVersion>=4 && 0!=(ctxOptions & CTX_PROFILE_COMPAT);
+ return ctxMajorVersion>=4 && 0 != (ctxOptions & CTX_IS_ARB_CREATED)
+ && 0 != (ctxOptions & CTX_PROFILE_COMPAT);
}
public final boolean isGL4() {
- return ctxMajorVersion>=4 && 0!=(ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE));
+ return ctxMajorVersion>=4 && 0 != (ctxOptions & CTX_IS_ARB_CREATED)
+ && 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE));
}
public final boolean isGL3bc() {
- return ctxMajorVersion>=3 && 0!=(ctxOptions & CTX_PROFILE_COMPAT);
+ return ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=1 )
+ && 0 != (ctxOptions & CTX_IS_ARB_CREATED)
+ && 0 != (ctxOptions & CTX_PROFILE_COMPAT);
}
public final boolean isGL3() {
- return ctxMajorVersion>=3 && 0!=(ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE));
+ return ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=1 )
+ && 0 != (ctxOptions & CTX_IS_ARB_CREATED)
+ && 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE));
}
public final boolean isGL2() {
@@ -483,18 +507,122 @@ public abstract class GLContext {
return true;
}
+ protected static int compose8bit(int one, int two, int three, int four) {
+ return ( ( one & 0x000000FF ) << 24 ) |
+ ( ( two & 0x000000FF ) << 16 ) |
+ ( ( three & 0x000000FF ) << 8 ) |
+ ( ( four & 0x000000FF ) ) ;
+ }
+
+ protected static int getComposed8bit(int bits32, int which ) {
+ switch (which) {
+ case 1: return ( bits32 & 0xFF000000 ) >> 24 ;
+ case 2: return ( bits32 & 0x00FF0000 ) >> 16 ;
+ case 3: return ( bits32 & 0x0000FF00 ) >> 8 ;
+ case 4: return ( bits32 & 0xFF0000FF ) ;
+ }
+ throw new GLException("argument which out of range: "+which);
+ }
+
+ protected static String composed8BitToString(int bits32, boolean hex1, boolean hex2, boolean hex3, boolean hex4) {
+ int a = getComposed8bit(bits32, 1);
+ int b = getComposed8bit(bits32, 2);
+ int c = getComposed8bit(bits32, 3);
+ int d = getComposed8bit(bits32, 4);
+ return "["+toString(a, hex1)+", "+toString(b, hex2)+", "+toString(c, hex3)+", "+toString(d, hex4)+"]";
+ }
+
+ private static void validateProfileBits(int bits, String argName) {
+ int num = 0;
+ if( 0 != ( CTX_PROFILE_COMPAT & bits ) ) { num++; }
+ if( 0 != ( CTX_PROFILE_CORE & bits ) ) { num++; }
+ if( 0 != ( CTX_PROFILE_ES & bits ) ) { num++; }
+ if(1!=num) {
+ throw new GLException("Internal Error: "+argName+": 1 != num-profiles: "+num);
+ }
+ }
+
+ //
+ // version mapping
+ //
+
/**
- * @param major Key Value either 1, 2, 3 or 4
+ * @see #getDeviceVersionAvailableKey(javax.media.nativewindow.AbstractGraphicsDevice, int, int)
+ */
+ protected static /*final*/ HashMap/*<DeviceVersionAvailableKey, Integer>*/ deviceVersionAvailable = new HashMap();
+
+ /**
+ * @see #getUniqueDeviceString(javax.media.nativewindow.AbstractGraphicsDevice)
+ */
+ private static /*final*/ HashSet/*<UniqueDeviceString>*/ deviceVersionsAvailableSet = new HashSet();
+
+ protected static String getContextFQN(AbstractGraphicsDevice device, int major, int minor, int ctp) {
+ return getUniqueDeviceString(device) + "-" + toHexString(compose8bit(major, minor, ctp, 0));
+ }
+
+ protected static String getDeviceVersionAvailableKey(AbstractGraphicsDevice device, int major, int profile) {
+ return getUniqueDeviceString(device) + "-" + toHexString(compose8bit(major, profile, 0, 0));
+ }
+
+ protected static String getUniqueDeviceString(AbstractGraphicsDevice device) {
+ return device.getType() + "_" + device.getConnection() ;
+ }
+
+ protected static boolean getAvailableGLVersionsSet(AbstractGraphicsDevice device) {
+ synchronized ( deviceVersionsAvailableSet ) {
+ return deviceVersionsAvailableSet.contains(getUniqueDeviceString(device));
+ }
+ }
+
+ protected static void setAvailableGLVersionsSet(AbstractGraphicsDevice device) {
+ synchronized ( deviceVersionsAvailableSet ) {
+ String devKey = getUniqueDeviceString(device);
+ if ( deviceVersionsAvailableSet.contains(devKey) ) {
+ throw new InternalError("Already set: "+devKey);
+ }
+ deviceVersionsAvailableSet.add(devKey);
+ if (DEBUG0) {
+ String msg = getThreadName() + ": !!! createContextARB: SET mappedVersionsAvailableSet "+devKey;
+ Throwable t = new Throwable(msg);
+ t.printStackTrace();
+ // System.err.println(msg);
+ }
+ }
+ }
+
+ /**
+ * Called by {@link com.jogamp.opengl.impl.GLContextImpl#createContextARBMapVersionsAvailable} not intended to be used by
+ * implementations. However, if {@link #createContextARB} is not being used within
+ * {@link javax.media.opengl.GLDrawableFactory#getOrCreateSharedContext(javax.media.nativewindow.AbstractGraphicsDevice)},
+ * GLProfile has to map the available versions.
+ *
+ * @param reqMajor Key Value either 1, 2, 3 or 4
* @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
+ * @return the old mapped value
+ *
+ * @see #createContextARBMapVersionsAvailable
*/
- public static final String getGLVersionAvailable(int major, int profile) {
- int _major[] = { 0 };
- int _minor[] = { 0 };
- int _ctp[] = { 0 };
- if(getGLVersionAvailable(major, profile, _major, _minor, _ctp)) {
- return getGLVersion(_major[0], _minor[0], _ctp[0], null);
+ protected static Integer mapAvailableGLVersion(AbstractGraphicsDevice device,
+ int reqMajor, int profile, int resMajor, int resMinor, int resCtp)
+ {
+ validateProfileBits(profile, "profile");
+ validateProfileBits(resCtp, "resCtp");
+
+ String key = getDeviceVersionAvailableKey(device, reqMajor, profile);
+ Integer val = new Integer(compose8bit(resMajor, resMinor, resCtp, 0));
+ synchronized(deviceVersionAvailable) {
+ val = (Integer) deviceVersionAvailable.put( key, val );
}
- return null;
+ return val;
+ }
+
+ protected static Integer getAvailableGLVersion(AbstractGraphicsDevice device, int reqMajor, int profile) {
+ String key = getDeviceVersionAvailableKey(device, reqMajor, profile);
+ Integer val;
+ synchronized(deviceVersionAvailable) {
+ val = (Integer) deviceVersionAvailable.get( key );
+ }
+ return val;
}
/**
@@ -504,15 +632,16 @@ public abstract class GLContext {
* @param minor if not null, returns the used minor version
* @param ctp if not null, returns the used context profile
*/
- public static final boolean getGLVersionAvailable(int reqMajor, int reqProfile, int[] major, int minor[], int ctp[]) {
- int key = compose8bit(reqMajor, reqProfile, 0, 0);
- int val;
- synchronized(mappedVersionsAvailableLock) {
- val = mappedVersionsAvailable.get( key );
- }
- if(val<=0) {
+ protected static boolean getAvailableGLVersion(AbstractGraphicsDevice device,
+ int reqMajor, int reqProfile, int[] major, int minor[], int ctp[]) {
+
+ Integer valI = getAvailableGLVersion(device, reqMajor, reqProfile);
+ if(null==valI) {
return false;
}
+
+ int val = valI.intValue();
+
if(null!=major) {
major[0] = getComposed8bit(val, 1);
}
@@ -529,14 +658,51 @@ public abstract class GLContext {
* @param major Key Value either 1, 2, 3 or 4
* @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
*/
- public static final boolean isGLVersionAvailable(int major, int profile) {
- return getGLVersionAvailable(major, profile, null, null, null);
+ public static boolean isGLVersionAvailable(AbstractGraphicsDevice device, int major, int profile) {
+ return null != getAvailableGLVersion(device, major, profile);
+ }
+
+ public static boolean isGLES1Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 1, GLContext.CTX_PROFILE_ES);
+ }
+
+ public static boolean isGLES2Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 2, GLContext.CTX_PROFILE_ES);
+ }
+
+ public static boolean isGL4bcAvailable(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 4, CTX_PROFILE_COMPAT);
+ }
+
+ public static boolean isGL4Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 4, CTX_PROFILE_CORE);
+ }
+
+ public static boolean isGL3bcAvailable(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 3, CTX_PROFILE_COMPAT);
+ }
+
+ public static boolean isGL3Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 3, CTX_PROFILE_CORE);
+ }
+
+ public static boolean isGL2Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 2, CTX_PROFILE_COMPAT);
+ }
+
+ /**
+ * @param major Key Value either 1, 2, 3 or 4
+ * @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
+ */
+ public static String getAvailableGLVersionAsString(AbstractGraphicsDevice device, int major, int profile) {
+ int _major[] = { 0 };
+ int _minor[] = { 0 };
+ int _ctp[] = { 0 };
+ if(getAvailableGLVersion(device, major, profile, _major, _minor, _ctp)) {
+ return getGLVersion(_major[0], _minor[0], _ctp[0], null);
+ }
+ return null;
}
- public static final boolean isGL4bcAvailable() { return isGLVersionAvailable(4, CTX_PROFILE_COMPAT); }
- public static final boolean isGL4Available() { return isGLVersionAvailable(4, CTX_PROFILE_CORE); }
- public static final boolean isGL3bcAvailable() { return isGLVersionAvailable(3, CTX_PROFILE_COMPAT); }
- public static final boolean isGL3Available() { return isGLVersionAvailable(3, CTX_PROFILE_CORE); }
- public static final boolean isGL2Available() { return isGLVersionAvailable(2, CTX_PROFILE_COMPAT); }
public static String getGLVersion(int major, int minor, int ctp, String gl_version) {
boolean needColon = false;
@@ -560,83 +726,6 @@ public abstract class GLContext {
return sb.toString();
}
- protected static final Object mappedVersionsAvailableLock;
- protected static final IntIntHashMap mappedVersionsAvailable;
- protected static volatile boolean mappedVersionsAvailableSet;
-
- protected static final Object mappedProcAddressLock;
- protected static final IntObjectHashMap mappedGLProcAddress;
- protected static final IntObjectHashMap mappedGLXProcAddress;
-
- static {
- mappedVersionsAvailableLock = new Object();
- mappedVersionsAvailableSet = false;
- mappedVersionsAvailable = new IntIntHashMap();
- mappedVersionsAvailable.setKeyNotFoundValue(-1);
- mappedProcAddressLock = new Object();
- mappedGLProcAddress = new IntObjectHashMap();
- mappedGLProcAddress.setKeyNotFoundValue(null);
- mappedGLXProcAddress = new IntObjectHashMap();
- mappedGLXProcAddress.setKeyNotFoundValue(null);
- }
-
- private static void validateProfileBits(int bits, String argName) {
- int num = 0;
- if( 0 != ( CTX_PROFILE_COMPAT & bits ) ) { num++; }
- if( 0 != ( CTX_PROFILE_CORE & bits ) ) { num++; }
- if( 0 != ( CTX_PROFILE_ES & bits ) ) { num++; }
- if(1!=num) {
- throw new GLException("Internal Error: "+argName+": 1 != num-profiles: "+num);
- }
- }
-
- /**
- * Called by {@link GLContextImpl#createContextARBMapVersionsAvailable} not intendet to be used by
- * implementations. However, if {@link #createContextARB} is not being used within the
- * {@link GLDrawableImpl} constructor, GLProfile has to map the available versions.
- *
- * @param reqMajor Key Value either 1, 2, 3 or 4
- * @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
-
- * @see #createContextARBMapVersionsAvailable
- */
- protected static void mapVersionAvailable(int reqMajor, int profile, int resMajor, int resMinor, int resCtp)
- {
- validateProfileBits(profile, "profile");
- validateProfileBits(resCtp, "resCtp");
-
- int key = compose8bit(reqMajor, profile, 0, 0);
- int val = compose8bit(resMajor, resMinor, resCtp, 0);
- synchronized(mappedVersionsAvailableLock) {
- mappedVersionsAvailable.put( key, val );
- }
- }
-
- protected static int compose8bit(int one, int two, int three, int four) {
- return ( ( one & 0x000000FF ) << 24 ) |
- ( ( two & 0x000000FF ) << 16 ) |
- ( ( three & 0x000000FF ) << 8 ) |
- ( ( four & 0x000000FF ) ) ;
- }
-
- protected static int getComposed8bit(int bits32, int which ) {
- switch (which) {
- case 1: return ( bits32 & 0xFF000000 ) >> 24 ;
- case 2: return ( bits32 & 0x00FF0000 ) >> 16 ;
- case 3: return ( bits32 & 0x0000FF00 ) >> 8 ;
- case 4: return ( bits32 & 0xFF0000FF ) ;
- }
- throw new GLException("argument which out of range: "+which);
- }
-
- protected static String composed8BitToString(int bits32, boolean hex1, boolean hex2, boolean hex3, boolean hex4) {
- int a = getComposed8bit(bits32, 1);
- int b = getComposed8bit(bits32, 2);
- int c = getComposed8bit(bits32, 3);
- int d = getComposed8bit(bits32, 4);
- return "["+toString(a, hex1)+", "+toString(b, hex2)+", "+toString(c, hex3)+", "+toString(d, hex4)+"]";
- }
-
protected static String toString(int val, boolean hex) {
if(hex) {
return "0x" + Integer.toHexString(val);
@@ -662,6 +751,10 @@ public abstract class GLContext {
}
return needColon;
}
+
+ protected static String getThreadName() {
+ return Thread.currentThread().getName();
+ }
}
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index d1bdcdda1..f6dce1c9c 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -47,6 +47,7 @@ import com.jogamp.common.util.ReflectionUtil;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
+import java.util.HashSet;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
@@ -150,6 +151,8 @@ public abstract class GLDrawableFactory {
eglFactory = tmp;
}
+ private AbstractGraphicsDevice defaultSharedDevice = null;
+
protected GLDrawableFactory() {
synchronized(glDrawableFactories) {
glDrawableFactories.add(this);
@@ -168,6 +171,55 @@ public abstract class GLDrawableFactory {
protected abstract void shutdownInstance();
+ /**
+ * Retrieve the default <code>device</code> {@link AbstractGraphicsDevice#getConnection()}. for this factory<br>
+ * The implementation must return a non <code>null</code> default device, which must not be opened, ie. it's native handle may be <code>null</code>.
+ * @return the default shared device for this factory, eg. :0.0 on X11 desktop.
+ */
+ public abstract AbstractGraphicsDevice getDefaultDevice();
+
+ /**
+ * @return true if the device is compatible with this factory, ie. if it can be used for creation. Otherwise false.
+ */
+ public abstract boolean getIsDeviceCompatible(AbstractGraphicsDevice device);
+
+ /**
+ * Returns true if a shared context is already mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()},
+ * or if a new shared context could be created and mapped. Otherwise return false.<br>
+ * Creation of the shared context is tried only once.
+ *
+ * @param device if <code>null</code>, the platform default device is being used
+ */
+ public final boolean getIsSharedContextAvailable(AbstractGraphicsDevice device) {
+ return null != getOrCreateSharedContext(device);
+ }
+
+ /**
+ * Returns the shared context mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()},
+ * either a preexisting or newly created, or <code>null</code> if creation failed or not supported.<br>
+ * Creation of the shared context is tried only once.
+ *
+ * @param device if <code>null</code>, the platform default device is being used
+ */
+ protected final GLContext getOrCreateSharedContext(AbstractGraphicsDevice device) {
+ if(null==device) {
+ device = getDefaultDevice();
+ if(null==device) {
+ throw new InternalError("no default device");
+ }
+ if (GLProfile.DEBUG) {
+ System.err.println("Info: GLDrawableFactory.getOrCreateSharedContext: using default device : "+device);
+ }
+ } else if( !getIsDeviceCompatible(device) ) {
+ if (GLProfile.DEBUG) {
+ System.err.println("Info: GLDrawableFactory.getOrCreateSharedContext: device not compatible : "+device);
+ }
+ return null;
+ }
+ return getOrCreateSharedContextImpl(device);
+ }
+ protected abstract GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device);
+
/**
* Returns the sole GLDrawableFactory instance.
*
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index c5f5a8511..4111eb5a2 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -40,7 +40,6 @@ package javax.media.opengl;
import com.jogamp.common.GlueGenVersion;
import com.jogamp.common.jvm.JVMUtil;
import com.jogamp.common.util.ReflectionUtil;
-import com.jogamp.common.util.VersionUtil;
import com.jogamp.nativewindow.NativeWindowVersion;
import com.jogamp.opengl.impl.Debug;
import com.jogamp.opengl.impl.GLDrawableFactoryImpl;
@@ -50,6 +49,7 @@ import com.jogamp.opengl.JoglVersion;
import java.util.HashMap;
import java.util.Iterator;
import java.security.*;
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.opengl.fixedfunc.GLPointerFunc;
import javax.media.nativewindow.NativeWindowFactory;
@@ -104,18 +104,22 @@ public class GLProfile {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
registerFactoryShutdownHook();
- initProfiles(firstUIActionOnProcess);
+ initProfilesForDefaultDevices(firstUIActionOnProcess);
return null;
}
});
-
- if(null==defaultGLProfile) {
- throw new GLException("No profile available: "+array2String(GL_PROFILE_LIST_ALL)+", "+glAvailabilityToString());
- }
}
}
/**
+ * Trigger eager initialization of GLProfiles for the given device,
+ * in case it isn't done yet.
+ */
+ public static void initProfiles(AbstractGraphicsDevice device) {
+ getProfileMap(device);
+ }
+
+ /**
* Manual shutdown method, may be called after your last JOGL use
* within the running JVM.<br>
* This method is called via the JVM shutdown hook.<br>
@@ -132,87 +136,169 @@ public class GLProfile {
// Query platform available OpenGL implementation
//
- public static final boolean isGL4bcAvailable() { return null != mappedProfiles.get(GL4bc); }
- public static final boolean isGL4Available() { return null != mappedProfiles.get(GL4); }
- public static final boolean isGL3bcAvailable() { return null != mappedProfiles.get(GL3bc); }
- public static final boolean isGL3Available() { return null != mappedProfiles.get(GL3); }
- public static final boolean isGL2Available() { return null != mappedProfiles.get(GL2); }
- public static final boolean isGLES2Available() { return null != mappedProfiles.get(GLES2); }
- public static final boolean isGLES1Available() { return null != mappedProfiles.get(GLES1); }
- public static final boolean isGL2ES1Available() { return null != mappedProfiles.get(GL2ES1); }
- public static final boolean isGL2ES2Available() { return null != mappedProfiles.get(GL2ES2); }
-
- public static final String glAvailabilityToString() {
+ public static boolean isGL4bcAvailable(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL4bc);
+ }
+
+ public static boolean isGL4Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL4);
+ }
+
+ public static boolean isGL3bcAvailable(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL3bc);
+ }
+
+ public static boolean isGL3Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL3);
+ }
+
+ public static boolean isGL2Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL2);
+ }
+
+ public static boolean isGLES2Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GLES2);
+ }
+
+ public static boolean isGLES1Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GLES1);
+ }
+
+ public static boolean isGL2ES1Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL2ES1);
+ }
+
+ public static boolean isGL2ES2Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL2ES2);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL4bcAvailable() {
+ return isGL4bcAvailable(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL4Available() {
+ return isGL4Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL3bcAvailable() {
+ return isGL3bcAvailable(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL3Available() {
+ return isGL3Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL2Available() {
+ return isGL2Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGLES2Available() {
+ return isGLES2Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGLES1Available() {
+ return isGLES1Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL2ES1Available() {
+ return isGL2ES1Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL2ES2Available() {
+ return isGL2ES2Available(null);
+ }
+
+ public static String glAvailabilityToString(AbstractGraphicsDevice device) {
boolean avail;
StringBuffer sb = new StringBuffer();
+ validateInitialization();
+
+ if(null==device) {
+ device = defaultDevice;
+ }
+
sb.append("GLAvailability[Native[GL4bc ");
- avail=isGL4bcAvailable();
+ avail=isGL4bcAvailable(device);
sb.append(avail);
if(avail) {
- glAvailabilityToString(sb, 4, GLContext.CTX_PROFILE_COMPAT);
+ glAvailabilityToString(device, sb, 4, GLContext.CTX_PROFILE_COMPAT);
}
sb.append(", GL4 ");
- avail=isGL4Available();
+ avail=isGL4Available(device);
sb.append(avail);
if(avail) {
- glAvailabilityToString(sb, 4, GLContext.CTX_PROFILE_CORE);
+ glAvailabilityToString(device, sb, 4, GLContext.CTX_PROFILE_CORE);
}
sb.append(", GL3bc ");
- avail=isGL3bcAvailable();
+ avail=isGL3bcAvailable(device);
sb.append(avail);
if(avail) {
- glAvailabilityToString(sb, 3, GLContext.CTX_PROFILE_COMPAT);
+ glAvailabilityToString(device, sb, 3, GLContext.CTX_PROFILE_COMPAT);
}
sb.append(", GL3 ");
- avail=isGL3Available();
+ avail=isGL3Available(device);
sb.append(avail);
if(avail) {
- glAvailabilityToString(sb, 3, GLContext.CTX_PROFILE_CORE);
+ glAvailabilityToString(device, sb, 3, GLContext.CTX_PROFILE_CORE);
}
sb.append(", GL2 ");
- avail=isGL2Available();
+ avail=isGL2Available(device);
sb.append(avail);
if(avail) {
- glAvailabilityToString(sb, 2, GLContext.CTX_PROFILE_COMPAT);
+ glAvailabilityToString(device, sb, 2, GLContext.CTX_PROFILE_COMPAT);
}
sb.append(", GL2ES1 ");
- sb.append(isGL2ES1Available());
+ sb.append(isGL2ES1Available(device));
sb.append(", GLES1 ");
- avail=isGLES1Available();
+ avail=isGLES1Available(device);
sb.append(avail);
if(avail) {
- glAvailabilityToString(sb, 1, GLContext.CTX_PROFILE_ES);
+ glAvailabilityToString(device, sb, 1, GLContext.CTX_PROFILE_ES);
}
sb.append(", GL2ES2 ");
- sb.append(isGL2ES2Available());
+ sb.append(isGL2ES2Available(device));
sb.append(", GLES2 ");
- avail=isGLES2Available();
+ avail=isGLES2Available(device);
sb.append(avail);
if(avail) {
- glAvailabilityToString(sb, 2, GLContext.CTX_PROFILE_ES);
+ glAvailabilityToString(device, sb, 2, GLContext.CTX_PROFILE_ES);
}
sb.append("], Profiles[");
- for(Iterator i=mappedProfiles.values().iterator(); i.hasNext(); ) {
+ for(Iterator i=getProfileMap(device).values().iterator(); i.hasNext(); ) {
sb.append(((GLProfile)i.next()).toString());
sb.append(", ");
}
sb.append(", default ");
- sb.append(defaultGLProfile);
+ sb.append(getDefault(device));
sb.append("]]");
return sb.toString();
}
+ /** Uses the default device */
+ public static String glAvailabilityToString() {
+ return glAvailabilityToString(null);
+ }
+
//
// Public (user-visible) profiles
//
@@ -249,6 +335,9 @@ public class GLProfile {
/** The intersection of the desktop GL3 and GL2 profile */
public static final String GL2GL3 = "GL2GL3";
+ /** The default profile, used for the device default profile map */
+ private static final String GL_DEFAULT = "GL_DEFAULT";
+
/**
* All GL Profiles in the order of default detection.
* Desktop compatibility profiles (the one with fixed function pipeline) comes first.
@@ -337,12 +426,14 @@ public class GLProfile {
* It selects the first of the set {@link GLProfile#GL_PROFILE_LIST_ALL}
* @see #GL_PROFILE_LIST_ALL
*/
- public static final GLProfile getDefault() {
- validateInitialization();
- if(null==defaultGLProfile) {
- throw new GLException("No default profile available"); // should never be reached
- }
- return defaultGLProfile;
+ public static GLProfile getDefault(AbstractGraphicsDevice device) {
+ GLProfile glp = get(device, GL_DEFAULT);
+ return glp;
+ }
+
+ /** Uses the default device */
+ public static GLProfile getDefault() {
+ return getDefault(defaultDevice);
}
/**
@@ -352,7 +443,14 @@ public class GLProfile {
* @throws GLException if no implementation for the given profile is found.
* @see #GL_PROFILE_LIST_MAX_FIXEDFUNC
*/
- public static final GLProfile getMaxFixedFunc()
+ public static GLProfile getMaxFixedFunc(AbstractGraphicsDevice device)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_MAX_FIXEDFUNC);
+ }
+
+ /** Uses the default device */
+ public static GLProfile getMaxFixedFunc()
throws GLException
{
return get(GL_PROFILE_LIST_MAX_FIXEDFUNC);
@@ -365,7 +463,14 @@ public class GLProfile {
* @throws GLException if no implementation for the given profile is found.
* @see #GL_PROFILE_LIST_MAX_PROGSHADER
*/
- public static final GLProfile getMaxProgrammable()
+ public static GLProfile getMaxProgrammable(AbstractGraphicsDevice device)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_MAX_PROGSHADER);
+ }
+
+ /** Uses the default device */
+ public static GLProfile getMaxProgrammable()
throws GLException
{
return get(GL_PROFILE_LIST_MAX_PROGSHADER);
@@ -378,7 +483,14 @@ public class GLProfile {
* @throws GLException if no implementation for the given profile is found.
* @see #GL_PROFILE_LIST_GL2ES1
*/
- public static final GLProfile getGL2ES1()
+ public static GLProfile getGL2ES1(AbstractGraphicsDevice device)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_GL2ES1);
+ }
+
+ /** Uses the default device */
+ public static GLProfile getGL2ES1()
throws GLException
{
return get(GL_PROFILE_LIST_GL2ES1);
@@ -391,29 +503,40 @@ public class GLProfile {
* @throws GLException if no implementation for the given profile is found.
* @see #GL_PROFILE_LIST_GL2ES2
*/
- public static final GLProfile getGL2ES2()
+ public static GLProfile getGL2ES2(AbstractGraphicsDevice device)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_GL2ES2);
+ }
+
+ /** Uses the default device */
+ public static GLProfile getGL2ES2()
throws GLException
{
return get(GL_PROFILE_LIST_GL2ES2);
}
/** Returns a GLProfile object.
- * Verfifies the given profile and chooses an apropriate implementation.
+ * verifies the given profile and chooses an appropriate implementation.
* A generic value of <code>null</code> or <code>GL</code> will result in
* the default profile.
*
* @throws GLException if no implementation for the given profile is found.
*/
- public static final GLProfile get(String profile)
+ public static GLProfile get(AbstractGraphicsDevice device, String profile)
throws GLException
{
- validateInitialization();
- if(null==profile || profile.equals("GL")) return getDefault();
- GLProfile glProfile = (GLProfile) mappedProfiles.get(profile);
- if(null==glProfile) {
- throw new GLException("No implementation for profile "+profile+" available");
+ if(null==profile || profile.equals("GL")) {
+ profile = GL_DEFAULT;
}
- return glProfile;
+ return (GLProfile) getProfileMap(device).get(profile);
+ }
+
+ /** Uses the default device */
+ public static GLProfile get(String profile)
+ throws GLException
+ {
+ return get(defaultDevice, profile);
}
/**
@@ -422,36 +545,43 @@ public class GLProfile {
*
* @throws GLException if no implementation for the given profile is found.
*/
- public static final GLProfile get(String[] profiles)
+ public static GLProfile get(AbstractGraphicsDevice device, String[] profiles)
throws GLException
{
- validateInitialization();
+ HashMap map = getProfileMap(device);
for(int i=0; i<profiles.length; i++) {
String profile = profiles[i];
- GLProfile glProfile = (GLProfile) mappedProfiles.get(profile);
+ GLProfile glProfile = (GLProfile) map.get(profile);
if(null!=glProfile) {
return glProfile;
}
}
- throw new GLException("Profiles "+array2String(profiles)+" not available");
+ throw new GLException("Profiles "+array2String(profiles)+" not available on device "+device);
+ }
+
+ /** Uses the default device */
+ public static GLProfile get(String[] profiles)
+ throws GLException
+ {
+ return get(defaultDevice, profiles);
}
/** Indicates whether the native OpenGL ES1 profile is in use.
* This requires an EGL interface.
*/
- public static final boolean usesNativeGLES1(String profileImpl) {
+ public static boolean usesNativeGLES1(String profileImpl) {
return GLES1.equals(profileImpl);
}
/** Indicates whether the native OpenGL ES2 profile is in use.
- * This requires an EGL interface.
+ * This requires an EGL or ES2 compatible interface.
*/
- public static final boolean usesNativeGLES2(String profileImpl) {
+ public static boolean usesNativeGLES2(String profileImpl) {
return GLES2.equals(profileImpl);
}
/** Indicates whether either of the native OpenGL ES profiles are in use. */
- public static final boolean usesNativeGLES(String profileImpl) {
+ public static boolean usesNativeGLES(String profileImpl) {
return usesNativeGLES2(profileImpl) || usesNativeGLES1(profileImpl);
}
@@ -922,20 +1052,16 @@ public class GLProfile {
private static /*final*/ boolean isAWTAvailable;
+ private static /*final*/ boolean hasDesktopGL;
private static /*final*/ boolean hasGL234Impl;
- private static /*final*/ boolean hasGL4bcImpl;
- private static /*final*/ boolean hasGL4Impl;
- private static /*final*/ boolean hasGL3bcImpl;
- private static /*final*/ boolean hasGL3Impl;
- private static /*final*/ boolean hasGL2Impl;
private static /*final*/ boolean hasGLES2Impl;
private static /*final*/ boolean hasGLES1Impl;
- /** The JVM/process wide default GL profile **/
- private static /*final*/ GLProfile defaultGLProfile;
-
- /** All GLProfiles */
- private static /*final*/ HashMap/*<String, GLProfile>*/ mappedProfiles;
+ private static /*final*/ GLDrawableFactoryImpl eglFactory;
+ private static /*final*/ GLDrawableFactoryImpl desktopFactory;
+ private static /*final*/ AbstractGraphicsDevice defaultDevice;
+ private static /*final*/ AbstractGraphicsDevice defaultDesktopDevice;
+ private static /*final*/ AbstractGraphicsDevice defaultEGLDevice;
static boolean initialized = false;
@@ -947,7 +1073,11 @@ public class GLProfile {
* Tries the profiles implementation and native libraries.
* Throws an GLException if no profile could be found at all.
*/
- private static void initProfiles(boolean firstUIActionOnProcess) {
+ private static void initProfilesForDefaultDevices(boolean firstUIActionOnProcess) {
+
+ if(DEBUG) {
+ System.err.println("GLProfile.init firstUIActionOnProcess "+firstUIActionOnProcess);
+ }
NativeWindowFactory.initSingleton(firstUIActionOnProcess);
@@ -957,17 +1087,7 @@ public class GLProfile {
ReflectionUtil.isClassAvailable("javax.media.opengl.awt.GLCanvas", classloader) ; // JOGL
hasGL234Impl = ReflectionUtil.isClassAvailable("com.jogamp.opengl.impl.gl4.GL4bcImpl", classloader);
- hasGL4bcImpl = hasGL234Impl;
- hasGL4Impl = hasGL234Impl;
- hasGL3bcImpl = hasGL234Impl;
- hasGL3Impl = hasGL234Impl;
- hasGL2Impl = hasGL234Impl;
- mappedProfiles = computeProfileMap();
-
- boolean hasDesktopGL = false;
- boolean hasNativeOSFactory = false;
- Throwable t;
-
+
//
// Iteration of desktop GL availability detection
// utilizing the detected GL version in the shared context.
@@ -975,14 +1095,12 @@ public class GLProfile {
// - Instantiate GLDrawableFactory incl its shared dummy drawable/context,
// which will register at GLContext ..
//
-
- t=null;
+ Throwable t=null;
// if successfull it has a shared dummy drawable and context created
try {
- GLDrawableFactoryImpl factory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GL2);
- hasNativeOSFactory = null != factory;
- if(hasNativeOSFactory) {
- DesktopGLDynamicLookupHelper glLookupHelper = (DesktopGLDynamicLookupHelper) factory.getGLDynamicLookupHelper(0);
+ desktopFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GL2);
+ if(null != desktopFactory) {
+ DesktopGLDynamicLookupHelper glLookupHelper = (DesktopGLDynamicLookupHelper) desktopFactory.getGLDynamicLookupHelper(0);
if(null!=glLookupHelper) {
hasDesktopGL = glLookupHelper.hasGLBinding();
}
@@ -998,43 +1116,29 @@ public class GLProfile {
if(null!=t) {
t.printStackTrace();
}
- if(!hasNativeOSFactory) {
- System.err.println("Info: GLProfile.init - Native platform GLDrawable factory not available");
+ if(null == desktopFactory) {
+ System.err.println("Info: GLProfile.init - Desktop GLDrawable factory not available");
}
}
- if(hasDesktopGL && !GLContext.mappedVersionsAvailableSet) {
- // nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent},
- // so we have to add the usual suspect
- GLContext.mapVersionAvailable(2, GLContext.CTX_PROFILE_COMPAT, 1, 5, GLContext.CTX_PROFILE_COMPAT|GLContext.CTX_OPTION_ANY);
- }
-
- if(!hasNativeOSFactory) {
+ if(null == desktopFactory) {
hasDesktopGL = false;
hasGL234Impl = false;
- hasGL4bcImpl = false;
- hasGL4Impl = false;
- hasGL3bcImpl = false;
- hasGL3Impl = false;
- hasGL2Impl = false;
} else {
- hasGL4bcImpl = hasGL4bcImpl && GLContext.isGL4bcAvailable();
- hasGL4Impl = hasGL4Impl && GLContext.isGL4Available();
- hasGL3bcImpl = hasGL3bcImpl && GLContext.isGL3bcAvailable();
- hasGL3Impl = hasGL3Impl && GLContext.isGL3Available();
- hasGL2Impl = hasGL2Impl && GLContext.isGL2Available();
+ defaultDesktopDevice = desktopFactory.getDefaultDevice();
+ defaultDevice = defaultDesktopDevice;
}
if ( ReflectionUtil.isClassAvailable("com.jogamp.opengl.impl.egl.EGLDrawableFactory", classloader) ) {
t=null;
try {
- GLDrawableFactoryImpl factory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GLES2);
- if(null != factory) {
- GLDynamicLookupHelper eglLookupHelper = factory.getGLDynamicLookupHelper(2);
+ eglFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GLES2);
+ if(null != eglFactory) {
+ GLDynamicLookupHelper eglLookupHelper = eglFactory.getGLDynamicLookupHelper(2);
if(null!=eglLookupHelper) {
hasGLES2Impl = eglLookupHelper.isLibComplete();
}
- eglLookupHelper = factory.getGLDynamicLookupHelper(1);
+ eglLookupHelper = eglFactory.getGLDynamicLookupHelper(1);
if(null!=eglLookupHelper) {
hasGLES1Impl = eglLookupHelper.isLibComplete();
}
@@ -1048,30 +1152,151 @@ public class GLProfile {
} catch (RuntimeException re) {
t=re;
}
- if(DEBUG && null!=t) {
- t.printStackTrace();
+ if(DEBUG) {
+ if(null!=t) {
+ t.printStackTrace();
+ }
+ if(null == eglFactory) {
+ System.err.println("Info: GLProfile.init - EGL GLDrawable factory not available");
+ }
}
}
- if(hasGLES2Impl) {
- GLContext.mapVersionAvailable(2, GLContext.CTX_PROFILE_ES, 2, 0, GLContext.CTX_PROFILE_ES|GLContext.CTX_OPTION_ANY);
+
+ if(null == eglFactory) {
+ hasGLES2Impl = false;
+ hasGLES1Impl = false;
+ } else {
+ defaultEGLDevice = eglFactory.getDefaultDevice();
+ if (null==defaultDevice) {
+ defaultDevice = defaultEGLDevice;
+ }
+ }
+
+ boolean addedAnyProfile = initProfilesForDevice(defaultDesktopDevice);
+ addedAnyProfile = addedAnyProfile || initProfilesForDevice(defaultEGLDevice);
+
+ if(DEBUG) {
+ System.err.println(GlueGenVersion.getInstance());
+ System.err.println(NativeWindowVersion.getInstance());
+ System.err.print(JoglVersion.getInstance());
+
+ System.err.println("GLProfile.init isAWTAvailable "+isAWTAvailable);
+ System.err.println("GLProfile.init has desktopFactory "+(null!=desktopFactory));
+ System.err.println("GLProfile.init hasDesktopGL "+hasDesktopGL);
+ System.err.println("GLProfile.init hasGL234Impl "+hasGL234Impl);
+ System.err.println("GLProfile.init has eglFactory "+(null!=eglFactory));
+ System.err.println("GLProfile.init hasGLES1Impl "+hasGLES1Impl);
+ System.err.println("GLProfile.init hasGLES2Impl "+hasGLES2Impl);
+ System.err.println("GLProfile.init defaultDesktopDevice "+defaultDevice);
+ System.err.println("GLProfile.init defaultEGLDevice "+defaultDevice);
+ System.err.println("GLProfile.init defaultDevice "+defaultDevice);
+ }
+
+ if(!addedAnyProfile) {
+ throw new GLException("No profile available: "+array2String(GL_PROFILE_LIST_ALL)+", "+ glAvailabilityToString());
}
- if(hasGLES1Impl) {
- GLContext.mapVersionAvailable(1, GLContext.CTX_PROFILE_ES, 1, 0, GLContext.CTX_PROFILE_ES|GLContext.CTX_OPTION_ANY);
+ }
+
+ /**
+ * @param device the device for which profiles shall be initialized
+ * @return true if any profile for the device exists, otherwise false
+ */
+ private static synchronized boolean initProfilesForDevice(AbstractGraphicsDevice device) {
+ boolean isSet = GLContext.getAvailableGLVersionsSet(device);
+
+ if(DEBUG) {
+ String msg = "Info: GLProfile.initProfilesForDevice: "+device.getConnection()+", isSet "+isSet;
+ Throwable t = new Throwable(msg);
+ t.printStackTrace();
+ // System.err.println(msg);
+ }
+ if(isSet) {
+ return null != GLProfile.getDefault(device);
+ }
+
+ boolean addedAnyProfile = false;
+
+ if( hasDesktopGL && desktopFactory.getIsDeviceCompatible(device)) {
+ // 1st pretend we have all Desktop and EGL profiles ..
+ computeProfileMap(device, true /* desktopCtxUndef*/, true /* eglCtxUndef */);
+
+ // Triggers eager initialization of share context in GLDrawableFactory for the device,
+ // hence querying all available GLProfiles
+ boolean desktopSharedCtxAvail = desktopFactory.getIsSharedContextAvailable(device);
+ if (DEBUG) {
+ System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": desktop Shared Ctx "+desktopSharedCtxAvail);
+ }
+ if( null == GLContext.getAvailableGLVersion(device, 2, GLContext.CTX_PROFILE_COMPAT) ) {
+ // nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent},
+ // so we have to add the usual suspect
+ GLContext.mapAvailableGLVersion(device,
+ 2, GLContext.CTX_PROFILE_COMPAT,
+ 1, 5, GLContext.CTX_PROFILE_COMPAT|GLContext.CTX_OPTION_ANY);
+ }
+ computeProfileMap(device, false /* desktopCtxUndef*/, false /* eglCtxUndef */);
+ addedAnyProfile = null != GLProfile.getDefault(device);
+ } else {
+ if(DEBUG) {
+ System.err.println("GLProfile: DesktopFactory - Device is not available: "+device.getConnection());
+ }
}
- mappedProfiles = computeProfileMap();
+ if( null!=eglFactory && ( hasGLES2Impl || hasGLES1Impl ) && eglFactory.getIsDeviceCompatible(device)) {
+ // 1st pretend we have all EGL profiles ..
+ computeProfileMap(device, false /* desktopCtxUndef*/, true /* eglCtxUndef */);
+
+ // Triggers eager initialization of share context in GLDrawableFactory for the device,
+ // hence querying all available GLProfiles
+ boolean eglSharedCtxAvail = eglFactory.getIsSharedContextAvailable(device);
+ if (DEBUG) {
+ System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": egl Shared Ctx "+eglSharedCtxAvail);
+ }
+ if(hasGLES2Impl && null == GLContext.getAvailableGLVersion(device, 2, GLContext.CTX_PROFILE_ES) ) {
+ // nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent},
+ // so we have to add the usual suspect
+ GLContext.mapAvailableGLVersion(device,
+ 2, GLContext.CTX_PROFILE_ES,
+ 2, 0, GLContext.CTX_PROFILE_ES|GLContext.CTX_OPTION_ANY);
+ }
+ if(hasGLES1Impl && null == GLContext.getAvailableGLVersion(device, 1, GLContext.CTX_PROFILE_ES)) {
+ // nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent},
+ // so we have to add the usual suspect
+ GLContext.mapAvailableGLVersion(device,
+ 1, GLContext.CTX_PROFILE_ES,
+ 1, 0, GLContext.CTX_PROFILE_ES|GLContext.CTX_OPTION_ANY);
+ }
+ computeProfileMap(device, false /* desktopCtxUndef*/, false /* eglCtxUndef */);
+ addedAnyProfile = addedAnyProfile || null != GLProfile.getDefault(device);
+ } else {
+ if(DEBUG) {
+ System.err.println("GLProfile: EGLFactory - Device is not available: "+device.getConnection());
+ }
+ }
+ if(!GLContext.getAvailableGLVersionsSet(device)) {
+ GLContext.setAvailableGLVersionsSet(device);
+ }
if (DEBUG) {
- System.err.println(GlueGenVersion.getInstance().getInfo(null));
- System.err.println(NativeWindowVersion.getInstance().getInfo(null));
- System.err.print(JoglVersion.getInstance().getInfo(null));
- System.err.println("GLProfile.init firstUIActionOnProcess "+firstUIActionOnProcess);
- System.err.println("GLProfile.init isAWTAvailable "+isAWTAvailable);
- System.err.println("GLProfile.init hasNativeOSFactory "+hasNativeOSFactory);
- System.err.println("GLProfile.init hasDesktopGL "+hasDesktopGL);
- System.err.println("GLProfile.init hasGL234Impl "+hasGL234Impl);
- System.err.println("GLProfile.init "+glAvailabilityToString());
+ System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": added profile(s): "+addedAnyProfile);
+ System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": "+glAvailabilityToString(device));
}
+
+ return addedAnyProfile;
+ }
+
+ public static AbstractGraphicsDevice getDefaultDevice() {
+ validateInitialization();
+ return defaultDevice;
+ }
+
+ public static AbstractGraphicsDevice getDefaultDesktopDevice() {
+ validateInitialization();
+ return defaultDesktopDevice;
+ }
+
+ public static AbstractGraphicsDevice getDefaultEGLDevice() {
+ validateInitialization();
+ return defaultEGLDevice;
}
private static synchronized void registerFactoryShutdownHook() {
@@ -1102,7 +1327,7 @@ public class GLProfile {
}
}
- private static final String array2String(String[] list) {
+ private static String array2String(String[] list) {
StringBuffer msg = new StringBuffer();
msg.append("[");
for (int i = 0; i < list.length; i++) {
@@ -1114,8 +1339,8 @@ public class GLProfile {
return msg.toString();
}
- private static final void glAvailabilityToString(StringBuffer sb, int major, int profile) {
- String str = GLContext.getGLVersionAvailable(major, profile);
+ private static void glAvailabilityToString(AbstractGraphicsDevice device, StringBuffer sb, int major, int profile) {
+ String str = GLContext.getAvailableGLVersionAsString(device, major, profile);
if(null==str) {
throw new GLException("Internal Error");
}
@@ -1124,103 +1349,152 @@ public class GLProfile {
sb.append("]");
}
- private static HashMap computeProfileMap() {
- defaultGLProfile=null;
- HashMap/*<String, GLProfile>*/ _mappedProfiles = new HashMap(GL_PROFILE_LIST_ALL.length);
+ private static void computeProfileMap(AbstractGraphicsDevice device, boolean desktopCtxUndef, boolean eglCtxUndef) {
+ if (DEBUG) {
+ System.err.println("GLProfile.init map "+device.getConnection()+", desktopCtxUndef "+desktopCtxUndef+", eglCtxUndef "+eglCtxUndef);
+ }
+ GLProfile defaultGLProfile = null;
+ HashMap/*<String, GLProfile>*/ _mappedProfiles = new HashMap(GL_PROFILE_LIST_ALL.length + 1 /* default */);
for(int i=0; i<GL_PROFILE_LIST_ALL.length; i++) {
String profile = GL_PROFILE_LIST_ALL[i];
- String profileImpl = computeProfileImpl(profile);
+ String profileImpl = computeProfileImpl(device, profile, desktopCtxUndef, eglCtxUndef);
if(null!=profileImpl) {
GLProfile glProfile = new GLProfile(profile, profileImpl);
_mappedProfiles.put(profile, glProfile);
if (DEBUG) {
- System.err.println("GLProfile.init map "+glProfile);
+ System.err.println("GLProfile.init map "+glProfile+" on devide "+device.getConnection());
}
if(null==defaultGLProfile) {
defaultGLProfile=glProfile;
if (DEBUG) {
- System.err.println("GLProfile.init default "+glProfile);
+ System.err.println("GLProfile.init map default "+glProfile+" on device "+device.getConnection());
}
}
} else {
if (DEBUG) {
- System.err.println("GLProfile.init map *** no mapping for "+profile);
+ System.err.println("GLProfile.init map *** no mapping for "+profile+" on device "+device.getConnection());
}
}
}
- return _mappedProfiles;
- }
-
- private static final String getGLImplBaseClassName(String profileImpl) {
- if ( GL4bc.equals(profileImpl) ||
- GL4.equals(profileImpl) ||
- GL3bc.equals(profileImpl) ||
- GL3.equals(profileImpl) ||
- GL2.equals(profileImpl) ) {
- return "com.jogamp.opengl.impl.gl4.GL4bc";
- } else if(GLES1.equals(profileImpl) || GL2ES1.equals(profileImpl)) {
- return "com.jogamp.opengl.impl.es1.GLES1";
- } else if(GLES2.equals(profileImpl) || GL2ES2.equals(profileImpl)) {
- return "com.jogamp.opengl.impl.es2.GLES2";
- } else {
- throw new GLException("unsupported profile \"" + profileImpl + "\"");
+ if(null!=defaultGLProfile) {
+ _mappedProfiles.put(GL_DEFAULT, defaultGLProfile);
}
+ setProfileMap(device, _mappedProfiles);
}
/**
* Returns the profile implementation
*/
- private static String computeProfileImpl(String profile) {
+ private static String computeProfileImpl(AbstractGraphicsDevice device, String profile, boolean desktopCtxUndef, boolean eglCtxUndef) {
if (GL2ES1.equals(profile)) {
- if(hasGL2Impl) {
- return GL2;
- } else if(hasGL3bcImpl) {
- return GL3bc;
- } else if(hasGL4bcImpl) {
- return GL4bc;
- } else if(hasGLES1Impl) {
+ if(hasGL234Impl) {
+ if(desktopCtxUndef || GLContext.isGL2Available(device)) {
+ return GL2;
+ } else if(GLContext.isGL3bcAvailable(device)) {
+ return GL3bc;
+ } else if(GLContext.isGL4bcAvailable(device)) {
+ return GL4bc;
+ }
+ }
+ if(hasGLES1Impl && ( eglCtxUndef || GLContext.isGLES1Available(device))) {
return GLES1;
}
} else if (GL2ES2.equals(profile)) {
- if(hasGL2Impl) {
- return GL2;
- } else if(hasGL3Impl) {
- return GL3;
- } else if(hasGL4Impl) {
- return GL4;
- } else if(hasGLES2Impl) {
+ if(hasGL234Impl) {
+ if(desktopCtxUndef || GLContext.isGL2Available(device)) {
+ return GL2;
+ } else if(GLContext.isGL3Available(device)) {
+ return GL3;
+ } else if(GLContext.isGL4Available(device)) {
+ return GL4;
+ }
+ }
+ if(hasGLES2Impl && ( eglCtxUndef || GLContext.isGLES2Available(device))) {
return GLES2;
}
} else if(GL2GL3.equals(profile)) {
- if(hasGL2Impl) {
- return GL2;
- } else if(hasGL3bcImpl) {
- return GL3bc;
- } else if(hasGL4bcImpl) {
- return GL4bc;
- } else if(hasGL3Impl) {
- return GL3;
- } else if(hasGL4Impl) {
- return GL4;
+ if(hasGL234Impl) {
+ if(desktopCtxUndef || GLContext.isGL2Available(device)) {
+ return GL2;
+ } else if(GLContext.isGL3bcAvailable(device)) {
+ return GL3bc;
+ } else if(GLContext.isGL4bcAvailable(device)) {
+ return GL4bc;
+ } else if(GLContext.isGL3Available(device)) {
+ return GL3;
+ } else if(GLContext.isGL4Available(device)) {
+ return GL4;
+ }
}
- } else if(GL4bc.equals(profile) && hasGL4bcImpl) {
+ } else if(GL4bc.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL4bcAvailable(device))) {
return GL4bc;
- } else if(GL4.equals(profile) && hasGL4Impl) {
+ } else if(GL4.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL4Available(device))) {
return GL4;
- } else if(GL3bc.equals(profile) && hasGL3bcImpl) {
+ } else if(GL3bc.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL3bcAvailable(device))) {
return GL3bc;
- } else if(GL3.equals(profile) && hasGL3Impl) {
+ } else if(GL3.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL3Available(device))) {
return GL3;
- } else if(GL2.equals(profile) && hasGL2Impl) {
+ } else if(GL2.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL2Available(device))) {
return GL2;
- } else if(GLES2.equals(profile) && hasGLES2Impl) {
+ } else if(GLES2.equals(profile) && hasGLES2Impl && ( eglCtxUndef || GLContext.isGLES2Available(device))) {
return GLES2;
- } else if(GLES1.equals(profile) && hasGLES1Impl) {
+ } else if(GLES1.equals(profile) && hasGLES1Impl && ( eglCtxUndef || GLContext.isGLES1Available(device))) {
return GLES1;
}
return null;
}
+ private static String getGLImplBaseClassName(String profileImpl) {
+ if ( GL4bc.equals(profileImpl) ||
+ GL4.equals(profileImpl) ||
+ GL3bc.equals(profileImpl) ||
+ GL3.equals(profileImpl) ||
+ GL2.equals(profileImpl) ) {
+ return "com.jogamp.opengl.impl.gl4.GL4bc";
+ } else if(GLES1.equals(profileImpl) || GL2ES1.equals(profileImpl)) {
+ return "com.jogamp.opengl.impl.es1.GLES1";
+ } else if(GLES2.equals(profileImpl) || GL2ES2.equals(profileImpl)) {
+ return "com.jogamp.opengl.impl.es2.GLES2";
+ } else {
+ throw new GLException("unsupported profile \"" + profileImpl + "\"");
+ }
+ }
+
+ private static /*final*/ HashMap/*<device_connection, HashMap<GL-String, GLProfile>*/ deviceConn2ProfileMap = new HashMap();
+
+ /**
+ * This implementation support lazy initialization, while avoiding recursion/deadlocks.<br>
+ * If no mapping 'device -> GLProfiles-Map' exists yet, it triggers<br>
+ * - create empty mapping device -> GLProfiles-Map <br>
+ * - initialization<br<
+ *
+ * @param device the key 'device -> GLProfiles-Map'
+ * @return the GLProfile HashMap
+ */
+ private static HashMap getProfileMap(AbstractGraphicsDevice device) {
+ validateInitialization();
+ if(null==device) {
+ device = defaultDevice;
+ }
+ String deviceKey = GLContext.getUniqueDeviceString(device);
+ HashMap map = (HashMap) deviceConn2ProfileMap.get(deviceKey);
+ if(null==map) {
+ map = new HashMap();
+ synchronized ( deviceConn2ProfileMap ) {
+ deviceConn2ProfileMap.put(deviceKey, map);
+ }
+ initProfilesForDevice(device);
+ }
+ return map;
+ }
+
+ private static void setProfileMap(AbstractGraphicsDevice device, HashMap/*<GL-String, GLProfile>*/mappedProfiles) {
+ validateInitialization();
+ synchronized ( deviceConn2ProfileMap ) {
+ deviceConn2ProfileMap.put(GLContext.getUniqueDeviceString(device), mappedProfiles);
+ }
+ }
+
private GLProfile(String profile, String profileImpl) {
this.profile = profile;
this.profileImpl = profileImpl;
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 9db718bfb..c0f2736fb 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -83,7 +83,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
static {
DEBUG = Debug.debug("GLCanvas");
- defaultGLProfile = GLProfile.getDefault();
+ defaultGLProfile = GLProfile.getDefault(GLProfile.getDefaultDesktopDevice());
}
private GLProfile glProfile;
@@ -795,11 +795,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
* A most simple JOGL AWT test entry
*/
public static void main(String args[]) {
- System.err.println(GlueGenVersion.getInstance().getInfo(null));
- System.err.println(NativeWindowVersion.getInstance().getInfo(null));
- System.err.print(JoglVersion.getInstance().getInfo(null));
+ System.err.println(GlueGenVersion.getInstance());
+ System.err.println(NativeWindowVersion.getInstance());
+ System.err.print(JoglVersion.getInstance());
- GLCapabilities caps = new GLCapabilities( GLProfile.getDefault() );
+ GLCapabilities caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDesktopDevice()) );
Frame frame = new Frame("JOGL AWT Test");
GLCanvas glCanvas = new GLCanvas(caps);
@@ -809,7 +809,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
glCanvas.addGLEventListener(new GLEventListener() {
public void init(GLAutoDrawable drawable) {
GL gl = drawable.getGL();
- System.err.println(JoglVersion.getInstance().getGLInfo(gl, null));
+ System.err.println(JoglVersion.getInstance().toString(gl));
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index b9bbf71c2..955e51e69 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -1275,7 +1275,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable {
public GLProfile getGLProfile() {
// FIXME: should do better than this; is it possible to using only platform-independent code?
- return GLProfile.getDefault();
+ return GLProfile.getDefault(GLProfile.getDefaultDesktopDevice());
}
public void handleReshape() {
diff --git a/src/junit/com/jogamp/test/junit/newt/TestGLWindows00NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestGLWindows00NEWT.java
new file mode 100644
index 000000000..5568f2e1a
--- /dev/null
+++ b/src/junit/com/jogamp/test/junit/newt/TestGLWindows00NEWT.java
@@ -0,0 +1,132 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.test.junit.newt;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.media.opengl.*;
+
+import com.jogamp.newt.*;
+import com.jogamp.newt.event.*;
+import com.jogamp.newt.opengl.*;
+import java.io.IOException;
+
+import com.jogamp.test.junit.util.UITestCase;
+import com.jogamp.test.junit.util.MiscUtils;
+import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+
+public class TestGLWindows00NEWT extends UITestCase {
+ static GLProfile glp;
+ static int width, height;
+ static long durationPerTest = 100; // ms
+
+ @BeforeClass
+ public static void initClass() {
+ GLProfile.initSingleton(true);
+ // GLProfile.initSingleton(false);
+ width = 640;
+ height = 480;
+ glp = GLProfile.getDefault();
+ }
+
+ static GLWindow createWindow(Screen screen, GLCapabilities caps)
+ throws InterruptedException
+ {
+ Assert.assertNotNull(caps);
+ //
+ // Create native windowing resources .. X11/Win/OSX
+ //
+ GLWindow glWindow;
+ if(null!=screen) {
+ glWindow = GLWindow.create(screen, caps);
+ Assert.assertNotNull(glWindow);
+ } else {
+ glWindow = GLWindow.create(caps);
+ Assert.assertNotNull(glWindow);
+ }
+
+ GLEventListener demo = new Gears();
+ glWindow.addGLEventListener(demo);
+
+ glWindow.setSize(512, 512);
+ glWindow.setVisible(true);
+ Assert.assertEquals(true,glWindow.isVisible());
+ Assert.assertEquals(true,glWindow.isNativeValid());
+
+ return glWindow;
+ }
+
+ static void destroyWindow(GLWindow glWindow) {
+ if(null!=glWindow) {
+ glWindow.destroy(true);
+ Assert.assertEquals(false,glWindow.isNativeValid());
+ }
+ }
+
+ @Test
+ public void testWindow00() throws InterruptedException {
+ GLCapabilities caps = new GLCapabilities(glp);
+ Assert.assertNotNull(caps);
+ GLWindow window1 = createWindow(null, caps); // local
+ Assert.assertEquals(true,window1.isNativeValid());
+ Assert.assertEquals(true,window1.isVisible());
+ AbstractGraphicsDevice device1 = window1.getScreen().getDisplay().getGraphicsDevice();
+
+ System.err.println("GLProfiles window1: "+device1.getConnection()+": "+GLProfile.glAvailabilityToString(device1));
+
+ for(int state=0; state*100<durationPerTest; state++) {
+ Thread.sleep(100);
+ }
+
+ destroyWindow(window1);
+ }
+
+ static int atoi(String a) {
+ int i=0;
+ try {
+ i = Integer.parseInt(a);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ return i;
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ durationPerTest = atoi(args[++i]);
+ }
+ }
+ System.out.println("durationPerTest: "+durationPerTest);
+ String tstname = TestGLWindows00NEWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/junit/com/jogamp/test/junit/newt/TestRemoteGLWindows01NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestRemoteGLWindows01NEWT.java
new file mode 100644
index 000000000..623651f2d
--- /dev/null
+++ b/src/junit/com/jogamp/test/junit/newt/TestRemoteGLWindows01NEWT.java
@@ -0,0 +1,161 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.test.junit.newt;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.util.Animator;
+
+import com.jogamp.newt.*;
+import com.jogamp.newt.opengl.*;
+import java.io.IOException;
+
+import com.jogamp.test.junit.util.UITestCase;
+import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeWindowException;
+
+public class TestRemoteGLWindows01NEWT extends UITestCase {
+ static GLProfile glp;
+ static int width, height;
+ static long durationPerTest = 100; // ms
+
+ @BeforeClass
+ public static void initClass() {
+ GLProfile.initSingleton(true);
+ // GLProfile.initSingleton(false);
+ width = 640;
+ height = 480;
+ glp = GLProfile.getDefault();
+ }
+
+ static GLWindow createWindow(Screen screen, GLCapabilities caps)
+ throws InterruptedException
+ {
+ Assert.assertNotNull(caps);
+ //
+ // Create native windowing resources .. X11/Win/OSX
+ //
+ GLWindow glWindow;
+ if(null!=screen) {
+ glWindow = GLWindow.create(screen, caps);
+ Assert.assertNotNull(glWindow);
+ } else {
+ glWindow = GLWindow.create(caps);
+ Assert.assertNotNull(glWindow);
+ }
+
+ GLEventListener demo = new Gears();
+ glWindow.addGLEventListener(demo);
+
+ glWindow.setSize(512, 512);
+ glWindow.setVisible(true);
+ Assert.assertEquals(true,glWindow.isVisible());
+ Assert.assertEquals(true,glWindow.isNativeValid());
+
+ return glWindow;
+ }
+
+ static void destroyWindow(GLWindow glWindow) {
+ if(null!=glWindow) {
+ glWindow.destroy(true);
+ Assert.assertEquals(false,glWindow.isNativeValid());
+ }
+ }
+
+ @Test
+ public void testRemoteWindow01() throws InterruptedException {
+ GLCapabilities caps = new GLCapabilities(glp);
+ Assert.assertNotNull(caps);
+ GLWindow window1 = createWindow(null, caps); // local
+ Assert.assertEquals(true,window1.isNativeValid());
+ Assert.assertEquals(true,window1.isVisible());
+ AbstractGraphicsDevice device1 = window1.getScreen().getDisplay().getGraphicsDevice();
+
+ System.err.println("GLProfiles window1: "+device1.getConnection()+": "+GLProfile.glAvailabilityToString(device1));
+
+ Animator animator1 = new Animator(window1);
+ animator1.start();
+
+ // Eager initialization of NEWT Display -> AbstractGraphicsDevice -> GLProfile (device)
+ Display display2 = NewtFactory.createDisplay("charelle:0.0"); // remote display
+ display2.setDestroyWhenUnused(true);
+ try {
+ display2.createNative();
+ } catch (NativeWindowException nwe) {
+ System.err.println(nwe);
+ Assume.assumeNoException(nwe);
+ destroyWindow(window1);
+ return;
+ }
+ AbstractGraphicsDevice device2 = display2.getGraphicsDevice();
+ GLProfile.initProfiles(device2); // just to make sure
+ System.err.println("");
+ System.err.println("GLProfiles window2: "+device2.getConnection()+": "+GLProfile.glAvailabilityToString(device2));
+
+ Screen screen2 = NewtFactory.createScreen(display2, 0); // screen 0
+ GLWindow window2 = createWindow(screen2, caps); // remote
+ Assert.assertEquals(true,window2.isNativeValid());
+ Assert.assertEquals(true,window2.isVisible());
+
+ Animator animator2 = new Animator(window2);
+ animator2.start();
+
+ for(int state=0; state*100<durationPerTest; state++) {
+ Thread.sleep(100);
+ }
+
+ destroyWindow(window1);
+ destroyWindow(window2);
+ }
+
+ static int atoi(String a) {
+ int i=0;
+ try {
+ i = Integer.parseInt(a);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ return i;
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ durationPerTest = atoi(args[++i]);
+ }
+ }
+ System.out.println("durationPerTest: "+durationPerTest);
+ String tstname = TestRemoteGLWindows01NEWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/junit/com/jogamp/test/junit/newt/TestRemoteWindow01NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestRemoteWindow01NEWT.java
new file mode 100644
index 000000000..2a43c3ac5
--- /dev/null
+++ b/src/junit/com/jogamp/test/junit/newt/TestRemoteWindow01NEWT.java
@@ -0,0 +1,146 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.test.junit.newt;
+
+import java.lang.reflect.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+import javax.media.nativewindow.*;
+
+import com.jogamp.newt.*;
+import java.io.IOException;
+
+import com.jogamp.test.junit.util.UITestCase;
+
+public class TestRemoteWindow01NEWT extends UITestCase {
+ static int width, height;
+
+ @BeforeClass
+ public static void initClass() {
+ NativeWindowFactory.initSingleton(true);
+ width = 640;
+ height = 480;
+ }
+
+ static Window createWindow(Screen screen, Capabilities caps, int width, int height, boolean onscreen, boolean undecorated) {
+ Assert.assertNotNull(caps);
+ caps.setOnscreen(onscreen);
+ // System.out.println("Requested: "+caps);
+
+ //
+ // Create native windowing resources .. X11/Win/OSX
+ //
+ Window window = NewtFactory.createWindow(screen, caps);
+ Assert.assertNotNull(window);
+ window.setUndecorated(onscreen && undecorated);
+ window.setSize(width, height);
+ Assert.assertEquals(false,window.isNativeValid());
+ Assert.assertEquals(false,window.isVisible());
+ window.setVisible(true);
+ Assert.assertEquals(true,window.isVisible());
+ Assert.assertEquals(true,window.isNativeValid());
+ // Assert.assertEquals(width,window.getWidth());
+ // Assert.assertEquals(height,window.getHeight());
+ // System.out.println("Created: "+window);
+
+ //
+ // Create native OpenGL resources .. XGL/WGL/CGL ..
+ // equivalent to GLAutoDrawable methods: setVisible(true)
+ //
+ caps = window.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ Assert.assertNotNull(caps);
+ Assert.assertTrue(caps.getGreenBits()>5);
+ Assert.assertTrue(caps.getBlueBits()>5);
+ Assert.assertTrue(caps.getRedBits()>5);
+ Assert.assertEquals(caps.isOnscreen(),onscreen);
+
+ return window;
+ }
+
+ static void destroyWindow(Display display, Screen screen, Window window) {
+ if(null!=window) {
+ window.destroy();
+ }
+ if(null!=screen) {
+ screen.destroy();
+ }
+ if(null!=display) {
+ display.destroy();
+ }
+ }
+
+ @Test
+ public void testRemoteWindow01() throws InterruptedException {
+ Capabilities caps = new Capabilities();
+ Display display1 = NewtFactory.createDisplay(null); // local display
+ Screen screen1 = NewtFactory.createScreen(display1, 0); // screen 0
+ Window window1 = createWindow(screen1, caps, width, height, true /* onscreen */, false /* undecorated */);
+ window1.setVisible(true);
+
+ Assert.assertEquals(true,window1.isNativeValid());
+ Assert.assertEquals(true,window1.isVisible());
+
+ Display display2 = NewtFactory.createDisplay("charelle:0.0"); // remote display
+ try {
+ display2.createNative();
+ } catch (NativeWindowException nwe) {
+ System.err.println(nwe);
+ Assume.assumeNoException(nwe);
+ destroyWindow(display1, screen1, window1);
+ return;
+ }
+ Screen screen2 = NewtFactory.createScreen(display2, 0); // screen 0
+ Window window2 = createWindow(screen2, caps, width, height, true /* onscreen */, false /* undecorated */);
+ window2.setVisible(true);
+
+ Assert.assertEquals(true,window2.isNativeValid());
+ Assert.assertEquals(true,window2.isVisible());
+
+ Thread.sleep(500); // 500 ms
+
+ destroyWindow(display1, screen1, window1);
+ destroyWindow(display2, screen2, window2);
+ }
+
+ public static void main(String args[]) throws IOException {
+ String tstname = TestRemoteWindow01NEWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}