aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xmake/scripts/tests.sh50
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java3
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java37
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java13
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java2
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java2
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java2
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java3
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java99
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java18
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java9
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java (renamed from src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java)60
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java141
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java3
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java3
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java119
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java7
-rw-r--r--src/nativewindow/native/x11/Xmisc.c38
-rw-r--r--src/newt/classes/com/jogamp/newt/Display.java35
-rw-r--r--src/newt/classes/com/jogamp/newt/NewtFactory.java2
-rw-r--r--src/newt/classes/com/jogamp/newt/Screen.java2
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java79
-rw-r--r--src/newt/classes/jogamp/newt/ScreenImpl.java3
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java33
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java1
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java1
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java65
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java31
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java107
-rw-r--r--src/newt/native/X11Common.h1
-rw-r--r--src/newt/native/X11Display.c91
-rw-r--r--src/newt/native/X11Window.c10
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java (renamed from src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrentNEWT.java)84
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent01NEWT.java (renamed from src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java)82
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent02NEWT.java78
38 files changed, 701 insertions, 623 deletions
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 8a0a638ba..3dc983072 100755
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -81,6 +81,7 @@ function jrun() {
#D_ARGS="-Djogl.debug.GLDebugMessageHandler -Djogl.debug.TraceGL -Djogl.debug.DebugGL -Djogl.debug.GLSLCode -Djogl.debug.GLSLState"
#D_ARGS="-Djogl.debug.GLDebugMessageHandler -Djogl.debug.DebugGL -Djogl.debug.TraceGL"
#D_ARGS="-Djogamp.debug.NativeLibrary -Djogamp.debug.NativeLibrary.UseCurrentThreadLibLoader"
+ #D_ARGS="-Djogamp.debug.NativeLibrary"
#D_ARGS="-Djogl.1thread=false -Djogl.debug.Threading"
#D_ARGS="-Djogl.1thread=true -Djogl.debug.Threading"
#D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL -Djogl.debug.GLContext.TraceSwitch -Djogl.debug=all"
@@ -100,7 +101,6 @@ function jrun() {
#D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile -Djogl.debug.GLDrawable"
#D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile"
#D_ARGS="-Djogl.debug.GLProfile"
- #D_ARGS="-Dnewt.debug.EDT -Dnativewindow.debug.ToolkitLock.TraceLock -Dnativewindow.debug.NativeWindow"
#D_ARGS="-Dnativewindow.debug.NativeWindow"
#D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT"
#D_ARGS="-Dnewt.debug.EDT -Dnewt.debug.Window -Djogl.debug.GLContext"
@@ -109,6 +109,7 @@ function jrun() {
#D_ARGS="-Dnativewindow.debug.X11Util -Dnativewindow.debug.X11Util.XSync"
#D_ARGS="-Dnativewindow.debug.X11Util.XSync -Dnewt.debug.Window"
#D_ARGS="-Djogl.debug.GLDrawable -Djogl.debug.GLContext"
+ #D_ARGS="-Dnativewindow.debug.NativeWindow -Dnativewindow.debug.X11Util"
#D_ARGS="-Djogamp.common.utils.locks.Lock.timeout=3000 -Djogamp.debug.Lock -Djogl.debug.GLContext.TraceSwitch"
#D_ARGS="-Djogamp.common.utils.locks.Lock.timeout=600000 -Djogamp.debug.Lock -Djogamp.debug.Lock.TraceLock"
#D_ARGS="-Djogamp.common.utils.locks.Lock.timeout=600000 -Djogamp.debug.Lock -Djogamp.debug.Lock.TraceLock -Dnativewindow.debug.ToolkitLock.TraceLock"
@@ -135,7 +136,9 @@ function jrun() {
#D_ARGS="-Djogl.debug.Animator"
#D_ARGS="-Dnativewindow.debug=all"
#D_ARGS="-Djogl.debug.GLCanvas"
- #D_ARGS="-Dnativewindow.debug.ToolkitLock.TraceLock"
+ #D_ARGS="-Djogl.debug.GLContext -Dnativewindow.debug.X11Util.XSync"
+ #D_ARGS="-Dnativewindow.debug.X11Util.XSync"
+ #D_ARGS="-Dnativewindow.debug.ToolkitLock"
#D_ARGS="-Djogl.debug.graph.curve -Djogl.debug.GLSLCode -Djogl.debug.TraceGL"
#D_ARGS="-Djogl.debug.graph.curve -Djogl.debug.GLSLState"
#D_ARGS="-Djogamp.debug.JNILibLoader -Djogamp.debug.TempJarCache -Djogamp.debug.JarUtil"
@@ -187,6 +190,8 @@ function jrun() {
#export LD_LIBRARY_PATH=/opt-linux-x86_64/mesa-7.8.1/lib64:$LD_LIBRARY_PATH
#export LD_LIBRARY_PATH=/usr/lib/mesa:/usr/lib32/mesa:$LD_LIBRARY_PATH
#export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/mesa:/usr/lib/i386-linux-gnu/mesa:$LD_LIBRARY_PATH
+ #export LD_LIBRARY_PATH=`pwd`/lib/external/mesa/x86_64-linux-gnu:$LD_LIBRARY_PATH
+ #export LD_LIBRARY_PATH=`pwd`/lib/external/mesa/x86_64-linux-gnu/gallium:$LD_LIBRARY_PATH
echo
echo "Test Start: $*"
echo
@@ -194,10 +199,10 @@ function jrun() {
echo
echo $javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $*
#LIBGL_DRIVERS_PATH=/usr/lib/mesa:/usr/lib32/mesa \
- #gdb --args $javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $*
#LIBGL_DEBUG=verbose INTEL_STRICT_CONFORMANCE=1 INTEL_DEBUG="buf bat" \
#LIBGL_DEBUG=verbose MESA_DEBUG=true INTEL_STRICT_CONFORMANCE=1 \
- #LIBGL_DEBUG=verbose MESA_DEBUG=true LIBGL_ALWAYS_SOFTWARE=true \
+ #export LIBGL_DEBUG=verbose MESA_DEBUG=true LIBGL_ALWAYS_SOFTWARE=true
+ #gdb --args $javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $*
$javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $*
echo
echo "Test End: $*"
@@ -239,7 +244,8 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile00NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrentNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrent01NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrent02NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextSurfaceLockNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug00NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug01NEWT $*
@@ -250,6 +256,38 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextDrawableSwitchNEWT $*
+# x11 no XinitThreads() specific tests (regressions, concurrent behavior) !
+# Deadlock:
+# com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT2 - test01
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT2 $*
+# com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT - testEachWithAnimatorSharedOffscreen
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT $*
+#
+# XCB:
+#
+# com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT - testShaderState01PerformanceDouble
+#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT $*
+# com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT - testWindowParenting02ReparentTop2WinReparentRecreate
+#testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT $*
+# com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT - winHopFrame2FrameDirectHop
+#testawtswt com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT $*
+#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting04AWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOOffThreadSharedContextMix2DemosES2NEWT $*
+
+#testnoawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle02NEWT
+#testnoawt com.jogamp.opengl.test.junit.newt.TestWindows01NEWT $*
+testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrent01NEWT $*
+testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrent02NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMix2DemosES2NEWT $*
+#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting04AWT $*
+#testnoawt com.jogamp.opengl.test.junit.newt.TestRemoteGLWindows01NEWT $*
+#testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTEclipseGLCanvas01GLn $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT2 $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOOffThreadSharedContextMix2DemosES2NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOOnThreadSharedContext1DemoES2NEWT $*
+
+
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateOnOffscrnCapsNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT $*
@@ -322,7 +360,7 @@ function testawtswt() {
#testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWT02WindowClosing
#testawt com.jogamp.opengl.test.junit.jogl.awt.text.TestAWTTextRendererUseVertexArrayBug464
#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWT $*
-testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWTAnalyzeBug455 $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWTBug450 $*
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
index ce2e824f5..0a603ab8a 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
@@ -71,10 +71,9 @@ public class EGLDisplayUtil {
Thread.dumpStack();
}
if( eglDisplayCounter.size() > 0) {
- EGLDisplayUtil.dumpOpenDisplayConnections();
+ dumpOpenDisplayConnections();
}
}
-
return eglDisplayCounter.size();
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
index e1e25be67..bdccc1047 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
@@ -172,7 +172,6 @@ public abstract class X11GLXContext extends GLContextImpl {
glXMakeContextCurrent(display, 0, 0, 0);
GLX.glXDestroyContext(display, ctx);
}
-
private static final int ctx_arb_attribs_idx_major = 0;
private static final int ctx_arb_attribs_idx_minor = 2;
private static final int ctx_arb_attribs_idx_flags = 6;
@@ -228,14 +227,14 @@ public abstract class X11GLXContext extends GLContextImpl {
X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration();
AbstractGraphicsDevice device = config.getScreen().getDevice();
- long display = device.getHandle();
+ final long display = device.getHandle();
try {
// critical path, a remote display might not support this command,
// hence we need to catch the X11 Error within this block.
- X11Lib.XSync(display, false);
+ X11Util.setX11ErrorHandler(true, DEBUG ? false : true); // make sure X11 error handler is set
ctx = _glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs);
- X11Lib.XSync(display, false);
+ if(DEBUG) { X11Lib.XSync(display, false); }
} catch (RuntimeException re) {
if(DEBUG) {
Throwable t = new Throwable(getThreadName()+": Info: X11GLXContext.createContextARBImpl glXCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re);
@@ -263,16 +262,6 @@ public abstract class X11GLXContext extends GLContextImpl {
@Override
protected boolean createImpl(GLContextImpl shareWith) {
- // covers the whole context creation loop incl createContextARBImpl and destroyContextARBImpl
- X11Util.setX11ErrorHandler(true, DEBUG ? false : true);
- try {
- return createImplRaw(shareWith);
- } finally {
- X11Util.setX11ErrorHandler(false, false);
- }
- }
-
- private boolean createImplRaw(GLContextImpl shareWith) {
boolean direct = true; // try direct always
isDirect = false; // fall back
@@ -401,14 +390,9 @@ public abstract class X11GLXContext extends GLContextImpl {
protected void makeCurrentImpl() throws GLException {
long dpy = drawable.getNativeSurface().getDisplayHandle();
- if (GLX.glXGetCurrentContext() != contextHandle) {
- X11Util.setX11ErrorHandler(true, DEBUG ? false : true);
- try {
- if (!glXMakeContextCurrent(dpy, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
- throw new GLException(getThreadName()+": Error making context current: "+this);
- }
- } finally {
- X11Util.setX11ErrorHandler(false, false);
+ if (GLX.glXGetCurrentContext() != contextHandle) {
+ if (!glXMakeContextCurrent(dpy, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
+ throw new GLException(getThreadName()+": Error making context current: "+this);
}
}
}
@@ -416,13 +400,8 @@ public abstract class X11GLXContext extends GLContextImpl {
@Override
protected void releaseImpl() throws GLException {
long display = drawable.getNativeSurface().getDisplayHandle();
- X11Util.setX11ErrorHandler(true, DEBUG ? false : true);
- try {
- if (!glXMakeContextCurrent(display, 0, 0, 0)) {
- throw new GLException(getThreadName()+": Error freeing OpenGL context");
- }
- } finally {
- X11Util.setX11ErrorHandler(false, false);
+ if (!glXMakeContextCurrent(display, 0, 0, 0)) {
+ throw new GLException(getThreadName()+": Error freeing OpenGL context");
}
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index ca5cd424b..03c661565 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -47,7 +47,6 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.nativewindow.VisualIDHolder;
@@ -230,11 +229,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
@Override
public SharedResourceRunner.Resource createSharedResource(String connection) {
- final X11GraphicsDevice sharedDevice =
- new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT,
- true); // own non-shared display connection, w/ locking
- // new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT,
- // NativeWindowFactory.getNullToolkitLock(), true); // own non-shared display connection, w/o locking
+ final X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT, true);
sharedDevice.lock();
try {
final X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, sharedDevice.getDefaultScreen());
@@ -509,8 +504,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) {
final X11GraphicsDevice device;
if(createNewDevice) {
- // Null X11 locking, due to private non-shared Display handle
- device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), NativeWindowFactory.getNullToolkitLock(), true);
+ // Null X11 resource locking, due to private non-shared Display handle
+ device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), true);
} else {
device = (X11GraphicsDevice)deviceReq;
}
@@ -531,7 +526,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
@Override
protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
- final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), NativeWindowFactory.getNullToolkitLock(), true);
+ final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), true);
final X11GraphicsScreen screen = new X11GraphicsScreen(device, screenIdx);
final int xvisualID = X11Lib.GetVisualIDFromWindow(device.getHandle(), windowHandle);
if(VisualIDHolder.VID_UNDEFINED == xvisualID) {
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
index 152384980..2e4099c1b 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
@@ -73,7 +73,7 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
/**
* @param display the Display connection
- * @param locker custom {@link javax.media.nativewindow.ToolkitLock}, eg to force null locking in NEWT
+ * @param locker custom {@link javax.media.nativewindow.ToolkitLock}, eg to force null locking w/ private connection
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(String, String, int, long, ToolkitLock)
*/
public X11GraphicsDevice(long display, int unitID, ToolkitLock locker, boolean owner) {
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
index 5f3c220ca..7ab5bd6aa 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
@@ -63,7 +63,7 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
private static int fetchScreen(X11GraphicsDevice device, int screen) {
// It still could be an AWT hold handle ..
- if(X11Util.XineramaIsEnabled(device.getHandle())) {
+ if(X11Util.XineramaIsEnabled(device)) {
screen = 0; // Xinerama -> 1 screen
}
return screen;
diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
index 756e4451b..5eaaa6613 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
@@ -131,7 +131,7 @@ public interface AbstractGraphicsDevice extends Cloneable {
/**
* Optionally closing the device if handle is not <code>null</code>.
* <p>
- * The default implementation is a <code>NOP</code>, just setting the handle to <code>null</code>.
+ * The default implementation {@link ToolkitLock#dispose() dispose} it's {@link ToolkitLock} and sets the handle to <code>null</code>.
* </p>
* <p>
* Example implementations like {@link com.jogamp.nativewindow.x11.X11GraphicsDevice}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
index 583fde07f..b16b0c75c 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
@@ -153,6 +153,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
@Override
public boolean close() {
+ toolkitLock.dispose();
if(0 != handle) {
handle = 0;
return true;
@@ -162,7 +163,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
@Override
public String toString() {
- return getClass().getSimpleName()+"[type "+getType()+", connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+"]";
+ return getClass().getSimpleName()+"[type "+getType()+", connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+", "+toolkitLock+"]";
}
/**
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
index 40aaa8a25..4f4bb629b 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
@@ -33,7 +33,6 @@
package javax.media.nativewindow;
-import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -43,6 +42,7 @@ import java.util.Map;
import jogamp.nativewindow.Debug;
import jogamp.nativewindow.NativeWindowFactoryImpl;
+import jogamp.nativewindow.ResourceToolkitLock;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.ReflectionUtil;
@@ -93,13 +93,6 @@ public abstract class NativeWindowFactory {
private static ToolkitLock jawtUtilJAWTToolkitLock;
- public static final String X11JAWTToolkitLockClassName = "jogamp.nativewindow.jawt.x11.X11JAWTToolkitLock" ;
- public static final String X11ToolkitLockClassName = "jogamp.nativewindow.x11.X11ToolkitLock" ;
-
- private static Class<?> x11JAWTToolkitLockClass;
- private static Constructor<?> x11JAWTToolkitLockConstructor;
- private static Class<?> x11ToolkitLockClass;
- private static Constructor<?> x11ToolkitLockConstructor;
private static boolean requiresToolkitLock;
private static volatile boolean isJVMShuttingDown = false;
@@ -266,16 +259,6 @@ public abstract class NativeWindowFactory {
// register either our default factory or (if exist) the X11/AWT one -> AWT Component
registerFactory(ReflectionUtil.getClass(ReflectionUtil.AWTNames.ComponentClass, false, cl), factory);
}
-
- if( TYPE_X11 == nativeWindowingTypePure ) {
- // passing through RuntimeException if not exists intended
- x11ToolkitLockClass = ReflectionUtil.getClass(X11ToolkitLockClassName, false, cl);
- x11ToolkitLockConstructor = ReflectionUtil.getConstructor(x11ToolkitLockClass, new Class[] { long.class } );
- if( isAWTAvailable() ) {
- x11JAWTToolkitLockClass = ReflectionUtil.getClass(X11JAWTToolkitLockClassName, false, cl);
- x11JAWTToolkitLockConstructor = ReflectionUtil.getConstructor(x11JAWTToolkitLockClass, new Class[] { long.class } );
- }
- }
if(DEBUG) {
System.err.println("NativeWindowFactory requiresToolkitLock "+requiresToolkitLock);
@@ -300,6 +283,7 @@ public abstract class NativeWindowFactory {
GraphicsConfigurationFactory.shutdown();
}
shutdownNativeImpl(NativeWindowFactory.class.getClassLoader()); // always re-shutdown
+ // SharedResourceToolkitLock.shutdown(DEBUG); // not used yet
if(DEBUG) {
System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END JVM Shutdown "+isJVMShuttingDown);
}
@@ -358,16 +342,9 @@ public abstract class NativeWindowFactory {
/**
* Provides the default {@link ToolkitLock} for <code>type</code>, a singleton instance.
- * <br>
* <ul>
- * <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li>
- * <ul>
- * <li>If <b>AWT-type</b> and <b>native-X11-type</b> and <b>AWT-available</b></li>
- * <ul>
- * <li> return {@link #getAWTToolkitLock()} </li>
- * </ul>
- * </ul>
- * <li> Otherwise return {@link #getNullToolkitLock()} </li>
+ * <li> JAWT {@link ToolkitLock} if required and AWT available, otherwise</li>
+ * <li> {@link jogamp.nativewindow.NullToolkitLock} </li>
* </ul>
*/
public static ToolkitLock getDefaultToolkitLock(String type) {
@@ -390,84 +367,36 @@ public abstract class NativeWindowFactory {
/**
* Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>.
- * <br>
* <ul>
- * <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li>
- * <ul>
- * <li>If <b>X11 type</b> </li>
- * <ul>
- * <li> return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li>
- * </ul>
- * </ul>
- * <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li>
+ * <li> {@link jogamp.nativewindow.ResourceToolkitLock} if required, otherwise</li>
+ * <li> {@link jogamp.nativewindow.NullToolkitLock} </li>
* </ul>
*/
public static ToolkitLock createDefaultToolkitLock(String type, long deviceHandle) {
if( requiresToolkitLock() ) {
- if( TYPE_X11 == type ) {
- if( 0== deviceHandle ) {
- throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11");
- }
- return createX11ToolkitLock(deviceHandle);
- }
+ return ResourceToolkitLock.create();
}
return NativeWindowFactoryImpl.getNullToolkitLock();
}
/**
* Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>.
- * <br>
* <ul>
- * <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li>
- * <ul>
- * <li>If <b>X11 type</b> </li>
- * <ul>
- * <li> If <b>shared-AWT-type</b> and <b>AWT available</b> </li>
- * <ul>
- * <li> return {@link jogamp.nativewindow.jawt.x11.X11JAWTToolkitLock} </li>
- * </ul>
- * <li> else return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li>
- * </ul>
- * </ul>
- * <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li>
+ * <li> JAWT {@link ToolkitLock} if required and AWT available,</li>
+ * <li> {@link jogamp.nativewindow.ResourceToolkitLock} if required, otherwise</li>
+ * <li> {@link jogamp.nativewindow.NullToolkitLock} </li>
* </ul>
*/
public static ToolkitLock createDefaultToolkitLock(String type, String sharedType, long deviceHandle) {
if( requiresToolkitLock() ) {
- if( TYPE_X11 == type ) {
- if( 0== deviceHandle ) {
- throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11");
- }
- if( TYPE_AWT == sharedType && isAWTAvailable() ) {
- return createX11AWTToolkitLock(deviceHandle);
- }
- return createX11ToolkitLock(deviceHandle);
+ if( TYPE_AWT == sharedType && isAWTAvailable() ) {
+ return getAWTToolkitLock();
}
+ return ResourceToolkitLock.create();
}
return NativeWindowFactoryImpl.getNullToolkitLock();
}
-
- protected static ToolkitLock createX11AWTToolkitLock(long deviceHandle) {
- try {
- if(DEBUG) {
- System.err.println("NativeWindowFactory.createX11AWTToolkitLock(0x"+Long.toHexString(deviceHandle)+")");
- // Thread.dumpStack();
- }
- return (ToolkitLock) x11JAWTToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)});
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
- protected static ToolkitLock createX11ToolkitLock(long deviceHandle) {
- try {
- return (ToolkitLock) x11ToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)});
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
-
+
/** Returns the appropriate NativeWindowFactory to handle window
objects of the given type. The windowClass might be {@link
NativeWindow NativeWindow}, in which case the client has
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
index 30f9660f0..18b7cf5d9 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
@@ -33,12 +33,26 @@ import jogamp.nativewindow.Debug;
/**
* Marker for a singleton global recursive blocking lock implementation,
* optionally locking a native windowing toolkit as well.
- * <br>
- * One use case is the AWT locking on X11, see {@link jogamp.nativewindow.jawt.JAWTToolkitLock}.
+ * <p>
+ * Toolkit locks are created solely via {@link NativeWindowFactory}.
+ * </p>
+ * <p>
+ * One use case is the AWT locking on X11, see {@link NativeWindowFactory#createDefaultToolkitLock(String, long)}.
+ * </p>
*/
public interface ToolkitLock {
public static final boolean TRACE_LOCK = Debug.isPropertyDefined("nativewindow.debug.ToolkitLock.TraceLock", true);
public void lock();
public void unlock();
+
+ /**
+ * Dispose this instance.
+ * <p>
+ * Shall be called when instance is no more required.
+ * </p>
+ * This allows implementations sharing a lock via resources
+ * to decrease the reference counter.
+ */
+ public void dispose();
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java
index 1af6bf279..e59910138 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java
@@ -50,4 +50,13 @@ public class NullToolkitLock implements ToolkitLock {
public final void unlock() {
if(TRACE_LOCK) { System.err.println("NullToolkitLock.unlock()"); }
}
+
+ public final void dispose() {
+ // nop
+ }
+
+ public String toString() {
+ return "NullToolkitLock[]";
+ }
+
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java
index 5166ef577..a3b0804fa 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 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:
@@ -25,7 +25,8 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
-package jogamp.nativewindow.x11;
+
+package jogamp.nativewindow;
import javax.media.nativewindow.ToolkitLock;
@@ -33,38 +34,41 @@ import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
/**
- * Implementing a recursive {@link javax.media.nativewindow.ToolkitLock}
- * utilizing {@link X11Util#XLockDisplay(long)}.
- * <br>
- * This strategy should not be used in case XInitThreads() is being used,
- * or a higher level toolkit lock is required, ie AWT lock.
+ * Implementing a resource based recursive {@link javax.media.nativewindow.ToolkitLock}.
+ * <p>
+ * A resource handle maybe used within a unique object
+ * and can be synchronized across threads via an instance of ResourceToolkitLock.
+ * </p>
*/
-public class X11ToolkitLock implements ToolkitLock {
- long displayHandle;
- RecursiveLock lock;
-
- public X11ToolkitLock(long displayHandle) {
- this.displayHandle = displayHandle;
- if(!X11Util.isNativeLockAvailable()) {
- lock = LockFactory.createRecursiveLock();
- }
+public class ResourceToolkitLock implements ToolkitLock {
+ public static final boolean DEBUG = Debug.debug("ToolkitLock");
+
+ public static final ResourceToolkitLock create() {
+ return new ResourceToolkitLock();
}
+ private final RecursiveLock lock;
+
+ private ResourceToolkitLock() {
+ this.lock = LockFactory.createRecursiveLock();
+ }
+
+
public final void lock() {
- if(TRACE_LOCK) { System.err.println("X11ToolkitLock.lock() - native: "+(null==lock)); }
- if(null == lock) {
- X11Lib.XLockDisplay(displayHandle);
- } else {
- lock.lock();
- }
+ if(TRACE_LOCK) { System.err.println("ResourceToolkitLock.lock()"); }
+ lock.lock();
}
public final void unlock() {
- if(TRACE_LOCK) { System.err.println("X11ToolkitLock.unlock() - native: "+(null==lock)); }
- if(null == lock) {
- X11Lib.XUnlockDisplay(displayHandle);
- } else {
- lock.unlock();
- }
+ if(TRACE_LOCK) { System.err.println("ResourceToolkitLock.unlock()"); }
+ lock.unlock();
+ }
+
+ public final void dispose() {
+ // nop
+ }
+
+ public String toString() {
+ return "ResourceToolkitLock[obj 0x"+Integer.toHexString(hashCode())+", isOwner "+lock.isOwner(Thread.currentThread())+", "+lock.toString()+"]";
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java
new file mode 100644
index 000000000..5d7ae8abb
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java
@@ -0,0 +1,141 @@
+/**
+ * Copyright 2012 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package jogamp.nativewindow;
+
+import java.util.Iterator;
+
+import javax.media.nativewindow.ToolkitLock;
+
+import com.jogamp.common.util.LongObjectHashMap;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
+
+/**
+ * Implementing a shared resource based recursive {@link javax.media.nativewindow.ToolkitLock}.
+ * <p>
+ * A resource handle maybe used within many objects
+ * and can be synchronized across threads via an unique instance of SharedResourceToolkitLock.
+ * </p>
+ * <p>
+ * Implementation holds a synchronized map from handle to reference counted {@link SharedResourceToolkitLock}.
+ * New elements are added via {@link #get(long)} if new
+ * and removed via {@link #dispose()} if no more referenced.
+ * </p>
+ */
+public class SharedResourceToolkitLock implements ToolkitLock {
+ public static final boolean DEBUG = Debug.debug("ToolkitLock");
+ private static final LongObjectHashMap handle2Lock;
+ static {
+ handle2Lock = new LongObjectHashMap();
+ handle2Lock.setKeyNotFoundValue(null);
+ }
+
+ /**
+ * @return number of unclosed EGL Displays.<br>
+ */
+ public static int shutdown(boolean verbose) {
+ if(DEBUG || verbose || handle2Lock.size() > 0 ) {
+ System.err.println("SharedResourceToolkitLock: Shutdown (open: "+handle2Lock.size()+")");
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
+ if( handle2Lock.size() > 0) {
+ dumpOpenDisplayConnections();
+ }
+ }
+ return handle2Lock.size();
+ }
+
+ public static void dumpOpenDisplayConnections() {
+ System.err.println("SharedResourceToolkitLock: Open ResourceToolkitLock's: "+handle2Lock.size());
+ int i=0;
+ for(Iterator<LongObjectHashMap.Entry> iter = handle2Lock.iterator(); iter.hasNext(); i++) {
+ final LongObjectHashMap.Entry e = iter.next();
+ System.err.println("SharedResourceToolkitLock: Open["+i+"]: "+e.value);
+ }
+ }
+
+ public static final SharedResourceToolkitLock get(long handle) {
+ SharedResourceToolkitLock res;
+ synchronized(handle2Lock) {
+ res = (SharedResourceToolkitLock) handle2Lock.get(handle);
+ if( null == res ) {
+ res = new SharedResourceToolkitLock(handle);
+ res.refCount++;
+ handle2Lock.put(handle, res);
+ if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.get() * NEW *: "+res); }
+ } else {
+ res.refCount++;
+ if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.get() * EXIST *: "+res); }
+ }
+ }
+ return res;
+ }
+
+ private final RecursiveLock lock;
+ private final long handle;
+ private volatile int refCount;
+
+ private SharedResourceToolkitLock(long handle) {
+ this.lock = LockFactory.createRecursiveLock();
+ this.handle = handle;
+ this.refCount = 0;
+ }
+
+
+ public final void lock() {
+ if(TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.lock()"); }
+ lock.lock();
+ }
+
+ public final void unlock() {
+ if(TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.unlock()"); }
+ lock.unlock();
+ }
+
+ public final void dispose() {
+ if(0 < refCount) { // volatile OK
+ synchronized(handle2Lock) {
+ refCount--;
+ if(0 == refCount) {
+ if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.dispose() * REMOV *: "+this); }
+ handle2Lock.remove(handle);
+ } else {
+ if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.dispose() * DOWN *: "+this); }
+ }
+ }
+ } else {
+ if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.dispose() * NULL *: "+this); }
+ }
+ }
+
+ public String toString() {
+ return "SharedResourceToolkitLock[refCount "+refCount+", handle 0x"+Long.toHexString(handle)+", obj 0x"+Integer.toHexString(hashCode())+", isOwner "+lock.isOwner(Thread.currentThread())+", "+lock.toString()+"]";
+ }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
index f1e8a786a..7c934b154 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
@@ -237,6 +237,9 @@ public class JAWTUtil {
public final void unlock() {
JAWTUtil.unlockToolkit();
}
+ public final void dispose() {
+ // nop
+ }
};
// trigger native AWT toolkit / properties initialization
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
index 736718de8..467809284 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
@@ -127,7 +127,8 @@ public class X11JAWTWindow extends JAWTWindow {
}
protected Point getLocationOnScreenNativeImpl(int x, int y) {
- return X11Lib.GetRelativeLocation( getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+ // surface is locked and hence the device
+ return X11Lib.GetRelativeLocation(getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
}
// Variables for lockSurface/unlockSurface
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
index 2ea75c7fb..60f54eb3c 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
@@ -42,8 +42,8 @@ import javax.media.nativewindow.NativeWindowFactory;
import jogamp.nativewindow.Debug;
import jogamp.nativewindow.NWJNILibLoader;
-
import com.jogamp.common.util.LongObjectHashMap;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
/**
* Contains a thread safe X11 utility to retrieve display connections.
@@ -80,25 +80,15 @@ public class X11Util {
*/
public static final boolean ATI_HAS_XCLOSEDISPLAY_BUG = !Debug.isPropertyDefined("nativewindow.debug.X11Util.ATI_HAS_NO_XCLOSEDISPLAY_BUG", true);
- /** Value is <code>true</code>, best 'stable' results if always using XInitThreads(). */
- public static final boolean XINITTHREADS_ALWAYS_ENABLED = true;
-
- /** Value is <code>true</code>, best 'stable' results if not using XLockDisplay/XUnlockDisplay at all. */
- public static final boolean HAS_XLOCKDISPLAY_BUG = true;
-
public static final boolean DEBUG = Debug.debug("X11Util");
public static final boolean XSYNC_ENABLED = Debug.isPropertyDefined("nativewindow.debug.X11Util.XSync", true);
public static final boolean XERROR_STACKDUMP = DEBUG || Debug.isPropertyDefined("nativewindow.debug.X11Util.XErrorStackDump", true);
private static final boolean TRACE_DISPLAY_LIFECYCLE = Debug.isPropertyDefined("nativewindow.debug.X11Util.TraceDisplayLifecycle", true);
private static String nullDisplayName = null;
- private static boolean isX11LockAvailable = false;
- private static boolean requiresX11Lock = true;
private static volatile boolean isInit = false;
private static boolean markAllDisplaysUnclosable = false; // ATI/AMD X11 driver issues
- private static int setX11ErrorHandlerRecCount = 0;
private static Object setX11ErrorHandlerLock = new Object();
-
/**
* Called by {@link NativeWindowFactory#initSingleton()}
@@ -115,9 +105,7 @@ public class X11Util {
throw new NativeWindowException("NativeWindow X11 native library load error.");
}
- final boolean callXInitThreads = XINITTHREADS_ALWAYS_ENABLED ;
- final boolean isXInitThreadsOK = initialize0( callXInitThreads, XERROR_STACKDUMP);
- isX11LockAvailable = isXInitThreadsOK && !HAS_XLOCKDISPLAY_BUG ;
+ final boolean isInitOK = initialize0( XERROR_STACKDUMP );
final long dpy = X11Lib.XOpenDisplay(null);
if(0 != dpy) {
@@ -134,9 +122,7 @@ public class X11Util {
}
if(DEBUG) {
- System.err.println("X11Util requiresX11Lock "+requiresX11Lock+
- ", XInitThreads [called "+callXInitThreads+", OK "+isXInitThreadsOK+"]"+
- ", isX11LockAvailable "+isX11LockAvailable+
+ System.err.println("X11Util init OK "+isInitOK+"]"+
", X11 Display(NULL) <"+nullDisplayName+">"+
", XSynchronize Enabled: "+XSYNC_ENABLED);
// Thread.dumpStack();
@@ -199,31 +185,14 @@ public class X11Util {
}
}
}
-
- public static synchronized boolean isNativeLockAvailable() {
- return isX11LockAvailable;
- }
-
- public static synchronized boolean requiresToolkitLock() {
- return requiresX11Lock;
+
+ public static boolean requiresToolkitLock() {
+ return true; // JAWT locking: yes, instead of native X11 locking w use a recursive lock.
}
-
+
public static void setX11ErrorHandler(boolean onoff, boolean quiet) {
synchronized(setX11ErrorHandlerLock) {
- if(onoff) {
- if(0==setX11ErrorHandlerRecCount) {
- setX11ErrorHandler0(true, quiet);
- }
- setX11ErrorHandlerRecCount++;
- } else {
- if(0 >= setX11ErrorHandlerRecCount) {
- throw new InternalError();
- }
- setX11ErrorHandlerRecCount--;
- if(0==setX11ErrorHandlerRecCount) {
- setX11ErrorHandler0(false, false);
- }
- }
+ setX11ErrorHandler0(onoff, quiet);
}
}
@@ -492,52 +461,50 @@ public class X11Util {
*******************************/
public static long XOpenDisplay(String arg0) {
- NativeWindowFactory.getDefaultToolkitLock().lock();
- try {
- long handle = X11Lib.XOpenDisplay(arg0);
- if(XSYNC_ENABLED && 0 != handle) {
- X11Lib.XSynchronize(handle, true);
- }
- if(TRACE_DISPLAY_LIFECYCLE) {
- System.err.println(Thread.currentThread()+" - X11Util.XOpenDisplay("+arg0+") 0x"+Long.toHexString(handle));
- // Thread.dumpStack();
- }
- return handle;
- } finally {
- NativeWindowFactory.getDefaultToolkitLock().unlock();
+ long handle = X11Lib.XOpenDisplay(arg0);
+ if(XSYNC_ENABLED && 0 != handle) {
+ X11Lib.XSynchronize(handle, true);
+ }
+ if(TRACE_DISPLAY_LIFECYCLE) {
+ System.err.println(Thread.currentThread()+" - X11Util.XOpenDisplay("+arg0+") 0x"+Long.toHexString(handle));
+ // Thread.dumpStack();
}
+ return handle;
}
public static int XCloseDisplay(long display) {
- NativeWindowFactory.getDefaultToolkitLock().lock();
+ if(TRACE_DISPLAY_LIFECYCLE) {
+ System.err.println(Thread.currentThread()+" - X11Util.XCloseDisplay() 0x"+Long.toHexString(display));
+ // Thread.dumpStack();
+ }
+ int res = -1;
try {
- if(TRACE_DISPLAY_LIFECYCLE) {
- System.err.println(Thread.currentThread()+" - X11Util.XCloseDisplay() 0x"+Long.toHexString(display));
- // Thread.dumpStack();
- }
- int res = -1;
- X11Util.setX11ErrorHandler(true, DEBUG ? false : true);
- try {
- res = X11Lib.XCloseDisplay(display);
- } catch (Exception ex) {
- System.err.println("X11Util: Catched Exception:");
- ex.printStackTrace();
- } finally {
- X11Util.setX11ErrorHandler(false, false);
- }
- return res;
- } finally {
- NativeWindowFactory.getDefaultToolkitLock().unlock();
+ res = X11Lib.XCloseDisplay(display);
+ } catch (Exception ex) {
+ System.err.println("X11Util: Catched Exception:");
+ ex.printStackTrace();
}
+ return res;
}
static volatile boolean XineramaFetched = false;
static long XineramaLibHandle = 0;
static long XineramaQueryFunc = 0;
- public static boolean XineramaIsEnabled(long display) {
- if(0==display) {
- throw new IllegalArgumentException("Display NULL");
+ public static boolean XineramaIsEnabled(X11GraphicsDevice device) {
+ if(null == device) {
+ throw new IllegalArgumentException("X11 Display device is NULL");
+ }
+ device.lock();
+ try {
+ return XineramaIsEnabled(device.getHandle());
+ } finally {
+ device.unlock();
+ }
+ }
+ public static boolean XineramaIsEnabled(long displayHandle) {
+ if( 0 == displayHandle ) {
+ throw new IllegalArgumentException("X11 Display handle is NULL");
}
if(!XineramaFetched) { // volatile: ok
synchronized(X11Util.class) {
@@ -551,9 +518,9 @@ public class X11Util {
}
}
if(0!=XineramaQueryFunc) {
- final boolean res = X11Lib.XineramaIsEnabled(XineramaQueryFunc, display);
+ final boolean res = X11Lib.XineramaIsEnabled(XineramaQueryFunc, displayHandle);
if(DEBUG) {
- System.err.println("XineramaIsEnabled: "+res);
+ System.err.println("XineramaIsEnabled: 0x"+Long.toHexString(displayHandle)+": "+res);
}
return res;
} else if(DEBUG) {
@@ -566,7 +533,7 @@ public class X11Util {
private static final String getCurrentThreadName() { return Thread.currentThread().getName(); } // Callback for JNI
private static final void dumpStack() { Thread.dumpStack(); } // Callback for JNI
- private static native boolean initialize0(boolean firstUIActionOnProcess, boolean debug);
+ private static native boolean initialize0(boolean debug);
private static native void shutdown0();
private static native void setX11ErrorHandler0(boolean onoff, boolean quiet);
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java b/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
index 1de03e8be..b152f0f97 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
@@ -91,7 +91,7 @@ public class X11AWTGraphicsConfigurationFactory extends GraphicsConfigurationFac
final long displayHandleAWT = X11SunJDKReflection.graphicsDeviceGetDisplay(device);
final long displayHandle;
- boolean owner = false;
+ final boolean owner;
if(0==displayHandleAWT) {
displayHandle = X11Util.openDisplay(null);
owner = true;
@@ -112,9 +112,8 @@ public class X11AWTGraphicsConfigurationFactory extends GraphicsConfigurationFac
System.err.println(getThreadName()+" - X11AWTGraphicsConfigurationFactory: AWT dpy "+displayName+" / "+toHexString(displayHandleAWT)+", create X11 display "+toHexString(displayHandle));
}
}
- final ToolkitLock lock = owner ?
- NativeWindowFactory.getDefaultToolkitLock(NativeWindowFactory.TYPE_AWT) : // own non-shared X11 display connection, no X11 lock
- NativeWindowFactory.createDefaultToolkitLock(NativeWindowFactory.TYPE_X11, NativeWindowFactory.TYPE_AWT, displayHandle);
+ // Global JAWT lock required - No X11 resource locking due to private display connection
+ final ToolkitLock lock = NativeWindowFactory.getDefaultToolkitLock(NativeWindowFactory.TYPE_AWT);
final X11GraphicsDevice x11Device = new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, lock, owner);
final X11GraphicsScreen x11Screen = new X11GraphicsScreen(x11Device, awtScreen.getIndex());
if(DEBUG) {
diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c
index fcba8580c..afdd413eb 100644
--- a/src/nativewindow/native/x11/Xmisc.c
+++ b/src/nativewindow/native/x11/Xmisc.c
@@ -178,11 +178,14 @@ static int x11ErrorHandler(Display *dpy, XErrorEvent *e)
char threadName[80];
char errCodeStr[80];
char reqCodeStr[80];
-
int shallBeDetached = 0;
- JNIEnv *jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ JNIEnv *jniEnv = NULL;
+ if( errorHandlerDebug || errorHandlerThrowException ) {
+ jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ }
(void) NativewindowCommon_GetStaticStringMethod(jniEnv, X11UtilClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a");
+
snprintf(errCodeStr, sizeof(errCodeStr), "%d", e->request_code);
XGetErrorDatabaseText(dpy, "XRequest", errCodeStr, "Unknown", reqCodeStr, sizeof(reqCodeStr));
XGetErrorText(dpy, e->error_code, errCodeStr, sizeof(errCodeStr));
@@ -191,7 +194,7 @@ static int x11ErrorHandler(Display *dpy, XErrorEvent *e)
threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
(int)e->request_code, (int)e->minor_code, reqCodeStr);
- if( errorHandlerDebug ) {
+ if( errorHandlerDebug && NULL != jniEnv ) {
(*jniEnv)->CallStaticVoidMethod(jniEnv, X11UtilClazz, dumpStackID);
}
@@ -246,16 +249,17 @@ static int x11IOErrorHandler(Display *dpy)
{
const char * dpyName = XDisplayName(NULL);
const char * errnoStr = strerror(errno);
- char threadName[80];
int shallBeDetached = 0;
- JNIEnv *jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
-
- (void) NativewindowCommon_GetStaticStringMethod(jniEnv, X11UtilClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a");
+ JNIEnv *jniEnv = NULL;
- fprintf(stderr, "Nativewindow X11 IOError (Thread %s): Display %p (%s): %s\n", threadName, dpy, dpyName, errnoStr);
+ fprintf(stderr, "Nativewindow X11 IOError: Display %p (%s): %s\n", dpy, dpyName, errnoStr);
(*jniEnv)->CallStaticVoidMethod(jniEnv, X11UtilClazz, dumpStackID);
+ jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
if (NULL != jniEnv) {
+ char threadName[80];
+ (void) NativewindowCommon_GetStaticStringMethod(jniEnv, X11UtilClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a");
+
NativewindowCommon_FatalError(jniEnv, "Nativewindow X11 IOError (Thread %s): Display %p (%s): %s", threadName, dpy, dpyName, errnoStr);
if (shallBeDetached) {
@@ -305,6 +309,7 @@ Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass clazz, jboo
_initClazzAccess(env);
x11IOErrorHandlerEnable(1, env);
+ NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 1, 0, 0 /* no dpy, no sync */);
_initialized=1;
if(JNI_TRUE == debug) {
fprintf(stderr, "Info: NativeWindow native init passed\n");
@@ -315,6 +320,7 @@ Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass clazz, jboo
JNIEXPORT void JNICALL
Java_jogamp_nativewindow_x11_X11Util_shutdown0(JNIEnv *env, jclass _unused) {
+ NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 0, 0 /* no dpy, no sync */);
x11IOErrorHandlerEnable(0, env);
}
@@ -347,7 +353,7 @@ Java_jogamp_nativewindow_x11_X11Lib_XGetVisualInfo1__JJLjava_nio_ByteBuffer_2Lja
}
NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 1, 0, 0);
_res = XGetVisualInfo((Display *) (intptr_t) arg0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3);
- NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 0, 0);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 0, 0);
count = _ptr3[0];
if (arg3 != NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0);
@@ -382,7 +388,7 @@ Java_jogamp_nativewindow_x11_X11Lib_GetVisualIDFromWindow(JNIEnv *env, jclass _u
} else {
r = 0;
}
- NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
return r;
}
@@ -396,7 +402,7 @@ Java_jogamp_nativewindow_x11_X11Lib_DefaultVisualID(JNIEnv *env, jclass _unused,
}
NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 1, 0, 0);
r = (jint) XVisualIDFromVisual( DefaultVisual( (Display*) (intptr_t) display, screen ) );
- NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 0, 0, 0);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 0, 0, 0);
return r;
}
@@ -439,7 +445,7 @@ Java_jogamp_nativewindow_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclass _unused
}
NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 1, 0, 0);
_res = XCloseDisplay((Display *) (intptr_t) display);
- NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 0, 0);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 0, 0);
return _res;
}
@@ -497,7 +503,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
if (visual==NULL)
{
- NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
NativewindowCommon_throwNewRuntimeException(env, "could not query Visual by given VisualID, bail out!");
return 0;
}
@@ -541,7 +547,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
XSelectInput(dpy, window, 0); // no events
- NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
DBG_PRINT( "X11: [CreateWindow] created window %p on display %p\n", window, dpy);
@@ -569,7 +575,7 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyDummyWindow
XUnmapWindow(dpy, w);
XSync(dpy, False);
XDestroyWindow(dpy, w);
- NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
}
/*
@@ -597,7 +603,7 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_x11_X11Lib_GetRelativeLocatio
res = XTranslateCoordinates(dpy, src_win, dest_win, src_x, src_y, &dest_x, &dest_y, &child);
- NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0);
DBG_PRINT( "X11: GetRelativeLocation0: %p %d/%d -> %p %d/%d - ok: %d\n",
(void*)src_win, src_x, src_y, (void*)dest_win, dest_x, dest_y, (int)res);
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java
index 1e9a0e9eb..391bccf3d 100644
--- a/src/newt/classes/com/jogamp/newt/Display.java
+++ b/src/newt/classes/com/jogamp/newt/Display.java
@@ -113,17 +113,23 @@ public abstract class Display {
*/
public abstract int removeReference();
+ /**
+ * Return the {@link AbstractGraphicsDevice} used for depending resources lifecycle,
+ * i.e. {@link Screen} and {@link Window}, as well as the event dispatching (EDT). */
public abstract AbstractGraphicsDevice getGraphicsDevice();
/**
- * @return the fully qualified Display name,
- * which is a key of {@link #getType()} + {@link #getName()} + {@link #getId()}
+ * Return the handle of the {@link AbstractGraphicsDevice} as returned by {@link #getGraphicsDevice()}.
*/
- public abstract String getFQName();
-
public abstract long getHandle();
/**
+ * @return The fully qualified Display name,
+ * which is a key of {@link #getType()} + {@link #getName()} + {@link #getId()}.
+ */
+ public abstract String getFQName();
+
+ /**
* @return this display internal serial id
*/
public abstract int getId();
@@ -141,6 +147,9 @@ public abstract class Display {
*/
public abstract String getType();
+ /** Return true if this instance is exclusive, i.e. will not be shared. */
+ public abstract boolean isExclusive();
+
/**
* Sets a new {@link EDTUtil} and returns the previous one.
* <p>
@@ -183,11 +192,12 @@ public abstract class Display {
*
* @param type
* @param name
- * @param fromIndex start index, then increasing until found or end of list *
+ * @param fromIndex start index, then increasing until found or end of list
+ * @paran shared if true, only shared instances are found, otherwise also exclusive
* @return
*/
- public static Display getFirstDisplayOf(String type, String name, int fromIndex) {
- return getDisplayOfImpl(type, name, fromIndex, 1);
+ public static Display getFirstDisplayOf(String type, String name, int fromIndex, boolean shared) {
+ return getDisplayOfImpl(type, name, fromIndex, 1, shared);
}
/**
@@ -195,19 +205,22 @@ public abstract class Display {
* @param type
* @param name
* @param fromIndex start index, then decreasing until found or end of list. -1 is interpreted as size - 1.
+ * @paran shared if true, only shared instances are found, otherwise also exclusive
* @return
*/
- public static Display getLastDisplayOf(String type, String name, int fromIndex) {
- return getDisplayOfImpl(type, name, fromIndex, -1);
+ public static Display getLastDisplayOf(String type, String name, int fromIndex, boolean shared) {
+ return getDisplayOfImpl(type, name, fromIndex, -1, shared);
}
- private static Display getDisplayOfImpl(String type, String name, int fromIndex, int incr) {
+ private static Display getDisplayOfImpl(String type, String name, int fromIndex, int incr, boolean shared) {
synchronized(displayList) {
int i = fromIndex >= 0 ? fromIndex : displayList.size() - 1 ;
while( ( incr > 0 ) ? i < displayList.size() : i >= 0 ) {
Display display = (Display) displayList.get(i);
if( display.getType().equals(type) &&
- display.getName().equals(name) ) {
+ display.getName().equals(name) &&
+ ( !shared || shared && !display.isExclusive() )
+ ) {
return display;
}
i+=incr;
diff --git a/src/newt/classes/com/jogamp/newt/NewtFactory.java b/src/newt/classes/com/jogamp/newt/NewtFactory.java
index abae94ab6..1bf47f4aa 100644
--- a/src/newt/classes/com/jogamp/newt/NewtFactory.java
+++ b/src/newt/classes/com/jogamp/newt/NewtFactory.java
@@ -305,7 +305,7 @@ public class NewtFactory {
* Instantiate a Display entity using the native handle.
*/
public static Display createDisplay(String type, long handle, boolean reuse) {
- return DisplayImpl.create(type, null, handle, false);
+ return DisplayImpl.create(type, null, handle, reuse);
}
public static boolean isScreenCompatible(NativeWindow parent, Screen childScreen) {
diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java
index 26f19ad6b..cfbcc988a 100644
--- a/src/newt/classes/com/jogamp/newt/Screen.java
+++ b/src/newt/classes/com/jogamp/newt/Screen.java
@@ -145,7 +145,7 @@ public abstract class Screen {
public abstract Display getDisplay();
/**
- * @return the screen fully qualified Screen name,
+ * @return The screen fully qualified Screen name,
* which is a key of {@link com.jogamp.newt.Display#getFQName()} + {@link #getIndex()}.
*/
public abstract String getFQName();
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index bca7f6e5b..daeb3e886 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -42,6 +42,7 @@ import com.jogamp.newt.event.NEWTEventConsumer;
import jogamp.newt.event.NEWTEventTask;
import com.jogamp.newt.util.EDTUtil;
import java.util.ArrayList;
+
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
@@ -66,7 +67,7 @@ public abstract class DisplayImpl extends Display {
name = display.validateDisplayName(name, handle);
synchronized(displayList) {
if(reuse) {
- Display display0 = Display.getLastDisplayOf(type, name, -1);
+ Display display0 = Display.getLastDisplayOf(type, name, -1, true /* shared only */);
if(null != display0) {
if(DEBUG) {
System.err.println("Display.create() REUSE: "+display0+" "+getThreadName());
@@ -74,9 +75,9 @@ public abstract class DisplayImpl extends Display {
return display0;
}
}
+ display.exclusive = !reuse;
display.name = name;
display.type=type;
- display.destroyWhenUnused=false;
display.refCount=0;
display.id = serialno++;
display.fqname = getFQName(display.type, display.name, display.id);
@@ -94,7 +95,7 @@ public abstract class DisplayImpl extends Display {
throw new RuntimeException(e);
}
}
-
+
@Override
public boolean equals(Object obj) {
if (obj == null) {
@@ -116,10 +117,12 @@ public abstract class DisplayImpl extends Display {
return true;
}
+ @Override
public int hashCode() {
return hashCode;
}
+ @Override
public synchronized final void createNative()
throws NativeWindowException
{
@@ -148,10 +151,6 @@ public abstract class DisplayImpl extends Display {
}
}
- protected boolean shallRunOnEDT() {
- return true;
- }
-
protected EDTUtil createEDTUtil() {
final EDTUtil def;
if(NewtFactory.useEDT()) {
@@ -179,12 +178,7 @@ public abstract class DisplayImpl extends Display {
if(DEBUG) {
System.err.println("Display.setEDTUtil: "+oldEDTUtil+" -> "+newEDTUtil);
}
- if(null != oldEDTUtil) {
- stopEDT( new Runnable() { public void run() {} } );
- // ready for restart ..
- oldEDTUtil.waitUntilStopped();
- oldEDTUtil.reset();
- }
+ removeEDT( new Runnable() { public void run() {} } );
edtUtil = newEDTUtil;
return oldEDTUtil;
}
@@ -194,16 +188,19 @@ public abstract class DisplayImpl extends Display {
return edtUtil;
}
- private void stopEDT(final Runnable task) {
- if( shallRunOnEDT() && null!=edtUtil ) {
+ private void removeEDT(final Runnable task) {
+ if(null!=edtUtil) {
edtUtil.invokeStop(task);
+ // ready for restart ..
+ edtUtil.waitUntilStopped();
+ edtUtil.reset();
} else {
task.run();
}
}
public void runOnEDTIfAvail(boolean wait, final Runnable task) {
- if( shallRunOnEDT() && null!=edtUtil && !edtUtil.isCurrentThreadEDT()) {
+ if( null!=edtUtil && !edtUtil.isCurrentThreadEDT()) {
edtUtil.invoke(wait, task);
} else {
task.run();
@@ -212,18 +209,17 @@ public abstract class DisplayImpl extends Display {
public boolean validateEDT() {
if(0==refCount && null==aDevice && null != edtUtil && edtUtil.isRunning()) {
- stopEDT( new Runnable() {
+ removeEDT( new Runnable() {
public void run() {
// nop
}
} );
- edtUtil.waitUntilStopped();
- edtUtil.reset();
return true;
}
return false;
}
+ @Override
public synchronized final void destroy() {
if(DEBUG) {
dumpDisplayList("Display.destroy("+getFQName()+") BEGIN");
@@ -239,17 +235,13 @@ public abstract class DisplayImpl extends Display {
}
final AbstractGraphicsDevice f_aDevice = aDevice;
final DisplayImpl f_dpy = this;
- stopEDT( new Runnable() {
+ removeEDT( new Runnable() {
public void run() {
if ( null != f_aDevice ) {
f_dpy.closeNativeImpl();
}
}
} );
- if(null!=edtUtil) {
- edtUtil.waitUntilStopped();
- edtUtil.reset();
- }
aDevice = null;
refCount=0;
if(DEBUG) {
@@ -290,21 +282,30 @@ public abstract class DisplayImpl extends Display {
protected abstract void createNativeImpl();
protected abstract void closeNativeImpl();
+ @Override
public final int getId() {
return id;
}
+ @Override
public final String getType() {
return type;
}
+ @Override
public final String getName() {
return name;
}
+ @Override
public final String getFQName() {
return fqname;
}
+
+ @Override
+ public final boolean isExclusive() {
+ return exclusive;
+ }
public static final String nilString = "nil" ;
@@ -324,9 +325,10 @@ public abstract class DisplayImpl extends Display {
sb.append(name);
sb.append("-");
sb.append(id);
- return sb.toString().intern();
+ return sb.toString();
}
+ @Override
public final long getHandle() {
if(null!=aDevice) {
return aDevice.getHandle();
@@ -334,14 +336,17 @@ public abstract class DisplayImpl extends Display {
return 0;
}
+ @Override
public final AbstractGraphicsDevice getGraphicsDevice() {
return aDevice;
}
+ @Override
public synchronized final boolean isNativeValid() {
return null != aDevice;
}
+ @Override
public boolean isEDTRunning() {
if(null!=edtUtil) {
return edtUtil.isRunning();
@@ -351,7 +356,7 @@ public abstract class DisplayImpl extends Display {
@Override
public String toString() {
- return "NEWT-Display["+getFQName()+", refCount "+refCount+", hasEDT "+(null!=edtUtil)+", edtRunning "+isEDTRunning()+", "+aDevice+"]";
+ return "NEWT-Display["+getFQName()+", excl "+exclusive+", refCount "+refCount+", hasEDT "+(null!=edtUtil)+", edtRunning "+isEDTRunning()+", "+aDevice+"]";
}
protected abstract void dispatchMessagesNative();
@@ -403,6 +408,7 @@ public abstract class DisplayImpl extends Display {
eventTask.notifyCaller();
}
+ @Override
public void dispatchMessages() {
// System.err.println("Display.dispatchMessages() 0 "+this+" "+getThreadName());
if(0==refCount || // no screens
@@ -475,20 +481,23 @@ public abstract class DisplayImpl extends Display {
public interface DisplayRunnable<T> {
T run(long dpy);
}
- public final <T> T runWithLockedDisplayHandle(DisplayRunnable<T> action) {
- final AbstractGraphicsDevice aDevice = getGraphicsDevice();
- if(null == aDevice) {
- throw new RuntimeException("null device - not initialized: "+this);
- }
+ public static final <T> T runWithLockedDevice(AbstractGraphicsDevice device, DisplayRunnable<T> action) {
T res;
- aDevice.lock();
+ device.lock();
try {
- res = action.run(aDevice.getHandle());
+ res = action.run(device.getHandle());
} finally {
- aDevice.unlock();
+ device.unlock();
}
return res;
}
+ public final <T> T runWithLockedDisplayDevice(DisplayRunnable<T> action) {
+ final AbstractGraphicsDevice device = getGraphicsDevice();
+ if(null == device) {
+ throw new RuntimeException("null device - not initialized: "+this);
+ }
+ return runWithLockedDevice(device, action);
+ }
protected EDTUtil edtUtil = null;
protected int id;
@@ -497,7 +506,7 @@ public abstract class DisplayImpl extends Display {
protected String fqname;
protected int hashCode;
protected int refCount; // number of Display references by Screen
- protected boolean destroyWhenUnused;
+ protected boolean exclusive; // do not share this display, uses NullLock!
protected AbstractGraphicsDevice aDevice;
}
diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java
index e2c0f746f..1cc53e80e 100644
--- a/src/newt/classes/jogamp/newt/ScreenImpl.java
+++ b/src/newt/classes/jogamp/newt/ScreenImpl.java
@@ -42,7 +42,6 @@ import java.util.List;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.util.Dimension;
import javax.media.nativewindow.util.DimensionImmutable;
import javax.media.nativewindow.util.Point;
@@ -130,7 +129,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
}
}
screen.screen_idx = idx;
- screen.fqname = (display.getFQName()+idx).intern();
+ screen.fqname = display.getFQName()+"-s"+idx;
screen.hashCode = screen.fqname.hashCode();
screenList.add(screen);
if(DEBUG) {
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index c1ac87d38..79770189b 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -85,7 +85,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private volatile long windowHandle = 0; // lifecycle critical
private volatile boolean visible = false; // lifecycle critical
private RecursiveLock windowLock = LockFactory.createRecursiveLock(); // Window instance wide lock
- private RecursiveLock surfaceLock = LockFactory.createRecursiveLock(); // Surface only lock
+ private int surfaceLockCount = 0; // surface lock recursion count
private ScreenImpl screen; // never null after create - may change reference though (reparent)
private boolean screenReferenceAdded = false;
@@ -553,10 +553,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
@Override
public final int lockSurface() throws NativeWindowException, RuntimeException {
final RecursiveLock _wlock = windowLock;
- final RecursiveLock _slock = surfaceLock;
_wlock.lock();
- _slock.lock();
- int res = _slock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
+ surfaceLockCount++;
+ int res = ( 1 == surfaceLockCount ) ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
if ( LOCK_SURFACE_NOT_READY == res ) {
try {
@@ -573,7 +572,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
} finally {
if (LOCK_SURFACE_NOT_READY >= res) {
- _slock.unlock();
_wlock.unlock();
}
}
@@ -583,12 +581,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
@Override
public final void unlockSurface() {
- final RecursiveLock _slock = surfaceLock;
final RecursiveLock _wlock = windowLock;
- _slock.validateLocked();
_wlock.validateLocked();
- if (_slock.getHoldCount() == 1) {
+ if ( 1 == surfaceLockCount ) {
final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
try {
unlockSurfaceImpl();
@@ -596,42 +592,48 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
adevice.unlock();
}
}
- _slock.unlock();
+ surfaceLockCount--;
_wlock.unlock();
}
@Override
public final boolean isSurfaceLockedByOtherThread() {
- return surfaceLock.isLockedByOtherThread();
+ return windowLock.isLockedByOtherThread();
}
@Override
public final Thread getSurfaceLockOwner() {
- return surfaceLock.getOwner();
+ return windowLock.getOwner();
}
public final RecursiveLock getLock() {
return windowLock;
}
+ @Override
public long getSurfaceHandle() {
return windowHandle; // default: return window handle
}
+ @Override
public boolean surfaceSwap() {
return false;
}
+ @Override
public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
return config.getNativeGraphicsConfiguration();
}
- public final long getDisplayHandle() {
- return getScreen().getDisplay().getHandle();
+ @Override
+ public long getDisplayHandle() {
+ // Actually: return getGraphicsConfiguration().getScreen().getDevice().getHandle();
+ return screen.getDisplay().getHandle(); // shortcut
}
+ @Override
public final int getScreenIndex() {
- return getScreen().getIndex();
+ return screen.getIndex();
}
//----------------------------------------------------------------------
@@ -1554,8 +1556,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
for (int i = 0; i < keyListeners.size(); i++ ) {
sb.append(keyListeners.get(i)+", ");
}
- sb.append("], surfaceLock "+surfaceLock);
- sb.append(", windowLock "+windowLock+"]");
+ sb.append("], windowLock "+windowLock+"]");
return sb.toString();
}
diff --git a/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
index 70e9ba570..ead567d82 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
@@ -66,7 +66,9 @@ public class DisplayDriver extends DisplayImpl {
return def;
}
- protected void closeNativeImpl() { }
+ protected void closeNativeImpl() {
+ aDevice.close();
+ }
protected void dispatchMessagesNative() { /* nop */ }
}
diff --git a/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java
index 65ca63eec..cc55c336e 100644
--- a/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java
@@ -39,6 +39,7 @@ import javax.media.nativewindow.NativeWindowException;
import jogamp.newt.NEWTJNILibLoader;
import jogamp.opengl.egl.EGL;
+import jogamp.opengl.egl.EGLDisplayUtil;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
@@ -72,6 +73,7 @@ public class DisplayDriver extends jogamp.newt.DisplayImpl {
if (aDevice.getHandle() != EGL.EGL_NO_DISPLAY) {
DestroyDisplay(aDevice.getHandle());
}
+ aDevice.close();
}
protected void dispatchMessagesNative() {
diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java
index 97c384d33..e370038d9 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java
@@ -84,6 +84,7 @@ public class DisplayDriver extends jogamp.newt.DisplayImpl {
}
}
}
+ aDevice.close();
}
protected void dispatchMessagesNative() {
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
index 1a3f14859..b49c6b6e0 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
@@ -72,7 +72,9 @@ public class DisplayDriver extends DisplayImpl {
aDevice = new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
}
- protected void closeNativeImpl() { }
+ protected void closeNativeImpl() {
+ aDevice.close();
+ }
public static void runNSApplication() {
runNSApplication0();
diff --git a/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
index 579ec5be8..615f9e63b 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
@@ -73,6 +73,7 @@ public class DisplayDriver extends DisplayImpl {
protected void closeNativeImpl() {
sharedClassFactory.releaseSharedClass();
+ aDevice.close();
}
protected void dispatchMessagesNative() {
diff --git a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
index 714324d63..bff050030 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
@@ -36,7 +36,6 @@ package jogamp.newt.driver.x11;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.NativeWindowFactory;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
@@ -74,71 +73,48 @@ public class DisplayDriver extends DisplayImpl {
* {@inheritDoc}
*
* We use a private non-shared X11 Display instance for EDT window operations and one for exposed animation, eg. OpenGL.
- * <p>
- * In case {@link X11Util#HAS_XLOCKDISPLAY_BUG} and {@link X11Util#XINITTHREADS_ALWAYS_ENABLED},
- * we use null locking. Even though this seems not to be rational, it gives most stable results on all platforms.
- * </p>
- * <p>
- * Otherwise we use basic locking via the constructor {@link X11GraphicsDevice#X11GraphicsDevice(long, int, boolean)},
- * since it is possible to share this device via {@link com.jogamp.newt.NewtFactory#createDisplay(String, boolean)}.
- * </p>
*/
- @SuppressWarnings("unused")
protected void createNativeImpl() {
+ X11Util.setX11ErrorHandler(true, DEBUG ? false : true); // make sure X11 error handler is set
long handle = X11Util.openDisplay(name);
if( 0 == handle ) {
throw new RuntimeException("Error creating display(Win): "+name);
}
- if(USE_SEPARATE_DISPLAY_FOR_EDT) {
- edtDisplayHandle = X11Util.openDisplay(name);
- if( 0 == edtDisplayHandle ) {
- X11Util.closeDisplay(handle);
- throw new RuntimeException("Error creating display(EDT): "+name);
- }
- } else {
- edtDisplayHandle = handle;
- }
+ aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, true);
try {
- CompleteDisplay0(edtDisplayHandle);
+ CompleteDisplay0(aDevice.getHandle());
} catch(RuntimeException e) {
closeNativeImpl();
throw e;
- }
-
- // see API doc above!
- if(X11Util.XINITTHREADS_ALWAYS_ENABLED && X11Util.HAS_XLOCKDISPLAY_BUG) {
- aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.getNullToolkitLock(), false);
- } else {
- aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, false);
- }
+ }
}
protected void closeNativeImpl() {
- DisplayRelease0(edtDisplayHandle, javaObjectAtom, windowDeleteAtom);
+ DisplayRelease0(aDevice.getHandle(), javaObjectAtom, windowDeleteAtom);
javaObjectAtom = 0;
windowDeleteAtom = 0;
- // closing using ATI driver bug 'same order'
- final long handle = getHandle();
- X11Util.closeDisplay(handle);
- if(handle != edtDisplayHandle) {
- X11Util.closeDisplay(edtDisplayHandle);
- }
- edtDisplayHandle = 0;
+ aDevice.close(); // closes X11 display
}
protected void dispatchMessagesNative() {
- if(0 != edtDisplayHandle) {
- DispatchMessages0(edtDisplayHandle, javaObjectAtom, windowDeleteAtom);
+ aDevice.lock();
+ try {
+ final long handle = aDevice.getHandle();
+ if(0 != handle) {
+ DispatchMessages0(handle, javaObjectAtom, windowDeleteAtom);
+ }
+ } finally {
+ aDevice.unlock();
}
}
- protected long getEDTHandle() { return edtDisplayHandle; }
protected long getJavaObjectAtom() { return javaObjectAtom; }
protected long getWindowDeleteAtom() { return windowDeleteAtom; }
//----------------------------------------------------------------------
// Internals only
//
+
private static native boolean initIDs0(boolean debug);
private native void CompleteDisplay0(long handle);
@@ -151,17 +127,6 @@ public class DisplayDriver extends DisplayImpl {
private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom);
- /**
- * 2011/06/14 libX11 1.4.2 and libxcb 1.7 bug 20708 - Multithreading Issues w/ OpenGL, ..
- * https://bugs.freedesktop.org/show_bug.cgi?id=20708
- * https://jogamp.org/bugzilla/show_bug.cgi?id=502
- * Affects: Ubuntu 11.04, OpenSuSE 11, ..
- * Workaround: Using a separate X11 Display connection for event dispatching (EDT)
- */
- private final boolean USE_SEPARATE_DISPLAY_FOR_EDT = true;
-
- private long edtDisplayHandle;
-
/** X11 Window delete atom marker used on EDT */
private long windowDeleteAtom;
diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
index 10f6b84da..b09d98e06 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
@@ -59,7 +59,7 @@ public class ScreenDriver extends ScreenImpl {
protected void createNativeImpl() {
// validate screen index
- Long handle = display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Long>() {
+ Long handle = runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Long>() {
public Long run(long dpy) {
return new Long(GetScreen0(dpy, screen_idx));
} } );
@@ -81,7 +81,7 @@ public class ScreenDriver extends ScreenImpl {
private int nmode_number;
protected int[] getScreenModeFirstImpl() {
- return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<int[]>() {
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<int[]>() {
public int[] run(long dpy) {
// initialize iterators and static data
nrotations = getAvailableScreenModeRotations0(dpy, screen_idx);
@@ -110,7 +110,7 @@ public class ScreenDriver extends ScreenImpl {
protected int[] getScreenModeNextImpl() {
// assemble: w x h x bpp x f x r
- return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<int[]>() {
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<int[]>() {
public int[] run(long dpy) {
/**
System.err.println("******** mode: "+nmode_number);
@@ -176,7 +176,7 @@ public class ScreenDriver extends ScreenImpl {
}
protected ScreenMode getCurrentScreenModeImpl() {
- return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<ScreenMode>() {
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<ScreenMode>() {
public ScreenMode run(long dpy) {
long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx);
if(0 == screenConfigHandle) {
@@ -237,7 +237,7 @@ public class ScreenDriver extends ScreenImpl {
throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode);
}
final long t0 = System.currentTimeMillis();
- boolean done = runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
+ boolean done = runWithTempDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
public Boolean run(long dpy) {
boolean done = false;
long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx);
@@ -276,23 +276,21 @@ public class ScreenDriver extends ScreenImpl {
return done;
}
- private class XineramaEnabledQuery implements DisplayImpl.DisplayRunnable<Boolean> {
+ private DisplayImpl.DisplayRunnable<Boolean> xineramaEnabledQueryWithTemp = new DisplayImpl.DisplayRunnable<Boolean>() {
public Boolean run(long dpy) {
return new Boolean(X11Util.XineramaIsEnabled(dpy));
- }
- }
- private XineramaEnabledQuery xineramaEnabledQuery = new XineramaEnabledQuery();
+ } };
protected int validateScreenIndex(final int idx) {
if(getDisplay().isNativeValid()) {
- return runWithLockedDisplayHandle( xineramaEnabledQuery ).booleanValue() ? 0 : idx;
+ return X11Util.XineramaIsEnabled((X11GraphicsDevice)getDisplay().getGraphicsDevice()) ? 0 : idx;
} else {
- return runWithTempDisplayHandle( xineramaEnabledQuery ).booleanValue() ? 0 : idx;
+ return runWithTempDisplayHandle( xineramaEnabledQueryWithTemp ).booleanValue() ? 0 : idx;
}
}
protected void getVirtualScreenOriginAndSize(final Point virtualOrigin, final Dimension virtualSize) {
- display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Object>() {
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
public Object run(long dpy) {
virtualOrigin.setX(0);
virtualOrigin.setY(0);
@@ -305,10 +303,8 @@ public class ScreenDriver extends ScreenImpl {
//----------------------------------------------------------------------
// Internals only
//
- private final <T> T runWithLockedDisplayHandle(DisplayRunnable<T> action) {
- return display.runWithLockedDisplayHandle(action);
- // return runWithTempDisplayHandle(action);
- // return runWithoutLock(action);
+ private final <T> T runWithLockedDisplayDevice(DisplayRunnable<T> action) {
+ return display.runWithLockedDisplayDevice(action);
}
private final <T> T runWithTempDisplayHandle(DisplayRunnable<T> action) {
@@ -324,9 +320,6 @@ public class ScreenDriver extends ScreenImpl {
}
return res;
}
- private final <T> T runWithoutLock(DisplayRunnable<T> action) {
- return action.run(display.getHandle());
- }
private static native long GetScreen0(long dpy, int scrn_idx);
diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
index 97d1ae3db..aea86a420 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
@@ -35,6 +35,7 @@
package jogamp.newt.driver.x11;
import jogamp.nativewindow.x11.X11Lib;
+import jogamp.nativewindow.x11.X11Util;
import jogamp.newt.DisplayImpl;
import jogamp.newt.DisplayImpl.DisplayRunnable;
import jogamp.newt.WindowImpl;
@@ -44,6 +45,8 @@ import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
+import com.jogamp.nativewindow.x11.X11GraphicsScreen;
import com.jogamp.newt.event.MouseEvent;
public class WindowDriver extends WindowImpl {
@@ -63,9 +66,19 @@ public class WindowDriver extends WindowImpl {
protected void createNativeImpl() {
final ScreenDriver screen = (ScreenDriver) getScreen();
final DisplayDriver display = (DisplayDriver) screen.getDisplay();
+ final AbstractGraphicsDevice edtDevice = display.getGraphicsDevice();
+
+ // Decoupled X11 Device/Screen allowing X11 display lock-free off-thread rendering
+ final long renderDeviceHandle = X11Util.openDisplay(edtDevice.getConnection());
+ if( 0 == renderDeviceHandle ) {
+ throw new RuntimeException("Error creating display(EDT): "+edtDevice.getConnection());
+ }
+ renderDevice = new X11GraphicsDevice(renderDeviceHandle, AbstractGraphicsDevice.DEFAULT_UNIT, true);
+ AbstractGraphicsScreen renderScreen = new X11GraphicsScreen((X11GraphicsDevice) renderDevice, screen.getIndex());
+
final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice(), capsRequested);
final AbstractGraphicsConfiguration cfg = factory.chooseGraphicsConfiguration(
- capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED);
+ capsRequested, capsRequested, capabilitiesChooser, renderScreen, VisualIDHolder.VID_UNDEFINED);
if(DEBUG_IMPLEMENTATION) {
System.err.println("X11Window.createNativeImpl() factory: "+factory+", chosen config: "+cfg);
}
@@ -78,11 +91,16 @@ public class WindowDriver extends WindowImpl {
}
setGraphicsConfiguration(cfg);
final int flags = getReconfigureFlags(0, true) &
- ( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ;
- setWindowHandle(CreateWindow0(getParentWindowHandle(),
- display.getEDTHandle(), screen.getIndex(), visualID,
- display.getJavaObjectAtom(), display.getWindowDeleteAtom(),
- getX(), getY(), getWidth(), getHeight(), autoPosition(), flags));
+ ( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ;
+ edtDevice.lock();
+ try {
+ setWindowHandle(CreateWindow0(getParentWindowHandle(),
+ edtDevice.getHandle(), screen.getIndex(), visualID,
+ display.getJavaObjectAtom(), display.getWindowDeleteAtom(),
+ getX(), getY(), getWidth(), getHeight(), autoPosition(), flags));
+ } finally {
+ edtDevice.unlock();
+ }
windowHandleClose = getWindowHandle();
if (0 == windowHandleClose) {
throw new NativeWindowException("Error creating window");
@@ -92,8 +110,10 @@ public class WindowDriver extends WindowImpl {
protected void closeNativeImpl() {
if(0!=windowHandleClose && null!=getScreen() ) {
DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
+ final AbstractGraphicsDevice edtDevice = display.getGraphicsDevice();
+ edtDevice.lock();
try {
- CloseWindow0(display.getEDTHandle(), windowHandleClose,
+ CloseWindow0(edtDevice.getHandle(), windowHandleClose,
display.getJavaObjectAtom(), display.getWindowDeleteAtom());
} catch (Throwable t) {
if(DEBUG_IMPLEMENTATION) {
@@ -101,28 +121,47 @@ public class WindowDriver extends WindowImpl {
e.printStackTrace();
}
} finally {
+ edtDevice.unlock();
windowHandleClose = 0;
}
}
+ if(null != renderDevice) {
+ renderDevice.close(); // closes X11 display
+ renderDevice = null;
+ }
}
- protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
+ @Override
+ public long getDisplayHandle() {
+ // Actually: return getGraphicsConfiguration().getScreen().getDevice().getHandle();
+ return renderDevice.getHandle(); // shortcut
+ }
+
+ protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, final int flags) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("X11Window reconfig: "+x+"/"+y+" "+width+"x"+height+", "+
getReconfigureFlagsAsString(null, flags));
}
+ final int _x, _y;
if(0 == ( FLAG_IS_UNDECORATED & flags)) {
final InsetsImmutable i = getInsets();
// client position -> top-level window position
- x -= i.getLeftWidth() ;
- y -= i.getTopHeight() ;
+ _x = x - i.getLeftWidth() ;
+ _y = y - i.getTopHeight() ;
+ } else {
+ _x = x;
+ _y = y;
}
final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
- reconfigureWindow0( getDisplayEDTHandle(), getScreenIndex(),
- getParentWindowHandle(), getWindowHandle(), display.getWindowDeleteAtom(),
- x, y, width, height, flags);
-
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
+ public Object run(long dpy) {
+ reconfigureWindow0( dpy, getScreenIndex(),
+ getParentWindowHandle(), getWindowHandle(), display.getWindowDeleteAtom(),
+ _x, _y, width, height, flags);
+ return null;
+ }
+ });
return true;
}
@@ -133,13 +172,18 @@ public class WindowDriver extends WindowImpl {
}
}
- protected void requestFocusImpl(boolean force) {
- requestFocus0(getDisplayEDTHandle(), getWindowHandle(), force);
+ protected void requestFocusImpl(final boolean force) {
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
+ public Object run(long dpy) {
+ requestFocus0(dpy, getWindowHandle(), force);
+ return null;
+ }
+ });
}
@Override
protected void setTitleImpl(final String title) {
- runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Object>() {
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
public Object run(long dpy) {
setTitle0(dpy, getWindowHandle(), title);
return null;
@@ -149,35 +193,38 @@ public class WindowDriver extends WindowImpl {
@Override
protected boolean setPointerVisibleImpl(final boolean pointerVisible) {
- return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Boolean>() {
public Boolean run(long dpy) {
- return Boolean.valueOf(setPointerVisible0(getDisplayEDTHandle(), getWindowHandle(), pointerVisible));
+ return Boolean.valueOf(setPointerVisible0(dpy, getWindowHandle(), pointerVisible));
}
}).booleanValue();
}
@Override
protected boolean confinePointerImpl(final boolean confine) {
- return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Boolean>() {
public Boolean run(long dpy) {
- return Boolean.valueOf(confinePointer0(getDisplayEDTHandle(), getWindowHandle(), confine));
+ return Boolean.valueOf(confinePointer0(dpy, getWindowHandle(), confine));
}
}).booleanValue();
}
@Override
protected void warpPointerImpl(final int x, final int y) {
- runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Object>() {
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
public Object run(long dpy) {
- warpPointer0(getDisplayEDTHandle(), getWindowHandle(), x, y);
+ warpPointer0(dpy, getWindowHandle(), x, y);
return null;
}
});
}
protected Point getLocationOnScreenImpl(final int x, final int y) {
- // X11Util.GetRelativeLocation: locks display already !
- return X11Lib.GetRelativeLocation( getScreen().getDisplay().getHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Point>() {
+ public Point run(long dpy) {
+ return X11Lib.GetRelativeLocation(dpy, getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+ }
+ } );
}
protected void updateInsetsImpl(Insets insets) {
@@ -229,16 +276,11 @@ public class WindowDriver extends WindowImpl {
//----------------------------------------------------------------------
// Internals only
//
-
private static final String getCurrentThreadName() { return Thread.currentThread().getName(); } // Callback for JNI
private static final void dumpStack() { Thread.dumpStack(); } // Callback for JNI
- private final long getDisplayEDTHandle() {
- return ((DisplayDriver) getScreen().getDisplay()).getEDTHandle();
- }
- private final <T> T runWithLockedDisplayHandle(DisplayRunnable<T> action) {
- return ((DisplayImpl) getScreen().getDisplay()).runWithLockedDisplayHandle(action);
- // return runWithTempDisplayHandle(action);
+ private final <T> T runWithLockedDisplayDevice(DisplayRunnable<T> action) {
+ return ((DisplayDriver) getScreen().getDisplay()).runWithLockedDisplayDevice(action);
}
protected static native boolean initIDs0();
@@ -258,4 +300,5 @@ public class WindowDriver extends WindowImpl {
private static native void warpPointer0(long display, long windowHandle, int x, int y);
private long windowHandleClose;
+ private AbstractGraphicsDevice renderDevice;
}
diff --git a/src/newt/native/X11Common.h b/src/newt/native/X11Common.h
index 128b6b6f1..4d1a7b59e 100644
--- a/src/newt/native/X11Common.h
+++ b/src/newt/native/X11Common.h
@@ -70,7 +70,6 @@ extern jclass X11NewtWindowClazz;
extern jmethodID insetsChangedID;
extern jmethodID visibleChangedID;
-void NewtDisplay_x11ErrorHandlerEnable(JNIEnv * env, Display *dpy, int onoff, int quiet, int sync);
jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning);
Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return);
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c
index 84b3a7630..56c11fab4 100644
--- a/src/newt/native/X11Display.c
+++ b/src/newt/native/X11Display.c
@@ -52,90 +52,6 @@ static jmethodID enqueueKeyEventID = NULL;
static jmethodID sendKeyEventID = NULL;
static jmethodID requestFocusID = NULL;
-static JavaVM *jvmHandle = NULL;
-static int jvmVersion = 0;
-
-static void setupJVMVars(JNIEnv * env) {
- if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
- jvmHandle = NULL;
- }
- jvmVersion = (*env)->GetVersion(env);
-}
-
-static XErrorHandler origErrorHandler = NULL ;
-static int errorHandlerQuiet = 0 ;
-static int errorHandlerDebug = 0 ;
-static int errorHandlerThrowException = 0;
-
-static int x11ErrorHandler(Display *dpy, XErrorEvent *e)
-{
- if(!errorHandlerQuiet) {
- const char * errnoStr = strerror(errno);
- char threadName[80];
- char errCodeStr[80];
- char reqCodeStr[80];
-
- int shallBeDetached = 0;
- JNIEnv *jniEnv = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
-
- (void) NewtCommon_GetStaticStringMethod(jniEnv, X11NewtWindowClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a");
- snprintf(errCodeStr, sizeof(errCodeStr), "%d", e->request_code);
- XGetErrorDatabaseText(dpy, "XRequest", errCodeStr, "Unknown", reqCodeStr, sizeof(reqCodeStr));
- XGetErrorText(dpy, e->error_code, errCodeStr, sizeof(errCodeStr));
-
- fprintf(stderr, "Info: Newt X11 Error (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
- threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
- (int)e->request_code, (int)e->minor_code, reqCodeStr);
-
- if( errorHandlerDebug ) {
- (*jniEnv)->CallStaticVoidMethod(jniEnv, X11NewtWindowClazz, dumpStackID);
- }
-
- if(errorHandlerThrowException) {
- if(NULL != jniEnv) {
- NewtCommon_throwNewRuntimeException(jniEnv, "Newt X11 Error (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
- threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
- (int)e->request_code, (int)e->minor_code, reqCodeStr);
- } else {
- fprintf(stderr, "Nativewindow X11 Error: null JNIEnv");
- #if 0
- if(NULL!=origErrorHandler) {
- origErrorHandler(dpy, e);
- }
- #endif
- }
- }
- fflush(stderr);
-
- if (NULL != jniEnv && shallBeDetached) {
- (*jvmHandle)->DetachCurrentThread(jvmHandle);
- }
- }
-
- return 0;
-}
-
-void NewtDisplay_x11ErrorHandlerEnable(JNIEnv * env, Display *dpy, int onoff, int quiet, int sync) {
- errorHandlerQuiet = quiet;
- if(onoff) {
- if(NULL==origErrorHandler) {
- setupJVMVars(env);
- origErrorHandler = XSetErrorHandler(x11ErrorHandler);
- if(sync && NULL!=dpy) {
- XSync(dpy, False);
- }
- }
- } else {
- if(NULL!=origErrorHandler) {
- if(sync && NULL!=dpy) {
- XSync(dpy, False);
- }
- XSetErrorHandler(origErrorHandler);
- origErrorHandler = NULL;
- }
- }
-}
-
/**
* Keycode
*/
@@ -273,9 +189,6 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
{
jclass c;
- if(debug) {
- errorHandlerDebug = 1 ;
- }
NewtCommon_init(env);
if(NULL==X11NewtWindowClazz) {
@@ -439,8 +352,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
// DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type);
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 1, 0, 0);
-
jwindow = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom,
#ifdef VERBOSE_ON
True
@@ -449,8 +360,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
#endif
);
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
-
if(NULL==jwindow) {
fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n",
(void*)dpy, evt.type, (void*)evt.xany.window);
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 59862f463..2e16e7cae 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -683,16 +683,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0
DBG_PRINT( "X11: CloseWindow START dpy %p, win %p\n", (void*)dpy, (void*)w);
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 1, 0, 0);
-
jwindow = getJavaWindowProperty(env, dpy, w, javaObjectAtom, True);
if(NULL==jwindow) {
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
NewtCommon_throwNewRuntimeException(env, "could not fetch Java Window object, bail out!");
return;
}
if ( JNI_FALSE == (*env)->IsSameObject(env, jwindow, obj) ) {
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
NewtCommon_throwNewRuntimeException(env, "Internal Error .. Window global ref not the same!");
return;
}
@@ -700,7 +696,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0
XSync(dpy, False);
XSelectInput(dpy, w, 0);
XUnmapWindow(dpy, w);
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
// Drain all events related to this window ..
Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom);
@@ -761,8 +756,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
fsEWMHFlags |= _NET_WM_ABOVE; // toggle above
}
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 1, 0, 0);
-
DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d, parent %p/%p, win %p, %d/%d %dx%d, parentChange %d, hasParent %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d, alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d, tempInvisible %d, fsEWMHFlags %d\n",
(void*)dpy, screen_index, (void*) jparent, (void*)parent, (void*)w,
x, y, width, height,
@@ -779,7 +772,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
( TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) ) {
Bool enable = TST_FLAG_CHANGE_FULLSCREEN(flags) ? TST_FLAG_IS_FULLSCREEN(flags) : TST_FLAG_IS_ALWAYSONTOP(flags) ;
if( NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, enable) ) {
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
#ifdef FS_GRAB_KEYBOARD
if(TST_FLAG_CHANGE_FULLSCREEN(flags)) {
if(TST_FLAG_IS_FULLSCREEN(flags)) {
@@ -863,8 +855,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
#endif
}
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
-
DBG_PRINT( "X11: reconfigureWindow0 X\n");
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrentNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java
index 7127b0a5f..11d1331ed 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrentNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java
@@ -28,8 +28,6 @@
package com.jogamp.opengl.test.junit.jogl.acore;
-import java.io.IOException;
-
import javax.media.nativewindow.Capabilities;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.opengl.GLCapabilities;
@@ -37,17 +35,24 @@ import javax.media.opengl.GLProfile;
import org.junit.Assert;
import org.junit.BeforeClass;
-import org.junit.Test;
-import com.jogamp.common.os.Platform;
+import com.jogamp.newt.Display;
import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Screen;
import com.jogamp.newt.Window;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.util.Animator;
-public class TestInitConcurrentNEWT extends UITestCase {
+/**
+ * Concurrent and lock-free initialization and rendering using exclusive NEWT Display EDT instances, or
+ * concurrent locked initialization and lock-free rendering using a shared NEWT Display EDT instances.
+ * <p>
+ * Rendering is always lock-free and independent of the EDT.
+ * </p>
+ */
+public class InitConcurrentBaseNEWT extends UITestCase {
static final int demoSize = 128;
@@ -73,20 +78,24 @@ public class TestInitConcurrentNEWT extends UITestCase {
}
public class JOGLTask implements Runnable {
- private int id;
- private Object postSync;
+ private final int id;
+ private final Object postSync;
+ private final boolean reuse;
private boolean done = false;
- public JOGLTask(Object postSync, int id) {
+ public JOGLTask(Object postSync, int id, boolean reuse) {
this.postSync = postSync;
this.id = id;
+ this.reuse = reuse;
}
public void run() {
int x = ( id % num_x ) * ( demoSize + insets.getTotalHeight() );
int y = ( (id / num_x) % num_y ) * ( demoSize + insets.getTotalHeight() );
- System.err.println("JOGLTask "+id+": START: "+x+"/"+y+" - "+Thread.currentThread().getName());
- GLWindow glWindow = GLWindow.create(new GLCapabilities(GLProfile.getDefault()));
+ System.err.println("JOGLTask "+id+": START: "+x+"/"+y+", reuse "+reuse+" - "+Thread.currentThread().getName());
+ final Display display = NewtFactory.createDisplay(null, reuse);
+ final Screen screen = NewtFactory.createScreen(display, 0);
+ final GLWindow glWindow = GLWindow.create(screen, new GLCapabilities(GLProfile.getDefault()));
Assert.assertNotNull(glWindow);
glWindow.setTitle("Task "+id);
glWindow.setPosition(x + insets.getLeftWidth(), y + insets.getTopHeight() );
@@ -98,6 +107,9 @@ public class TestInitConcurrentNEWT extends UITestCase {
glWindow.setSize(demoSize, demoSize);
glWindow.setVisible(true);
animator.setUpdateFPSFrames(60, null);
+
+ System.err.println("JOGLTask "+id+": INITIALIZED: "+", "+display+" - "+Thread.currentThread().getName());
+
animator.start();
Assert.assertEquals(true, animator.isAnimating());
Assert.assertEquals(true, glWindow.isVisible());
@@ -169,67 +181,39 @@ public class TestInitConcurrentNEWT extends UITestCase {
return sb.toString();
}
- protected void runJOGLTasks(int num) throws InterruptedException {
+ protected void runJOGLTasks(int num, boolean reuse) throws InterruptedException {
final String currentThreadName = Thread.currentThread().getName();
- final Object sync = new Object();
+ final Object syncDone = new Object();
final JOGLTask[] tasks = new JOGLTask[num];
final Thread[] threads = new Thread[num];
int i;
for(i=0; i<num; i++) {
- tasks[i] = new JOGLTask(sync, i);
+ tasks[i] = new JOGLTask(syncDone, i, reuse);
threads[i] = new Thread(tasks[i], currentThreadName+"-jt"+i);
}
+ final long t0 = System.currentTimeMillis();
+
for(i=0; i<num; i++) {
threads[i].start();
}
- synchronized (sync) {
+ synchronized (syncDone) {
while(!done(tasks)) {
try {
- sync.wait();
+ syncDone.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
+ final long t1 = System.currentTimeMillis();
+ System.err.println("total: "+(t1-t0)/1000.0+"s");
+
Assert.assertTrue("Tasks are incomplete. Complete: "+doneDump(tasks), done(tasks));
i=0;
while(i<30 && !isDead(threads)) {
Thread.sleep(100);
i++;
}
- Assert.assertTrue("Threads are still alive after 3s. Alive: "+isAliveDump(threads), isDead(threads));
- }
-
- @Test
- public void test01OneThread() throws InterruptedException {
- runJOGLTasks(1);
- }
-
- @Test
- public void test02TwoThreads() throws InterruptedException {
- runJOGLTasks(2);
- }
-
- @Test
- public void test16SixteenThreads() throws InterruptedException {
- if( Platform.getCPUFamily() == Platform.CPUFamily.ARM ) {
- runJOGLTasks(8);
- } else {
- runJOGLTasks(16);
- }
- }
-
- public static void main(String args[]) throws IOException {
- for(int i=0; i<args.length; i++) {
- if(args[i].equals("-time")) {
- i++;
- try {
- duration = Integer.parseInt(args[i]);
- } catch (Exception ex) { ex.printStackTrace(); }
- }
- }
- String tstname = TestInitConcurrentNEWT.class.getName();
- org.junit.runner.JUnitCore.main(tstname);
- }
-
+ Assert.assertTrue("Threads are still alive after 3s. Alive: "+isAliveDump(threads), isDead(threads));
+ }
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent01NEWT.java
index 743d371b7..e5ed8a79f 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent01NEWT.java
@@ -3,14 +3,14 @@
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
- *
+ *
* 2. Redistributions 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.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
@@ -20,57 +20,59 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
+ *
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
-package jogamp.nativewindow.jawt.x11;
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.io.IOException;
-import jogamp.nativewindow.jawt.*;
-import jogamp.nativewindow.x11.X11Lib;
-import jogamp.nativewindow.x11.X11Util;
-import javax.media.nativewindow.ToolkitLock;
+import org.junit.Test;
-import com.jogamp.common.util.locks.LockFactory;
-import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.common.os.Platform;
/**
- * Implementing a recursive {@link javax.media.nativewindow.ToolkitLock}
- * utilizing JAWT's AWT lock via {@link JAWTUtil#lockToolkit()} and {@link X11Util#XLockDisplay(long)}.
- * <br>
- * This strategy should only be used if AWT is using the underlying native windowing toolkit
- * in a not intrinsic thread safe manner, e.g. under X11 where no XInitThreads() call
- * is issued before any other X11 usage. This is the current situation for e.g. Webstart or Applets.
+ * Concurrent initialization and lock-free rendering using shared NEWT Display EDT instances.
+ * <p>
+ * Rendering is always lock-free and independent of the EDT, however shared NEWT Display instances
+ * perform lifecycle actions (window creation etc) with locking.
+ * </p>
*/
-public class X11JAWTToolkitLock implements ToolkitLock {
- long displayHandle;
- RecursiveLock lock;
+public class TestInitConcurrent01NEWT extends InitConcurrentBaseNEWT {
- public X11JAWTToolkitLock(long displayHandle) {
- this.displayHandle = displayHandle;
- if(!X11Util.isNativeLockAvailable()) {
- lock = LockFactory.createRecursiveLock();
- }
+ @Test
+ public void test02TwoThreads() throws InterruptedException {
+ runJOGLTasks(2, true);
}
-
- public final void lock() {
- if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.lock() - native: "+(null==lock)); }
- JAWTUtil.lockToolkit();
- if(null == lock) {
- X11Lib.XLockDisplay(displayHandle);
+
+ @Test
+ public void test02FourThreads() throws InterruptedException {
+ runJOGLTasks(4, true);
+ }
+
+ @Test
+ public void test16SixteenThreads() throws InterruptedException {
+ if( Platform.getCPUFamily() != Platform.CPUFamily.ARM ) {
+ runJOGLTasks(16, true);
} else {
- lock.lock();
+ runJOGLTasks( 8, true);
}
}
-
- public final void unlock() {
- if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.unlock() - native: "+(null==lock)); }
- if(null == lock) {
- X11Lib.XUnlockDisplay(displayHandle);
- } else {
- lock.unlock();
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ try {
+ duration = Integer.parseInt(args[i]);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ }
}
- JAWTUtil.unlockToolkit();
+ String tstname = TestInitConcurrent01NEWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
}
+
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent02NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent02NEWT.java
new file mode 100644
index 000000000..51e9af00e
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent02NEWT.java
@@ -0,0 +1,78 @@
+/**
+ * Copyright 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+import com.jogamp.common.os.Platform;
+
+/**
+ * Concurrent and lock-free initialization and rendering using exclusive NEWT Display EDT instances.
+ * <p>
+ * Rendering is always lock-free and independent of the EDT, however exclusive NEWT Display instances
+ * perform lifecycle actions (window creation etc) w/o locking.
+ * </p>
+ */
+public class TestInitConcurrent02NEWT extends InitConcurrentBaseNEWT {
+
+ @Test
+ public void test02TwoThreads() throws InterruptedException {
+ runJOGLTasks(2, false);
+ }
+
+ @Test
+ public void test02FourThreads() throws InterruptedException {
+ runJOGLTasks(4, false);
+ }
+
+ @Test
+ public void test16SixteenThreads() throws InterruptedException {
+ if( Platform.getCPUFamily() != Platform.CPUFamily.ARM ) {
+ runJOGLTasks(16, false);
+ } else {
+ runJOGLTasks( 8, false);
+ }
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ try {
+ duration = Integer.parseInt(args[i]);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ }
+ }
+ String tstname = TestInitConcurrent02NEWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}