diff options
author | Sven Gothel <[email protected]> | 2010-06-10 09:35:06 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-06-10 09:35:06 +0200 |
commit | 1d333a771ce0bc7c8594e21d031703f698f06a46 (patch) | |
tree | 933d470582896320855fa1d98c1a917edc412c24 /src/nativewindow/classes/javax | |
parent | 4512900ddcb9ce9a498411d257b1b6d6010ec006 (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/nativewindow/classes/javax')
7 files changed, 46 insertions, 209 deletions
diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java index 4240ec81e..c133df5b4 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java @@ -55,4 +55,8 @@ public interface AbstractGraphicsDevice extends Cloneable { * if such thing exist. */ public long getHandle(); + + public void lock(); + + public void unlock(); } diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java index fdc849d0f..e18b7b2dc 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java @@ -62,6 +62,12 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice return handle; } + public void lock() { + } + + public void unlock() { + } + public String toString() { return getClass().toString()+"[type "+getType()+", handle 0x"+Long.toHexString(getHandle())+"]"; } diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java index 09c605e1c..7d0c52e3b 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java @@ -53,6 +53,9 @@ package javax.media.nativewindow; such as the window handle. */ public interface NativeWindow extends SurfaceUpdatedListener { + /** Unlocked state */ + public static final int LOCK_SURFACE_UNLOCKED = 0; + /** Returned by {@link #lockSurface()} if the surface is not ready to be locked. */ public static final int LOCK_SURFACE_NOT_READY = 1; diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java index 14cb830e3..41be6e4b2 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -76,6 +76,7 @@ public abstract class NativeWindowFactory { private static String nativeOSNameCustom; private static final boolean isAWTAvailable; public static final String AWTComponentClassName = "java.awt.Component" ; + public static final String X11UtilClassName = "com.jogamp.nativewindow.impl.x11.X11Util"; /** Creates a new NativeWindowFactory instance. End users do not need to call this method. */ @@ -112,6 +113,10 @@ public abstract class NativeWindowFactory { nativeWindowingTypeCustom = nativeOSNameCustom; } + if( TYPE_X11.equals(nativeWindowingTypePure) ) { + ReflectionUtil.callStaticMethod( X11UtilClassName, "initSingleton", new Class[] { }, new Object[] { } ); + } + registeredFactories = Collections.synchronizedMap(new HashMap()); String factoryClassName = null; @@ -124,87 +129,25 @@ public abstract class NativeWindowFactory { // We break compile-time dependencies on the AWT here to // make it easier to run this code on mobile devices - isAWTAvailable = !Debug.getBooleanProperty("java.awt.headless", true, acc) && ReflectionUtil.isClassAvailable(AWTComponentClassName) && ReflectionUtil.isClassAvailable("javax.media.nativewindow.awt.AWTGraphicsDevice") ; - boolean toolkitLockForced = Debug.getBooleanProperty("nativewindow.locking", true, acc); - boolean awtToolkitLockDisabled = !isAWTAvailable || - Debug.getBooleanProperty("nativewindow.nolocking", true, acc) ; - - NativeWindowFactory _factory = null; - - if( !awtToolkitLockDisabled && TYPE_X11.equals(nativeWindowingTypeCustom) ) { - // There are certain operations that may be done by - // user-level native code which must share the display - // connection with the underlying window toolkit. In JOGL, - // for example, the AWT GLCanvas makes GLX and OpenGL - // calls against an X Drawable that was created by the - // AWT. In this case, the AWT Native Interface ("JAWT") is - // used to lock and unlock this surface, which grabs and - // releases a lock which is also used internally to the - // AWT implementation. This is required because the AWT - // makes X calls from multiple threads: for example, the - // AWT Toolkit thread and one or more Event Dispatch - // Threads. - // - // There are cases where synchronization with the - // toolkit is required in case of a shared resource pattern, - // e.g. with AWT. From recollection, visual selection is - // performed outside of the cover of the - // toolkit's lock, and the toolkit's display connection is - // used for this operation, so for correctness the toolkit - // must be locked during glXChooseFBConfig / - // glXChooseVisual. Synchronization with the toolkit is - // definitely needed for support of external GLDrawables, - // where JOGL creates additional OpenGL contexts on a - // surface that was created by a third party. External - // GLDrawables are the foundation of the Java 2D / JOGL - // bridge. While this bridge may be historical at this - // point, support for external GLDrawables on platforms - // that can support them (namely, WGL and X11 platforms; - // Mac OS X does not currently have the required - // primitives in its OpenGL window system binding) makes - // the JOGL library more powerful. - // - // The X11AWTNativeWindowFactory provides a locking - // mechanism compatible with the AWT. It may be desirable - // to replace this window factory when using third-party - // toolkits like Newt even when running on Java SE when - // the AWT is available. - - try { - Constructor factoryConstructor = - ReflectionUtil.getConstructor("com.jogamp.nativewindow.impl.x11.awt.X11AWTNativeWindowFactory", new Class[] {}); - _factory = (NativeWindowFactory) factoryConstructor.newInstance(null); - } catch (Exception e) { } - } - - if (toolkitLockForced && null==_factory) { - try { - Constructor factoryConstructor = - ReflectionUtil.getConstructor("com.jogamp.nativewindow.impl.LockingNativeWindowFactory", new Class[] {}); - _factory = (NativeWindowFactory) factoryConstructor.newInstance(null); - } catch (Exception e) { } - } - - if (null !=_factory) { - factory = _factory; - } - if ( isAWTAvailable ) { // register either our default factory or (if exist) the X11/AWT one -> AWT Component registerFactory(ReflectionUtil.getClass(AWTComponentClassName, false), factory); } - defaultFactory = factory; if(DEBUG) { - System.err.println("NativeWindowFactory toolkitLockForced "+toolkitLockForced+ - ", awtToolkitLockDisabled "+awtToolkitLockDisabled+", defaultFactory "+factory); + System.err.println("NativeWindowFactory isAWTAvailable "+isAWTAvailable+ + ", defaultFactory "+factory); } } + public static void initSingleton() { + // just exist to ensure static init has been run + } + /** @return true if not headless, AWT Component and NativeWindow's AWT part available */ public static boolean isAWTAvailable() { return isAWTAvailable; } @@ -216,32 +159,12 @@ public abstract class NativeWindowFactory { return useCustom?nativeWindowingTypeCustom:nativeWindowingTypePure; } - /** Sets the default NativeWindowFactory. Certain operations on - X11 platforms require synchronization, and the implementation - of this synchronization may be specific to the window toolkit - in use. It is impractical to require that all of the APIs that - might require synchronization receive a {@link ToolkitLock - ToolkitLock} as argument. For this reason the concept of a - default NativeWindowFactory is introduced. The toolkit lock - provided via {@link #getToolkitLock getToolkitLock} from this - default NativeWindowFactory will be used for synchronization - within the Java binding to OpenGL. By default, if the AWT is - available, the default toolkit will support the AWT. */ + /** Sets the default NativeWindowFactory. */ public static void setDefaultFactory(NativeWindowFactory factory) { defaultFactory = factory; } - /** Gets the default NativeWindowFactory. Certain operations on - X11 platforms require synchronization, and the implementation - of this synchronization may be specific to the window toolkit - in use. It is impractical to require that all of the APIs that - might require synchronization receive a {@link ToolkitLock - ToolkitLock} as argument. For this reason the concept of a - default NativeWindowFactory is introduced. The toolkit lock - provided via {@link #getToolkitLock getToolkitLock} from this - default NativeWindowFactory will be used for synchronization - within the Java binding to OpenGL. By default, if the AWT is - available, the default toolkit will support the AWT. */ + /** Gets the default NativeWindowFactory. */ public static NativeWindowFactory getDefaultFactory() { return defaultFactory; } @@ -308,10 +231,4 @@ public abstract class NativeWindowFactory { NativeWindow. Implementors of concrete NativeWindowFactory subclasses should override this method. */ protected abstract NativeWindow getNativeWindowImpl(Object winObj, AbstractGraphicsConfiguration config) throws IllegalArgumentException; - - /** Returns the object which provides support for synchronizing - with the underlying window toolkit.<br> - @see ToolkitLock - */ - public abstract ToolkitLock getToolkitLock(); } diff --git a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java deleted file mode 100644 index 6f83896fa..000000000 --- a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. 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. - */ - -package javax.media.nativewindow; - -/** Provides an interface for locking and unlocking the underlying - window toolkit, where this is necessary in the OpenGL - implementation. This mechanism is generally only needed on X11 - platforms. Currently it is only used when the AWT is in use. - Implementations of this lock, if they are not no-ops, must support - reentrant locking and unlocking. <P> - - The ToolkitLock implementation can be aquired by - {@link NativeWindowFactory#getToolkitLock NativeWindowFactory's getToolkitLock()}.<P> - - All toolkit shared resources shall be accessed by encapsulating the - code with a locking block as follows. - <PRE> - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - try { - long displayHandle = X11Util.getThreadLocalDefaultDisplay(); - ... some code dealing with shared resources - ... ie the window surface - } finally { - NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); - } - </PRE><P> - - The underlying toolkit's locking mechanism may relate to {@link NativeWindow}'s - {@link NativeWindow#lockSurface lockSurface()}. Hence it is important - that both implementation harmonize well, ie {@link NativeWindow#lockSurface lockSurface()} - shall issue a ToolkitLock lock befor it aquires it's surface lock. This is true - in the AWT implementation for example. Otherwise the surface lock would <i>steal</i> - the ToolkitLock's lock and a deadlock would be unavoidable.<P> - - However the necessity of needing a global state synchronization will of course - impact your performance very much, especially in case of a multithreaded/multiwindow case. - */ -public interface ToolkitLock { - /** Locks the toolkit. */ - public void lock(); - - /** Unlocks the toolkit. */ - public void unlock(); -} diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java index f0ea11011..192abf775 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java @@ -33,6 +33,8 @@ package javax.media.nativewindow.x11; import javax.media.nativewindow.*; +import com.jogamp.nativewindow.impl.*; +import com.jogamp.nativewindow.impl.x11.X11Util; /** Encapsulates a graphics device on X11 platforms. */ @@ -49,5 +51,14 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl public Object clone() { return super.clone(); } + + public void lock() { + X11Util.XLockDisplay(handle); + } + + public void unlock() { + X11Util.XUnlockDisplay(handle); + } + } diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java index a18ee91c2..97bdc37cf 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java +++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java @@ -56,53 +56,23 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl /** Creates a new X11GraphicsScreen using a thread local display connection */ public static AbstractGraphicsScreen createDefault() { - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - try { - long display = X11Util.createThreadLocalDefaultDisplay(); - X11Util.XLockDisplay(display); - try{ - int scrnIdx = X11Lib.DefaultScreen(display); - return createScreenDevice(display, scrnIdx); - }finally{ - X11Util.XUnlockDisplay(display); - } - } finally { - NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); - } + long display = X11Util.createThreadLocalDisplay(null); + int scrnIdx = X11Lib.DefaultScreen(display); + return createScreenDevice(display, scrnIdx); } public long getDefaultVisualID() { // It still could be an AWT hold handle .. - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - try { - long display = getDevice().getHandle(); - X11Util.XLockDisplay(display); - try{ - int scrnIdx = X11Lib.DefaultScreen(display); - return X11Lib.DefaultVisualID(display, scrnIdx); - }finally{ - X11Util.XUnlockDisplay(display); - } - } finally { - NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); - } + long display = getDevice().getHandle(); + int scrnIdx = X11Lib.DefaultScreen(display); + return X11Lib.DefaultVisualID(display, scrnIdx); } private static int fetchScreen(X11GraphicsDevice device, int screen) { // It still could be an AWT hold handle .. - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - try { - long display = device.getHandle(); - X11Util.XLockDisplay(display); - try{ - if(X11Lib.XineramaEnabled(display)) { - screen = 0; // Xinerama -> 1 screen - } - }finally{ - X11Util.XUnlockDisplay(display); - } - } finally { - NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); + long display = device.getHandle(); + if(X11Lib.XineramaEnabled(display)) { + screen = 0; // Xinerama -> 1 screen } return screen; } |