aboutsummaryrefslogtreecommitdiffstats
path: root/src/nativewindow
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2010-05-21 06:15:17 +0200
committerSven Gothel <[email protected]>2010-05-21 06:15:17 +0200
commit6e599a2696f878786783e0fea17534e67655a5c9 (patch)
tree65774f7318ea67a170902efefbd3a952c94d7f6d /src/nativewindow
parent3d8e85915ccdf48b9a97b5ed279716a2204a7a82 (diff)
Changed NEWT NativeWindow creation contract - AWT/NEWT Parenting - Misc Fixes
+++++ Changed NEWT NativeWindow creation contract Original contract: (1) A native window was created as soon as possible, ie when NEWTFactory.createWindow(..) was called - if possible. (2) A valid native window has to be created at least after setVisible(true) has been called. Problems: Not all implementation are able to create the native window that early, but at setVisible(true) only (e.g: KD and EGL). Due to window parenting especially the new AWT/NEWT parenting, the native window can only be created in case the parent native window is valid. New contract: (1) A native window is created at setVisible(true), if it's a top level window or the native parent window is valid. (2) A valid native window may not be created after setVisible(true) has been called. Subsequent setVisible(true) calls shall be made in case the creation has not been done yet. This is demonstrated in GLWindow.display() for example. The new contract implements a lazy native window creation. +++++ AWT/NEWT Parenting - HierarchyListener and ComponentListener ensure that the NEWT child window will be setVisible according to the AWT parent window. - Lazy native window creation relaxes requirements to the parent window's state. - Attachment of the child window and setVisible() may be called after NEWT child window creation. - GLWindow supports NEWT child window creation directly The test case TestParenting01AWT.java reflect this new contract and demonstrates more simplified and more flexible use cases. +++++ NEWT Fixes: - All NEWT implementation's native code method names end with 0. - GLWindow: don't issue the actual 'init'/'display' call to GLEventListeners in case the window is not visible. - NEWT setSize/setPosition: if native-window call native-window action and let the attributes being set by the feedback call, which issues more action, ie RESIZE. else set the attributes directly, no feedback call/action is necessary. +++++ X11 Fixes: - X11GLContext MakeContextCurrent: Use MakeCurrent in case write and read drawable are equal, otherwise SEGV happens on ATI with heavy multithreading involved! Even XLockDisplay and XSync didn't help here .. - X11GLXDrawableFactory shared resource: Removed the resource holder thread to simplify code, hence proper release is no more desired and it could become a cause for deadlock. - Moved XInitThreads() from NEWT X11Window -> NativeWindow X11Util, since NativeWindow is loaded first (essential for XInitThreads()) and it is the more basic lib. - Made call to XInitThreads() conditional, ie it's spared if AWT could be used - which causes SEGV .. (AWT bug). See X11Util.java +++++ JOGL Fixes: - GLProfile.isAWTAvailable() -> NativeWindowFactory.isAWTAvailable() - GLProfile.isAWTJOGLAvailable() -> GLProfile.isAWTAvailable()
Diffstat (limited to 'src/nativewindow')
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java61
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java14
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java32
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java23
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java36
-rw-r--r--src/nativewindow/native/x11/Xmisc.c13
6 files changed, 162 insertions, 17 deletions
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java
index b3c706ed8..527d7750d 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java
@@ -42,6 +42,7 @@ import javax.media.nativewindow.*;
import java.awt.GraphicsEnvironment;
import java.lang.reflect.*;
+import java.security.*;
public class JAWTUtil {
@@ -53,6 +54,12 @@ public class JAWTUtil {
private static final Method isQueueFlusherThread;
private static final boolean j2dExist;
+ private static Class sunToolkitClass;
+ private static Method sunToolkitAWTLockMethod;
+ private static Method sunToolkitAWTUnlockMethod;
+ private static final boolean hasSunToolkitAWTLock;
+ private static final boolean useSunToolkitAWTLock;
+
static {
JAWTJNILibLoader.loadAWTImpl();
JAWTJNILibLoader.loadNativeWindow("awt");
@@ -73,6 +80,32 @@ public class JAWTUtil {
j2dClazz = jC;
isQueueFlusherThread = m;
j2dExist = ok;
+
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ try {
+ sunToolkitClass = Class.forName("sun.awt.SunToolkit");
+ sunToolkitAWTLockMethod = sunToolkitClass.getDeclaredMethod("awtLock", new Class[] {});
+ sunToolkitAWTLockMethod.setAccessible(true);
+ sunToolkitAWTUnlockMethod = sunToolkitClass.getDeclaredMethod("awtUnlock", new Class[] {});
+ sunToolkitAWTUnlockMethod.setAccessible(true);
+ } catch (Exception e) {
+ // Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5
+ }
+ return null;
+ }
+ });
+ boolean _hasSunToolkitAWTLock = false;
+ if ( null!=sunToolkitAWTLockMethod && null!=sunToolkitAWTUnlockMethod ) {
+ try {
+ sunToolkitAWTLockMethod.invoke(null, null);
+ sunToolkitAWTUnlockMethod.invoke(null, null);
+ _hasSunToolkitAWTLock = true;
+ } catch (Exception e) {}
+ }
+ hasSunToolkitAWTLock = _hasSunToolkitAWTLock;
+ // useSunToolkitAWTLock = hasSunToolkitAWTLock;
+ useSunToolkitAWTLock = false;
}
private static Exception lockedStack;
@@ -99,6 +132,30 @@ public class JAWTUtil {
return headlessMode;
}
+ private static void awtLock() {
+ if(useSunToolkitAWTLock) {
+ try {
+ sunToolkitAWTLockMethod.invoke(null, null);
+ } catch (Exception e) {
+ throw new NativeWindowException("SunToolkit.awtLock failed", e);
+ }
+ } else {
+ JAWT.getJAWT().Lock();
+ }
+ }
+
+ private static void awtUnlock() {
+ if(useSunToolkitAWTLock) {
+ try {
+ sunToolkitAWTUnlockMethod.invoke(null, null);
+ } catch (Exception e) {
+ throw new NativeWindowException("SunToolkit.awtUnlock failed", e);
+ }
+ } else {
+ JAWT.getJAWT().Unlock();
+ }
+ }
+
public static synchronized void lockToolkit() throws NativeWindowException {
if (isJava2DQueueFlusherThread()) return;
@@ -115,7 +172,7 @@ public class JAWTUtil {
return;
}
- JAWT.getJAWT().Lock();
+ awtLock();
}
public static synchronized void unlockToolkit() {
@@ -130,7 +187,7 @@ public class JAWTUtil {
return;
}
- JAWT.getJAWT().Unlock();
+ awtUnlock();
}
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java
index f2977e8f0..77bf93204 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java
@@ -37,6 +37,7 @@
package com.jogamp.nativewindow.impl.jawt.x11;
import javax.media.nativewindow.*;
+import javax.media.nativewindow.awt.*;
import javax.media.nativewindow.x11.*;
import com.jogamp.nativewindow.impl.x11.*;
@@ -53,6 +54,19 @@ public class X11JAWTWindow extends JAWTWindow {
}
protected void initNative() throws NativeWindowException {
+ if(0==config.getScreen().getDevice().getHandle()) {
+ AWTGraphicsDevice awtDevice = (AWTGraphicsDevice) config.getScreen().getDevice();
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ try {
+ long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(awtDevice.getGraphicsDevice());
+ if(0==displayHandle) {
+ displayHandle = X11Util.createThreadLocalDefaultDisplay();
+ }
+ awtDevice.setHandle(displayHandle);
+ } finally {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
+ }
+ }
}
public synchronized int lockSurface() throws NativeWindowException {
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java
index d93302e57..196e8f4e2 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java
@@ -56,7 +56,17 @@ public class X11Util {
static {
NWJNILibLoader.loadNativeWindow("x11");
- initialize();
+
+ // No concurrent threading support in case AWT could be used,
+ // Mixing AWT and X11/NEWT results in a segmentation fault:
+ // C pthread_mutex_lock+0x4
+ // J sun.awt.X11.XlibWrapper.XGetDefault
+ // J sun.awt.X11.XToolkit.initializeMultiClickTime
+ // J sun.awt.X11.XToolkit.getMultiClickTime
+ //
+ // It seems like (Oracle's) AWT's Display locking is buggy.
+ //
+ initialize( ! NativeWindowFactory.isAWTAvailable() ) ;
}
public static void initSingleton() {
@@ -142,6 +152,8 @@ public class X11Util {
if(0==dpy) {
throw new NativeWindowException("X11Util.Display: Unable to create a display("+name+") connection in Thread "+Thread.currentThread().getName());
}
+ // if you like to debug and synchronize X11 commands ..
+ // setSynchronizeDisplay(dpy, true);
namedDpy = new NamedDisplay(name, dpy);
addCurrentDisplay( namedDpy );
synchronized(globalLock) {
@@ -207,6 +219,22 @@ public class X11Util {
return closeThreadLocalDisplay(ndpy.getName());
}
+ public static boolean setSynchronizeDisplay(long handle, boolean onoff) {
+ String name;
+ XLockDisplay(handle);
+ boolean res = X11Lib.XSynchronize(handle, onoff);
+ XUnlockDisplay(handle);
+ return res;
+ }
+
+ public static String getNameOfDisplay(long handle) {
+ String name;
+ XLockDisplay(handle);
+ name = X11Lib.XDisplayString(handle);
+ XUnlockDisplay(handle);
+ return name;
+ }
+
public static void XLockDisplay(long handle) {
if(DEBUG_XDISPLAY_LOCK) {
NamedDisplay ndpy;
@@ -298,5 +326,5 @@ public class X11Util {
return (NamedDisplay) displayMap.get(name);
}
- private static native void initialize();
+ private static native void initialize(boolean initConcurrentThreadSupport);
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
index 944fdee74..2125fb4c0 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
@@ -74,6 +74,8 @@ public abstract class NativeWindowFactory {
private static String nativeOSNamePure;
private static String nativeWindowingTypeCustom;
private static String nativeOSNameCustom;
+ private static final boolean isAWTAvailable;
+ private static final String awtComponentClassName = "java.awt.Component" ;
/** Creates a new NativeWindowFactory instance. End users do not
need to call this method. */
@@ -123,21 +125,17 @@ public abstract class NativeWindowFactory {
// We break compile-time dependencies on the AWT here to
// make it easier to run this code on mobile devices
- Class componentClass = null;
- if ( ReflectionUtil.isClassAvailable("java.awt.Component") &&
- ReflectionUtil.isClassAvailable("javax.media.nativewindow.awt.AWTGraphicsDevice") ) {
- try {
- componentClass = ReflectionUtil.getClass("java.awt.Component", false);
- } catch (Exception e) { }
- }
+ 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 = Debug.getBooleanProperty("java.awt.headless", true, acc) ||
+ boolean awtToolkitLockDisabled = !isAWTAvailable ||
Debug.getBooleanProperty("nativewindow.nolocking", true, acc) ;
NativeWindowFactory _factory = null;
- if( !awtToolkitLockDisabled && null!=componentClass && TYPE_X11.equals(nativeWindowingTypeCustom) ) {
+ 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,
@@ -195,9 +193,9 @@ public abstract class NativeWindowFactory {
factory = _factory;
}
- if(null!=componentClass) {
+ if ( isAWTAvailable ) {
// register either our default factory or (if exist) the X11/AWT one -> AWT Component
- registerFactory(componentClass, factory);
+ registerFactory(ReflectionUtil.getClass(awtComponentClassName, false), factory);
}
defaultFactory = factory;
@@ -207,6 +205,9 @@ public abstract class NativeWindowFactory {
}
}
+ /** @return true if not headless, AWT Component and NativeWindow's AWT part available */
+ public static boolean isAWTAvailable() { return isAWTAvailable; }
+
public static String getNativeOSName(boolean useCustom) {
return useCustom?nativeOSNameCustom:nativeOSNamePure;
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java
index 9b48f8f6e..f56248e67 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java
@@ -40,7 +40,9 @@
package javax.media.nativewindow.awt;
import javax.media.nativewindow.*;
+import java.awt.Component;
import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
import java.awt.Transparency;
import java.awt.image.ColorModel;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
@@ -67,6 +69,40 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple
this.encapsulated=null;
}
+ /**
+ * @param capsChosen if null, <code>capsRequested</code> is copied and aligned
+ * with the graphics capabilties of the AWT Component to produce the chosen Capabilties.
+ * Otherwise the <code>capsChosen</code> is used.
+ */
+ public static AWTGraphicsConfiguration create(Component awtComp, Capabilities capsChosen, Capabilities capsRequested)
+ {
+ AWTGraphicsScreen awtScreen = null;
+ AWTGraphicsDevice awtDevice = null;
+ GraphicsDevice awtGraphicsDevice = null;
+ GraphicsConfiguration awtGfxConfig = awtComp.getGraphicsConfiguration();
+ if(null!=awtGfxConfig) {
+ awtGraphicsDevice = awtGfxConfig.getDevice();
+ if(null!=awtGraphicsDevice) {
+ // Create Device/Screen
+ awtDevice = new AWTGraphicsDevice(awtGraphicsDevice);
+ awtScreen = new AWTGraphicsScreen(awtDevice);
+ }
+ }
+ if(null==awtScreen) {
+ // use defaults since no native peer is available yet
+ awtScreen = (AWTGraphicsScreen) AWTGraphicsScreen.createScreenDevice(-1);
+ awtDevice = (AWTGraphicsDevice) awtScreen.getDevice();
+ awtGraphicsDevice = awtDevice.getGraphicsDevice();
+ }
+
+ if(null==capsChosen) {
+ capsChosen = (Capabilities) capsRequested.clone() ;
+ GraphicsConfiguration gc = awtGraphicsDevice.getDefaultConfiguration();
+ setupCapabilitiesRGBABits(capsChosen, gc);
+ }
+ return new AWTGraphicsConfiguration(awtScreen, capsChosen, capsRequested, awtGfxConfig);
+ }
+
public Object clone() {
return super.clone();
}
diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c
index b8a5004c4..23ff5f854 100644
--- a/src/nativewindow/native/x11/Xmisc.c
+++ b/src/nativewindow/native/x11/Xmisc.c
@@ -247,8 +247,18 @@ static void x11IOErrorHandlerEnable(int onoff, JNIEnv * env) {
static int _initialized=0;
JNIEXPORT void JNICALL
-Java_com_jogamp_nativewindow_impl_x11_X11Util_initialize(JNIEnv *env, jclass _unused) {
+Java_com_jogamp_nativewindow_impl_x11_X11Util_initialize(JNIEnv *env, jclass _unused, jboolean initConcurrentThreadSupport) {
if(0==_initialized) {
+ if( JNI_TRUE == initConcurrentThreadSupport ) {
+ if( 0 == XInitThreads() ) {
+ fprintf(stderr, "Warning: XInitThreads() failed\n");
+ } else {
+ fprintf(stderr, "Info: XInitThreads() called for concurrent Thread support\n");
+ }
+ } else {
+ fprintf(stderr, "Info: XInitThreads() _not_ called for concurrent Thread support\n");
+ }
+
_initClazzAccess(env);
x11ErrorHandlerEnable(1, env);
x11IOErrorHandlerEnable(1, env);
@@ -350,7 +360,6 @@ Java_com_jogamp_nativewindow_impl_x11_X11Lib_XUnlockDisplay__J(JNIEnv *env, jcla
XUnlockDisplay((Display *) (intptr_t) display);
}
-
/* Java->C glue code:
* Java package: com.jogamp.nativewindow.impl.x11.X11Lib
* Java method: int XCloseDisplay(long display)