diff options
author | Sven Gothel <[email protected]> | 2011-04-23 06:14:38 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-04-23 06:14:38 +0200 |
commit | f5e0656fe20925d8c921d1b4cc70acd02dfbf9fd (patch) | |
tree | 17f7bae0f416eab6438b2826e9b57ddb0791eebf /src/jogl/classes | |
parent | 48201a6ea6471eb5951edb735b36156ab3410a15 (diff) |
GLContextImpl: GLContextLock -> RecursiveLock
RecursiveLock maintains a queue of waiting Threads,
ensuring the longest waiting thread will be notified at unlock.
Delete GLContextLock.
Cleanup HashMap generics style.
Diffstat (limited to 'src/jogl/classes')
6 files changed, 70 insertions, 212 deletions
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java index 9361fb0f9..dcd42a3b4 100644 --- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java @@ -46,6 +46,7 @@ import java.util.Map; import com.jogamp.common.os.DynamicLookupHelper; import com.jogamp.common.util.ReflectionUtil; +import com.jogamp.common.util.locks.RecursiveLock; import com.jogamp.gluegen.runtime.FunctionAddressResolver; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLExtensionNames; @@ -65,7 +66,8 @@ import javax.media.opengl.GLProfile; public abstract class GLContextImpl extends GLContext { public static final boolean DEBUG = Debug.debug("GLContext"); - protected GLContextLock lock = new GLContextLock(); + // RecursiveLock maintains a queue of waiting Threads, ensuring the longest waiting thread will be notified at unlock. + protected RecursiveLock lock = new RecursiveLock(); /** * Context full qualified name: display_type + display_connection + major + minor + ctp. @@ -92,15 +94,15 @@ 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; + protected static final HashMap<String, ExtensionAvailabilityCache> mappedExtensionAvailabilityCache; + protected static final HashMap<String, ProcAddressTable> mappedGLProcAddress; + protected static final HashMap<String, ProcAddressTable> mappedGLXProcAddress; static { mappedContextTypeObjectLock = new Object(); - mappedExtensionAvailabilityCache = new HashMap(); - mappedGLProcAddress = new HashMap(); - mappedGLXProcAddress = new HashMap(); + mappedExtensionAvailabilityCache = new HashMap<String, ExtensionAvailabilityCache>(); + mappedGLProcAddress = new HashMap<String, ProcAddressTable>(); + mappedGLXProcAddress = new HashMap<String, ProcAddressTable>(); } public GLContextImpl(GLDrawableImpl drawable, GLContext shareWith) { @@ -145,7 +147,7 @@ public abstract class GLContextImpl extends GLContext { if(null!=read && drawable!=read && !isGLReadDrawableAvailable()) { throw new GLException("GL Read Drawable not available"); } - boolean lockHeld = lock.isHeld(); + boolean lockHeld = lock.isOwner(); if(lockHeld) { release(); } @@ -185,19 +187,36 @@ public abstract class GLContextImpl extends GLContext { // This is only needed for Mac OS X on-screen contexts protected void update() throws GLException { } + boolean lockFailFast = true; + Object lockFailFastSync = new Object(); + public boolean isSynchronized() { - return !lock.getFailFastMode(); + synchronized (lockFailFastSync) { + return !lockFailFast; + } } public void setSynchronized(boolean isSynchronized) { - lock.setFailFastMode(!isSynchronized); + synchronized (lockFailFastSync) { + lockFailFast = !isSynchronized; + } } + private final void lockConsiderFailFast() { + synchronized (lockFailFastSync) { + if(lockFailFast && lock.isLockedByOtherThread()) { + throw new GLException("Error: Attempt to make context current on thread " + Thread.currentThread() + + " which is already current on thread " + lock.getOwner()); + } + } + lock.lock(); + } + public abstract Object getPlatformGLExtensions(); // Note: the surface is locked within [makeCurrent .. swap .. release] public void release() throws GLException { - if (!lock.isHeld()) { + if ( !lock.isOwner() ) { throw new GLException("Context not current on current thread"); } setCurrent(null); @@ -213,14 +232,14 @@ public abstract class GLContextImpl extends GLContext { protected abstract void releaseImpl() throws GLException; public final void destroy() { - if (lock.isHeld()) { + if ( lock.isOwner() ) { // release current context release(); } // Must hold the lock around the destroy operation to make sure we // don't destroy the context out from under another thread rendering to it - lock.lock(); + lockConsiderFailFast(); try { /* FIXME: refactor dependence on Java 2D / JOGL bridge if (tracker != null) { @@ -347,7 +366,7 @@ public abstract class GLContextImpl extends GLContext { } } - lock.lock(); + lockConsiderFailFast(); int res = 0; try { res = makeCurrentLocking(); @@ -765,14 +784,14 @@ public abstract class GLContextImpl extends GLContext { name. Currently this is only used to map "glAllocateMemoryNV" and associated routines to wglAllocateMemoryNV / glXAllocateMemoryNV. */ protected String mapToRealGLFunctionName(String glFunctionName) { - Map/*<String, String>*/ map = getFunctionNameMap(); - String lookup = ( null != map ) ? (String) map.get(glFunctionName) : null; + Map<String, String> map = getFunctionNameMap(); + String lookup = ( null != map ) ? map.get(glFunctionName) : null; if (lookup != null) { return lookup; } return glFunctionName; } - protected abstract Map/*<String, String>*/ getFunctionNameMap() ; + protected abstract Map<String, String> getFunctionNameMap() ; /** Maps the given "platform-independent" extension name to a real function name. Currently this is only used to map @@ -780,14 +799,14 @@ public abstract class GLContextImpl extends GLContext { "GL_ARB_pixel_format" to "WGL_ARB_pixel_format/n.a." */ protected String mapToRealGLExtensionName(String glExtensionName) { - Map/*<String, String>*/ map = getExtensionNameMap(); - String lookup = ( null != map ) ? (String) map.get(glExtensionName) : null; + Map<String, String> map = getExtensionNameMap(); + String lookup = ( null != map ) ? map.get(glExtensionName) : null; if (lookup != null) { return lookup; } return glExtensionName; } - protected abstract Map/*<String, String>*/ getExtensionNameMap() ; + protected abstract Map<String, String> getExtensionNameMap() ; /** Helper routine which resets a ProcAddressTable generated by the GLEmitter by looking up anew all of its function pointers. */ @@ -841,7 +860,7 @@ public abstract class GLContextImpl extends GLContext { ProcAddressTable table = null; synchronized(mappedContextTypeObjectLock) { - table = (ProcAddressTable) mappedGLProcAddress.get( contextFQN ); + table = mappedGLProcAddress.get( contextFQN ); if(null != table && !verifyInstance(gl.getGLProfile(), "ProcAddressTable", table)) { throw new InternalError("GLContext GL ProcAddressTable mapped key("+contextFQN+") -> "+ table.getClass().getName()+" not matching "+gl.getGLProfile().getGLImplBaseClassName()); @@ -877,7 +896,7 @@ public abstract class GLContextImpl extends GLContext { // ExtensionAvailabilityCache eCache; synchronized(mappedContextTypeObjectLock) { - eCache = (ExtensionAvailabilityCache) mappedExtensionAvailabilityCache.get( contextFQN ); + eCache = mappedExtensionAvailabilityCache.get( contextFQN ); } if(null != eCache) { extensionAvailability = eCache; @@ -1046,7 +1065,7 @@ public abstract class GLContextImpl extends GLContext { // public boolean hasWaiters() { - return lock.hasWaiters(); + return lock.getWaitingThreadQueueSize()>0; } } diff --git a/src/jogl/classes/jogamp/opengl/GLContextLock.java b/src/jogl/classes/jogamp/opengl/GLContextLock.java deleted file mode 100644 index f725508d8..000000000 --- a/src/jogl/classes/jogamp/opengl/GLContextLock.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - * - * Sun gratefully acknowledges that this software was originally authored - * and developed by Kenneth Bradley Russell and Christopher John Kline. - */ - -package jogamp.opengl; - -import javax.media.opengl.*; - -/** Implements the makeCurrent / release locking behavior of the - GLContext class. When "fail fast mode" is enabled, attempts to - lock the same GLContextLock on more than one thread cause - GLException to be raised. This lock is not recursive. Attempts to - lock it more than once on a given thread will cause GLException to - be raised. */ - -public class GLContextLock { - protected static final boolean DEBUG = GLContextImpl.DEBUG; - - static class SyncData { - boolean failFastMode = true; - Thread owner = null; - int waiters = 0; - Exception lockedStack = null; // only enabled if DEBUG - } - private SyncData sdata = new SyncData(); // synchronized (flow/mem) mutable access - - /** Locks this GLContextLock on the current thread. If fail fast - mode is enabled and the GLContextLock is already owned by - another thread, throws GLException. */ - public final void lock() throws GLException { - synchronized(sdata) { - Thread current = Thread.currentThread(); - if (sdata.owner == null) { - sdata.owner = current; - if(DEBUG) { - sdata.lockedStack = new Exception("Error: Previously made current (1) by "+sdata.owner+", lock: "+this); - } - } else if (sdata.owner != current) { - while (sdata.owner != null) { - if (sdata.failFastMode) { - if(null!=sdata.lockedStack) { - sdata.lockedStack.printStackTrace(); - } - throw new GLException("Error: Attempt to make context current on thread " + current + - " which is already current on thread " + sdata.owner); - } else { - try { - ++sdata.waiters; - sdata.wait(); - } catch (InterruptedException e) { - throw new GLException(e); - } finally { - --sdata.waiters; - } - } - } - sdata.owner = current; - if(DEBUG) { - sdata.lockedStack = new Exception("Previously made current (2) by "+sdata.owner+", lock: "+this); - } - } else { - throw new GLException("Attempt to make the same context current twice on thread " + current); - } - } - } - - /** Unlocks this GLContextLock. */ - public final void unlock() throws GLException { - synchronized (sdata) { - Thread current = Thread.currentThread(); - if (sdata.owner == current) { - sdata.owner = null; - sdata.lockedStack = null; - // Assuming notify() implementation weaks up the longest waiting thread, to avoid starvation. - // Otherwise we would need to have a Thread queue implemented, using sleep(timeout) and interrupt. - sdata.notify(); - } else { - if (sdata.owner != null) { - throw new GLException("Attempt by thread " + current + - " to release context owned by thread " + sdata.owner); - } else { - throw new GLException("Attempt by thread " + current + - " to release unowned context"); - } - } - } - } - - /** Indicates whether this lock is held by the current thread. */ - public final boolean isHeld() { - synchronized(sdata) { - return (Thread.currentThread() == sdata.owner); - } - } - - public final void setFailFastMode(boolean onOrOff) { - synchronized(sdata) { - sdata.failFastMode = onOrOff; - } - } - - public final boolean getFailFastMode() { - synchronized(sdata) { - return sdata.failFastMode; - } - } - - public final boolean hasWaiters() { - synchronized(sdata) { - return (0 != sdata.waiters); - } - } - - /** holding the owners stack trace when lock is acquired and DEBUG is true */ - public final Exception getLockedStack() { - synchronized(sdata) { - return sdata.lockedStack; - } - } - -} diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java index 864b9583d..dbdfcd5d9 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java @@ -76,9 +76,9 @@ public abstract class EGLContext extends GLContextImpl { return eglExtProcAddressTable; } - protected Map/*<String, String>*/ getFunctionNameMap() { return null; } + protected Map<String, String> getFunctionNameMap() { return null; } - protected Map/*<String, String>*/ getExtensionNameMap() { return null; } + protected Map<String, String> getExtensionNameMap() { return null; } public final boolean isGLReadDrawableAvailable() { return true; @@ -203,12 +203,12 @@ public abstract class EGLContext extends GLContextImpl { eglQueryStringInitialized = false; eglQueryStringAvailable = false; - EGLExtProcAddressTable table = null; + ProcAddressTable table = null; synchronized(mappedContextTypeObjectLock) { - table = (EGLExtProcAddressTable) mappedGLXProcAddress.get( key ); + table = mappedGLXProcAddress.get( key ); } if(null != table) { - eglExtProcAddressTable = table; + eglExtProcAddressTable = (EGLExtProcAddressTable) table; if(DEBUG) { System.err.println(getThreadName() + ": !!! GLContext EGL ProcAddressTable reusing key("+key+") -> "+table.hashCode()); } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java index 2a2fba8bd..db737902a 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java @@ -82,9 +82,9 @@ public abstract class MacOSXCGLContext extends GLContextImpl return cglExtProcAddressTable; } - protected Map/*<String, String>*/ getFunctionNameMap() { return null; } + protected Map<String, String> getFunctionNameMap() { return null; } - protected Map/*<String, String>*/ getExtensionNameMap() { return null; } + protected Map<String, String> getExtensionNameMap() { return null; } protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) { return 0; // FIXME @@ -230,12 +230,12 @@ public abstract class MacOSXCGLContext extends GLContextImpl if (DEBUG) { System.err.println(getThreadName() + ": !!! Initializing CGL extension address table: "+key); } - CGLExtProcAddressTable table = null; + ProcAddressTable table = null; synchronized(mappedContextTypeObjectLock) { - table = (CGLExtProcAddressTable) mappedGLXProcAddress.get( key ); + table = mappedGLXProcAddress.get( key ); } if(null != table) { - cglExtProcAddressTable = table; + cglExtProcAddressTable = (CGLExtProcAddressTable) table; if(DEBUG) { System.err.println(getThreadName() + ": !!! GLContext CGL ProcAddressTable reusing key("+key+") -> "+table.hashCode()); } diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java index 94017e79a..91a907a09 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java @@ -58,8 +58,8 @@ import jogamp.opengl.GLContextShareSet; import jogamp.opengl.GLDrawableImpl; public class WindowsWGLContext extends GLContextImpl { - static final Map/*<String, String>*/ functionNameMap; - static final Map/*<String, String>*/ extensionNameMap; + static final Map<String, String> functionNameMap; + static final Map<String, String> extensionNameMap; private boolean wglGetExtensionsStringEXTInitialized; private boolean wglGetExtensionsStringEXTAvailable; private boolean wglGLReadDrawableAvailableSet; @@ -70,11 +70,11 @@ public class WindowsWGLContext extends GLContextImpl { private WGLExtProcAddressTable wglExtProcAddressTable; static { - functionNameMap = new HashMap(); + functionNameMap = new HashMap<String, String>(); functionNameMap.put("glAllocateMemoryNV", "wglAllocateMemoryNV"); functionNameMap.put("glFreeMemoryNV", "wglFreeMemoryNV"); - extensionNameMap = new HashMap(); + extensionNameMap = new HashMap<String, String>(); extensionNameMap.put("GL_ARB_pbuffer", "WGL_ARB_pbuffer"); extensionNameMap.put("GL_ARB_pixel_format", "WGL_ARB_pixel_format"); } @@ -161,9 +161,9 @@ public class WindowsWGLContext extends GLContextImpl { return wglExtProcAddressTable; } - protected Map/*<String, String>*/ getFunctionNameMap() { return functionNameMap; } + protected Map<String, String> getFunctionNameMap() { return functionNameMap; } - protected Map/*<String, String>*/ getExtensionNameMap() { return extensionNameMap; } + protected Map<String, String> getExtensionNameMap() { return extensionNameMap; } protected void destroyContextARBImpl(long context) { WGL.wglMakeCurrent(0, 0); @@ -405,12 +405,12 @@ public class WindowsWGLContext extends GLContextImpl { wglGLReadDrawableAvailableSet=false; wglGLReadDrawableAvailable=false; - WGLExtProcAddressTable table = null; + ProcAddressTable table = null; synchronized(mappedContextTypeObjectLock) { - table = (WGLExtProcAddressTable) mappedGLXProcAddress.get( key ); + table = mappedGLXProcAddress.get( key ); } if(null != table) { - wglExtProcAddressTable = table; + wglExtProcAddressTable = (WGLExtProcAddressTable) table; if(DEBUG) { System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable reusing key("+key+") -> "+table.hashCode()); } diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java index 7d7614ca2..119886838 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java @@ -56,8 +56,8 @@ import jogamp.nativewindow.x11.X11Util; public abstract class X11GLXContext extends GLContextImpl { protected static final boolean TRACE_CONTEXT_CURRENT = false; // true; - private static final Map/*<String, String>*/ functionNameMap; - private static final Map/*<String, String>*/ extensionNameMap; + private static final Map<String, String> functionNameMap; + private static final Map<String, String> extensionNameMap; private VersionNumber glXVersion; private boolean glXVersionOneThreeCapable; private boolean glXQueryExtensionsStringInitialized; @@ -74,11 +74,11 @@ public abstract class X11GLXContext extends GLContextImpl { protected boolean isDirect; static { - functionNameMap = new HashMap(); + functionNameMap = new HashMap<String, String>(); functionNameMap.put("glAllocateMemoryNV", "glXAllocateMemoryNV"); functionNameMap.put("glFreeMemoryNV", "glXFreeMemoryNV"); - extensionNameMap = new HashMap(); + extensionNameMap = new HashMap<String, String>(); extensionNameMap.put("GL_ARB_pbuffer", "GLX_SGIX_pbuffer"); extensionNameMap.put("GL_ARB_pixel_format", "GLX_SGIX_pbuffer"); // good enough } @@ -118,9 +118,9 @@ public abstract class X11GLXContext extends GLContextImpl { return glXExt; } - protected Map/*<String, String>*/ getFunctionNameMap() { return functionNameMap; } + protected Map<String, String> getFunctionNameMap() { return functionNameMap; } - protected Map/*<String, String>*/ getExtensionNameMap() { return extensionNameMap; } + protected Map<String, String> getExtensionNameMap() { return extensionNameMap; } public final boolean isGLXVersionGreaterEqualOneThree() { if(null == glXVersion) { @@ -297,7 +297,6 @@ public abstract class X11GLXContext extends GLContextImpl { GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); GLProfile glp = glCaps.getGLProfile(); - isVendorATI = factory.isGLXVendorATI(device); if(config.getFBConfigID()<0) { // not able to use FBConfig @@ -472,12 +471,12 @@ public abstract class X11GLXContext extends GLContextImpl { glXQueryExtensionsStringInitialized = false; glXQueryExtensionsStringAvailable = false; - GLXExtProcAddressTable table = null; + ProcAddressTable table = null; synchronized(mappedContextTypeObjectLock) { - table = (GLXExtProcAddressTable) mappedGLXProcAddress.get( key ); + table = mappedGLXProcAddress.get( key ); } if(null != table) { - glXExtProcAddressTable = table; + glXExtProcAddressTable = (GLXExtProcAddressTable) table; if(DEBUG) { System.err.println(getThreadName() + ": !!! GLContext GLX ProcAddressTable reusing key("+key+") -> "+table.hashCode()); } @@ -581,7 +580,4 @@ public abstract class X11GLXContext extends GLContextImpl { //---------------------------------------------------------------------- // Internals only below this point // - - private boolean isVendorATI = false; - } |