aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl
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/jogl/classes/com/jogamp/opengl
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/jogl/classes/com/jogamp/opengl')
-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
15 files changed, 796 insertions, 343 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) {