aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2010-06-10 09:35:06 +0200
committerSven Gothel <[email protected]>2010-06-10 09:35:06 +0200
commit1d333a771ce0bc7c8594e21d031703f698f06a46 (patch)
tree933d470582896320855fa1d98c1a917edc412c24 /src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java
parent4512900ddcb9ce9a498411d257b1b6d6010ec006 (diff)
Fix: Locking/Threading; Common IntIntHashMap and Buffers; Fix: glMap*Buffer*; GLX/WGL/CgGL: All runtime dynamic; Misc ..
TODO: Compile and test on MacOSX .. Fix: ===== Multithreading/Locking: See jogl/doc/Implementation/MultiThreading.txt - Locking layer is not platform agnostic, ie GLContextImpl, GLDrawableImpl, .. and NEWT: Window/Display - No more use of JAWT global lock necessary, removed. - No need for X11 Display lock, on the contrary, this made the NV driver hang. - Use common window/surface lock - All NativeWindow surfaceLock's are recursive now glMapBuffer: If size is 0, don't do cont with the native call. glMapBufferRange: Fix capacity. glNamedBufferDataEXT: Track the size. glMapNamedBufferEXT: Manual impl. - use the tracked size glXGetVisualFromFBConfig, glXChooseFBConfig, glXChooseVisual: Instead of ignoring and implement a renamed version (*Copied), we just use ManualImplementation for the proper copy-result code. DesktopGLDynamicLookupHelper: Initialize _hasGLBinding* attributes in the determing loadGLJNILibrary() method, which is called by super(). Otherwise static init will overwrite them after the super() call. X11GLXDrawableFactory: Don't release anything at shutdown (removed sharedContext.destroy()), since this caused a freeze/SEGV sometimes. Fixed NEWT's reparentWindow() functionality incl NewtCanvasAWT usage. - Native: if not visible, don't focus, etc - NewtCanvasAWT: Use the container size to start with - Run the command on the EDT Using GlueGen's new DynamicLibraryBundle utility: - X11, Windows and MacOSX OpenGL adapted to DynamicLibraryBundleInfo. - X11GLXDynamicLookupHelper -> X11GLXDynamicLibraryBundleInfo - Remove all path from lib names. - GL order: libGL.so.1, libGL.so, GL - shallLinkGlobal: true -> to server some 'old' DRI systems -> http://dri.sourceforge.net/doc/DRIuserguide.html - shallLookupGlobal: false - Try both : glXGetProcAddressARB and glXGetProcAddress - Using bootstrap: GLX.glXGetProcAddress(long glxGetProcAddressHandle, String glFuncName) Found the issue with LIBGL_DRIVERS_PATH, ie if not set no valid GL instance can be found (ie ATI fglrx/DRI). This may happen if using a differen user than the desktop user for whom the env var is set within some /etc/X11/Xsession.d/ script. Enhancements: ============= GLBufferSizeTracker: Use IntIntHashMap and add DirectState size tracking. GLBufferStateTracker: Use IntIntHashMap. GLStateTracker: Use IntIntHashMap. GLDynamicLookupHelper: More generic (global loading/lookup and GetProcAddress function name list), remove redundant code. FIXME: MacOSXCGLDynamicLookupHelper: - Not tested - Not using NSImage lookup anymore as recommended by OSX API Doc, so dlsym is used always (to be tested) WindowsWGLDynamicLookupHelper: - Not tested GLX/WGL/CgGL is all runtime-dynamic as now, ie loaded and looked-up at runtime, no compile time dependencies to GL anymore, nor a need to specify CgGL. Split up WGL in GDI and WGL, to allow proper dynamic runtime linkage of OpenGL32 while using static binding to GDI32 NEWT events generated by native code are enqueued and not send directly. This should ease locking mechanisms .. if any are necessary. NEWT: More platform specific code moved to *Impl method, simplifying the generic code of the superclass and impl protocol. Cleanup: ========= Replace all InternalBufferUtil's with com.jogamp.common.nio.Buffers Removed all InternalBufferUtil's from repository Removed GLContextImpl notion of 'optimized' surface locking, where the surface gets unlocked during makeCurrent/release. This just makes no sense and would impact multithreading in a horrible way.
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java140
1 files changed, 96 insertions, 44 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java
index 0742587dd..dc98b5514 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java
@@ -53,16 +53,6 @@ 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();
- // NOTE: default sense of GLContext optimization disabled in JSR-231
- // 1.0 beta 5 due to problems on X11 platforms (both Linux and
- // Solaris) when moving and resizing windows. Apparently GLX tokens
- // get sent to the X server under the hood (and out from under the
- // cover of the AWT lock) in these situations. Users requiring
- // multi-screen X11 applications can manually enable this flag. It
- // basically had no tangible effect on the Windows or Mac OS X
- // platforms anyway in particular with the disabling of the
- // GLWorkerThread which we found to be necessary in 1.0 beta 4.
- protected boolean optimizationEnabled = Debug.isPropertyDefined("jogl.GLContext.optimize", true);
// Cache of the functions that are available to be called at the current
// moment in time
@@ -151,21 +141,24 @@ public abstract class GLContextImpl extends GLContext {
public abstract Object getPlatformGLExtensions();
+ // Note: the surface is locked within [makeCurrent .. swap .. release]
public void release() throws GLException {
if (!lock.isHeld()) {
throw new GLException("Context not current on current thread");
}
setCurrent(null);
try {
- releaseImpl();
+ releaseImpl();
} finally {
+ if (drawable.isSurfaceLocked()) {
+ drawable.unlockSurface();
+ }
lock.unlock();
}
}
-
protected abstract void releaseImpl() throws GLException;
- public void destroy() {
+ public final void destroy() {
if (lock.isHeld()) {
// release current context
release();
@@ -209,14 +202,47 @@ public abstract class GLContextImpl extends GLContext {
glStateTracker.clearStates(false);
}
- destroyImpl();
+ if (contextHandle != 0) {
+ int lockRes = drawable.lockSurface();
+ if (NativeWindow.LOCK_SURFACE_NOT_READY == lockRes) {
+ // this would be odd ..
+ throw new GLException("Surface not ready to lock: "+drawable);
+ }
+ try {
+ destroyImpl();
+ contextHandle = 0;
+ GLContextShareSet.contextDestroyed(this);
+ } finally {
+ drawable.unlockSurface();
+ }
+ }
} finally {
lock.unlock();
}
}
-
protected abstract void destroyImpl() throws GLException;
+ public final void copy(GLContext source, int mask) throws GLException {
+ if (source.getHandle() == 0) {
+ throw new GLException("Source OpenGL context has not been created");
+ }
+ if (getHandle() == 0) {
+ throw new GLException("Destination OpenGL context has not been created");
+ }
+
+ int lockRes = drawable.lockSurface();
+ if (NativeWindow.LOCK_SURFACE_NOT_READY == lockRes) {
+ // this would be odd ..
+ throw new GLException("Surface not ready to lock");
+ }
+ try {
+ copyImpl(source, mask);
+ } finally {
+ drawable.unlockSurface();
+ }
+ }
+ protected abstract void copyImpl(GLContext source, int mask) throws GLException;
+
//----------------------------------------------------------------------
//
@@ -285,7 +311,7 @@ public abstract class GLContextImpl extends GLContext {
lock.lock();
int res = 0;
try {
- res = makeCurrentImpl();
+ res = makeCurrentLocking();
/* FIXME: refactor dependence on Java 2D / JOGL bridge
if ((tracker != null) &&
@@ -320,15 +346,50 @@ public abstract class GLContextImpl extends GLContext {
return res;
}
- /**
- * @see #makeCurrent
- */
- protected abstract int makeCurrentImpl() throws GLException;
-
- /**
- * @see #makeCurrent
- */
- protected abstract void create() throws GLException ;
+ // Note: the surface is locked within [makeCurrent .. swap .. release]
+ protected final int makeCurrentLocking() throws GLException {
+ boolean exceptionOccurred = false;
+ int lockRes = drawable.lockSurface();
+ try {
+ if (NativeWindow.LOCK_SURFACE_NOT_READY == lockRes) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ try {
+ if (NativeWindow.LOCK_SURFACE_CHANGED == lockRes) {
+ drawable.updateHandle();
+ }
+ if (0 == drawable.getHandle()) {
+ throw new GLException("drawable has invalid handle: "+drawable);
+ }
+ boolean newCreated = false;
+ if (!isCreated()) {
+ newCreated = createImpl(); // may throws exception if fails!
+ if (DEBUG) {
+ if(newCreated) {
+ System.err.println(getThreadName() + ": !!! Create GL context OK: " + toHexString(contextHandle) + " for " + getClass().getName());
+ } else {
+ System.err.println(getThreadName() + ": !!! Create GL context FAILED for " + getClass().getName());
+ }
+ }
+ if(!newCreated) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ GLContextShareSet.contextCreated(this);
+ }
+ makeCurrentImpl(newCreated);
+ return newCreated ? CONTEXT_CURRENT_NEW : CONTEXT_CURRENT ;
+ } catch (RuntimeException e) {
+ exceptionOccurred = true;
+ throw e;
+ }
+ } finally {
+ if (exceptionOccurred) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+ protected abstract void makeCurrentImpl(boolean newCreatedContext) throws GLException;
+ protected abstract boolean createImpl() throws GLException ;
/**
* Platform dependent but harmonized implementation of the <code>ARB_create_context</code>
@@ -388,8 +449,8 @@ public abstract class GLContextImpl extends GLContext {
* @see #createContextARBImpl
* @see #destroyContextARBImpl
*/
- protected long createContextARB(long share, boolean direct,
- int major[], int minor[], int ctp[])
+ protected final long createContextARB(long share, boolean direct,
+ int major[], int minor[], int ctp[])
{
AbstractGraphicsConfiguration config = drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities();
@@ -441,7 +502,7 @@ public abstract class GLContextImpl extends GLContext {
return _ctx;
}
- private void createContextARBMapVersionsAvailable(int reqMajor, boolean compat)
+ private final void createContextARBMapVersionsAvailable(int reqMajor, boolean compat)
{
long _context;
int reqProfile = compat ? CTX_PROFILE_COMPAT : CTX_PROFILE_CORE ;
@@ -509,10 +570,10 @@ public abstract class GLContextImpl extends GLContext {
}
}
- private long createContextARBVersions(long share, boolean direct, int ctxOptionFlags,
- int majorMax, int minorMax,
- int majorMin, int minorMin,
- int major[], int minor[]) {
+ private final long createContextARBVersions(long share, boolean direct, int ctxOptionFlags,
+ int majorMax, int minorMax,
+ int majorMin, int minorMin,
+ int major[], int minor[]) {
major[0]=majorMax;
minor[0]=minorMax;
long _context=0;
@@ -540,7 +601,7 @@ public abstract class GLContextImpl extends GLContext {
* If major==0 && minor == 0 : Use GL_VERSION
* Otherwise .. don't touch ..
*/
- protected void setContextVersion(int major, int minor, int ctp) {
+ protected final void setContextVersion(int major, int minor, int ctp) {
if (0==ctp) {
throw new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
}
@@ -619,7 +680,7 @@ public abstract class GLContextImpl extends GLContext {
public abstract ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3);
- public void setSwapInterval(final int interval) {
+ public final void setSwapInterval(final int interval) {
GLContext current = getCurrent();
if (current != this) {
throw new GLException("This context is not current. Current context: "+current+
@@ -627,17 +688,12 @@ public abstract class GLContextImpl extends GLContext {
}
setSwapIntervalImpl(interval);
}
-
+ protected void setSwapIntervalImpl(final int interval) { /** nop per default .. **/ }
protected int currentSwapInterval = -1; // default: not set yet ..
-
public int getSwapInterval() {
return currentSwapInterval;
}
- protected void setSwapIntervalImpl(final int interval) {
- // nop per default ..
- }
-
/** Maps the given "platform-independent" function name to a real function
name. Currently this is only used to map "glAllocateMemoryNV" and
associated routines to wglAllocateMemoryNV / glXAllocateMemoryNV. */
@@ -838,10 +894,6 @@ public abstract class GLContextImpl extends GLContext {
// current on the OpenGL worker thread
//
- public boolean isOptimizable() {
- return optimizationEnabled;
- }
-
public boolean hasWaiters() {
return lock.hasWaiters();
}