summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2010-04-15 03:44:12 +0200
committerSven Gothel <[email protected]>2010-04-15 03:44:12 +0200
commit2ae28d54858ff684bc2368e0476a7a357dc63432 (patch)
tree41524bc7be69f029d2b183128cc0c8b89ec4754c
parent2df3bea10859ee2f2c4b3622f3b610b17a5749d6 (diff)
Further ATI (fglrx) X11Display bug workaround/cleanup
- See https://bugzilla.mozilla.org/show_bug.cgi?id=486277 - Calling XCloseDisplay occasionally leads to a SIGSEGV, even thought the reference is valid and OK. Workaround is not to close any X11Display, but to hold them stashed and reuse them. Since we already pipeline all X11Display's via Nativewindow's X11Util, an added referenceCounter and a global active/passive list solved this problem. This workaround is only active in case 'isVendorATI()'. NEWT/NativeWindow X11: - Let XIOErrorHandler and invalid display references fail hard with FatalError, otherwise we won't see the stack trace - and those bugs are indeed fatal. NativeWindow X11: - Install XIOErrorHandler, which stays active. - X11Util.X11Display: - Add reference counter - Add global active/passive list. Passive if reference count == 0 and marked as 'un-closeable' (-> ATI). Reusing passive members when create a new display. - JOGL: - Use DeleteLocalRef() calls to free temp NIO buffer in manual *Copied implementation. - GLDrawableFactoryImpl: Be serious about the shutdown() semantics - *GraphicsConfiguration: - Fix the invalid Onscreen/PBuffer/Pixmap determination (X11/EGL/WGL) - Just return null if not valid - X11GLXGraphicsConfigurationFactory - FBConfig - Determine recommendedIndex properly .. - Don't bail out if a FBConfig is invalid .. - Use Chooser in case nothing is recommended .. - X11OffscreenGLXDrawable fixes bugs: - wrong (int) cast of parent window in XCreatePixmap call - setting display to zero too early in destruction, ie before XCloseDisplay - X11GLXDrawableFactory is using [singleton] shared dummy resources for - Screen, Drawable and Context which are utilized in case they are needed .. They are removed at shutdown call - GLXVersion gathering in GLXUtil now .. - DefaultGLCapabilitiesChooser: Respect PBuffer selection Tests: - Add DrawableFactory shutdown() - Add various Offscreen Capabilties - Add Offscreen and non-pbuffer case - JUnit Passed (Linux64bit: NVidia/ATI) - demos.jrefract.JRefract passed (Linux64bit: NVidia/ATI)
-rw-r--r--make/build-nativewindow.xml3
-rwxr-xr-xmake/config/jogl/glx-CustomCCode.c7
-rwxr-xr-xmake/config/nativewindow/x11-CustomCCode.c230
-rw-r--r--make/config/nativewindow/x11-CustomJavaCode.java12
-rw-r--r--make/config/nativewindow/x11-lib.cfg20
-rw-r--r--make/stub_includes/x11/window-lib.c3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java17
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java19
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java15
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java8
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java48
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java20
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java36
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java156
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java57
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java92
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java12
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java2
-rw-r--r--src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java11
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawableFactory.java2
-rwxr-xr-xsrc/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java35
-rwxr-xr-xsrc/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java264
-rwxr-xr-xsrc/junit/com/jogamp/test/junit/jogl/offscreen/WindowUtilNEWT.java25
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java228
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java2
-rw-r--r--src/nativewindow/native/x11/Xmisc.c471
-rwxr-xr-xsrc/newt/classes/com/jogamp/newt/x11/X11Display.java6
-rwxr-xr-xsrc/newt/native/X11Window.c76
28 files changed, 1369 insertions, 508 deletions
diff --git a/make/build-nativewindow.xml b/make/build-nativewindow.xml
index 3a62e9733..4b726bafb 100644
--- a/make/build-nativewindow.xml
+++ b/make/build-nativewindow.xml
@@ -530,6 +530,7 @@
<patternset id="c.src.files.x11">
<include name="${rootrel.generated.c}/X11/X11*.c" if="isX11"/>
+ <include name="${rootrel.src.c}/x11/Xmisc.c" if="isX11"/>
<include name="${rootrel.src.c}/x11/XineramaHelper.c" if="isX11"/>
<!-- Xinerama supporting functions for Linux only (for now) -->
<!-- Also supported on Solaris, but works differently -->
@@ -623,6 +624,8 @@
</target>
<target name="c.build.nativewindow.windowlib.x11" if="isX11">
+ <javah destdir="${src.generated.c}/X11" classpath="${classes}" class="com.jogamp.nativewindow.impl.x11.X11Lib" />
+
<c.build c.compiler.src.files="c.src.files.x11"
output.lib.name="nativewindow_x11"
compiler.cfg.id="${compiler.cfg.id}"
diff --git a/make/config/jogl/glx-CustomCCode.c b/make/config/jogl/glx-CustomCCode.c
index 7dac53fb6..1b30a7da6 100755
--- a/make/config/jogl/glx-CustomCCode.c
+++ b/make/config/jogl/glx-CustomCCode.c
@@ -78,7 +78,7 @@ Java_com_jogamp_opengl_impl_x11_glx_GLX_glXGetVisualFromFBConfigCopied0__JJ(JNIE
jbyteCopy = (*env)->CallStaticObjectMethod(env,
clazzInternalBufferUtil, cstrInternalBufferUtil, jbyteSource);
- // FIXME: remove reference/gc jbyteSource ??
+ (*env)->DeleteLocalRef(env, jbyteSource);
XFree(_res);
return jbyteCopy;
@@ -118,8 +118,7 @@ Java_com_jogamp_opengl_impl_x11_glx_GLX_glXChooseFBConfigCopied1__JILjava_lang_O
jbyteSource = (*env)->NewDirectByteBuffer(env, _res, count * sizeof(GLXFBConfig));
jbyteCopy = (*env)->CallStaticObjectMethod(env,
clazzInternalBufferUtil, cstrInternalBufferUtil, jbyteSource);
-
- // FIXME: remove reference/gc jbyteSource ??
+ (*env)->DeleteLocalRef(env, jbyteSource);
XFree(_res);
return jbyteCopy;
@@ -151,7 +150,7 @@ Java_com_jogamp_opengl_impl_x11_glx_GLX_glXChooseVisualCopied1__JILjava_lang_Obj
jbyteCopy = (*env)->CallStaticObjectMethod(env,
clazzInternalBufferUtil, cstrInternalBufferUtil, jbyteSource);
- // FIXME: remove reference/gc jbyteSource ??
+ (*env)->DeleteLocalRef(env, jbyteSource);
XFree(_res);
return jbyteCopy;
diff --git a/make/config/nativewindow/x11-CustomCCode.c b/make/config/nativewindow/x11-CustomCCode.c
deleted file mode 100755
index 982a39f7e..000000000
--- a/make/config/nativewindow/x11-CustomCCode.c
+++ /dev/null
@@ -1,230 +0,0 @@
-#include <inttypes.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-/* Linux headers don't work properly */
-#define __USE_GNU
-#include <dlfcn.h>
-#undef __USE_GNU
-
-/* Current versions of Solaris don't expose the XF86 extensions,
- although with the recent transition to Xorg this will probably
- happen in an upcoming release */
-#if !defined(__sun) && !defined(_HPUX)
-#include <X11/extensions/xf86vmode.h>
-#else
-/* Need to provide stubs for these */
-Bool XF86VidModeGetGammaRampSize(
- Display *display,
- int screen,
- int* size)
-{
- return False;
-}
-
-Bool XF86VidModeGetGammaRamp(
- Display *display,
- int screen,
- int size,
- unsigned short *red_array,
- unsigned short *green_array,
- unsigned short *blue_array) {
- return False;
-}
-Bool XF86VidModeSetGammaRamp(
- Display *display,
- int screen,
- int size,
- unsigned short *red_array,
- unsigned short *green_array,
- unsigned short *blue_array) {
- return False;
-}
-#endif
-
-/* HP-UX doesn't define RTLD_DEFAULT. */
-#if defined(_HPUX) && !defined(RTLD_DEFAULT)
-#define RTLD_DEFAULT NULL
-#endif
-
-/* Need to expose DefaultScreen and RootWindow macros to Java */
-JNIEXPORT jlong JNICALL
-Java_com_jogamp_nativewindow_impl_x11_X11Lib_DefaultScreen(JNIEnv *env, jclass _unused, jlong display) {
- return DefaultScreen((Display*) (intptr_t) display);
-}
-
-JNIEXPORT jlong JNICALL
-Java_com_jogamp_nativewindow_impl_x11_X11Lib_DefaultVisualID(JNIEnv *env, jclass _unused, jlong display, jint screen) {
- return (jlong) XVisualIDFromVisual( DefaultVisual( (Display*) (intptr_t) display, screen ) );
-}
-
-JNIEXPORT jlong JNICALL
-Java_com_jogamp_nativewindow_impl_x11_X11Lib_RootWindow(JNIEnv *env, jclass _unused, jlong display, jint screen) {
- return RootWindow((Display*) (intptr_t) display, screen);
-}
-
-JNIEXPORT jlong JNICALL
-Java_com_jogamp_nativewindow_impl_x11_X11Lib_dlopen(JNIEnv *env, jclass _unused, jstring name) {
- const jbyte* chars;
- void* res;
- chars = (*env)->GetStringUTFChars(env, name, NULL);
- res = dlopen(chars, RTLD_LAZY | RTLD_GLOBAL);
- (*env)->ReleaseStringUTFChars(env, name, chars);
- return (jlong) ((intptr_t) res);
-}
-
-JNIEXPORT jlong JNICALL
-Java_com_jogamp_nativewindow_impl_x11_X11Lib_dlsym(JNIEnv *env, jclass _unused, jstring name) {
- const jbyte* chars;
- void* res;
- chars = (*env)->GetStringUTFChars(env, name, NULL);
- res = dlsym(RTLD_DEFAULT, chars);
- (*env)->ReleaseStringUTFChars(env, name, chars);
- return (jlong) ((intptr_t) res);
-}
-
-/* Need to pull this in as we don't have a stub header for it */
-extern Bool XineramaEnabled(Display* display);
-
-static const char * clazzNameInternalBufferUtil = "com/jogamp/nativewindow/impl/InternalBufferUtil";
-static const char * clazzNameInternalBufferUtilStaticCstrName = "copyByteBuffer";
-static const char * clazzNameInternalBufferUtilStaticCstrSignature = "(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;";
-static const char * clazzNameByteBuffer = "java/nio/ByteBuffer";
-static jclass clazzInternalBufferUtil = NULL;
-static jmethodID cstrInternalBufferUtil = NULL;
-static jclass clazzByteBuffer = NULL;
-
-static void _initClazzAccess(JNIEnv *env) {
- jclass c;
-
- if(NULL!=cstrInternalBufferUtil) return ;
-
- c = (*env)->FindClass(env, clazzNameInternalBufferUtil);
- if(NULL==c) {
- fprintf(stderr, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s\n", clazzNameInternalBufferUtil);
- (*env)->FatalError(env, clazzNameInternalBufferUtil);
- }
- clazzInternalBufferUtil = (jclass)(*env)->NewGlobalRef(env, c);
- if(NULL==clazzInternalBufferUtil) {
- fprintf(stderr, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s\n", clazzNameInternalBufferUtil);
- (*env)->FatalError(env, clazzNameInternalBufferUtil);
- }
- c = (*env)->FindClass(env, clazzNameByteBuffer);
- if(NULL==c) {
- fprintf(stderr, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s\n", clazzNameByteBuffer);
- (*env)->FatalError(env, clazzNameByteBuffer);
- }
- clazzByteBuffer = (jclass)(*env)->NewGlobalRef(env, c);
- if(NULL==c) {
- fprintf(stderr, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s\n", clazzNameByteBuffer);
- (*env)->FatalError(env, clazzNameByteBuffer);
- }
-
- cstrInternalBufferUtil = (*env)->GetStaticMethodID(env, clazzInternalBufferUtil,
- clazzNameInternalBufferUtilStaticCstrName, clazzNameInternalBufferUtilStaticCstrSignature);
- if(NULL==cstrInternalBufferUtil) {
- fprintf(stderr, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib:: can't create %s.%s %s\n",
- clazzNameInternalBufferUtil,
- clazzNameInternalBufferUtilStaticCstrName, clazzNameInternalBufferUtilStaticCstrSignature);
- (*env)->FatalError(env, clazzNameInternalBufferUtilStaticCstrName);
- }
-}
-
-/* Java->C glue code:
- * Java package: com.jogamp.nativewindow.impl.x11.X11Lib
- * Java method: XVisualInfo XGetVisualInfo(long arg0, long arg1, XVisualInfo arg2, java.nio.IntBuffer arg3)
- * C function: XVisualInfo * XGetVisualInfo(Display * , long, XVisualInfo * , int * );
- */
-JNIEXPORT jobject JNICALL
-Java_com_jogamp_nativewindow_impl_x11_X11Lib_XGetVisualInfoCopied1__JJLjava_nio_ByteBuffer_2Ljava_lang_Object_2I(JNIEnv *env, jclass _unused, jlong arg0, jlong arg1, jobject arg2, jobject arg3, jint arg3_byte_offset) {
- XVisualInfo * _ptr2 = NULL;
- int * _ptr3 = NULL;
- XVisualInfo * _res;
- int count;
- jobject jbyteSource;
- jobject jbyteCopy;
- if (arg2 != NULL) {
- _ptr2 = (XVisualInfo *) (((char*) (*env)->GetDirectBufferAddress(env, arg2)) + 0);
- }
- if (arg3 != NULL) {
- _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, arg3, NULL)) + arg3_byte_offset);
- }
- _res = XGetVisualInfo((Display *) (intptr_t) arg0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3);
- count = _ptr3[0];
- if (arg3 != NULL) {
- (*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0);
- }
- if (_res == NULL) return NULL;
-
- _initClazzAccess(env);
-
- jbyteSource = (*env)->NewDirectByteBuffer(env, _res, count * sizeof(XVisualInfo));
- jbyteCopy = (*env)->CallStaticObjectMethod(env,
- clazzInternalBufferUtil, cstrInternalBufferUtil, jbyteSource);
-
- // FIXME: remove reference/gc jbyteSource ??
- XFree(_res);
-
- return jbyteCopy;
-}
-
-
-static XIOErrorHandler origIOErrorHandler = NULL;
-
-static int displayIOErrorHandler(Display *dpy)
-{
- fprintf(stderr, "Fatal: Nativewindow X11 IOError: Display %p not available\n", dpy);
- origIOErrorHandler(dpy);
- return 0;
-}
-
-static void displayIOErrorHandlerEnable(int onoff) {
- if(onoff) {
- if(NULL==origIOErrorHandler) {
- origIOErrorHandler = XSetIOErrorHandler(displayIOErrorHandler);
- }
- } else {
- XSetIOErrorHandler(origIOErrorHandler);
- origIOErrorHandler = NULL;
- }
-}
-
-/* Java->C glue code:
- * Java package: com.jogamp.nativewindow.impl.x11.X11Lib
- * Java method: int XCloseDisplay(long display)
- * C function: int XCloseDisplay(Display * display);
- */
-JNIEXPORT jint JNICALL
-Java_com_jogamp_nativewindow_impl_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclass _unused, jlong display) {
- int _res;
- // fprintf(stderr, "X11Lib.XCloseDisplay: %p\n", (Display *) (intptr_t) display);
- displayIOErrorHandlerEnable(1);
- _res = XCloseDisplay((Display *) (intptr_t) display);
- displayIOErrorHandlerEnable(0);
- return _res;
-}
-
-/* Java->C glue code:
- * Java package: com.jogamp.nativewindow.impl.x11.X11Lib
- * Java method: long XOpenDisplay(java.lang.String arg0)
- * C function: Display * XOpenDisplay(const char * );
- */
-JNIEXPORT jlong JNICALL
-Java_com_jogamp_nativewindow_impl_x11_X11Lib_XOpenDisplay__Ljava_lang_String_2(JNIEnv *env, jclass _unused, jstring arg0) {
- const char* _strchars_arg0 = NULL;
- Display * _res;
- if ( NULL != arg0 ) {
- _strchars_arg0 = (*env)->GetStringUTFChars(env, arg0, (jboolean*)NULL);
- if ( NULL == _strchars_arg0 ) {
- (*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/OutOfMemoryError"),
- "Failed to get UTF-8 chars for argument \"arg0\" in native dispatcher for \"XOpenDisplay\"");
- return 0;
- }
- }
- _res = XOpenDisplay((char *) _strchars_arg0);
- // fprintf(stderr, "X11Lib.XOpenDisplay: %s -> %p\n", _strchars_arg0, _res);
- if ( NULL != arg0 ) {
- (*env)->ReleaseStringUTFChars(env, arg0, _strchars_arg0);
- }
- return (jlong) (intptr_t) _res;
-}
-
diff --git a/make/config/nativewindow/x11-CustomJavaCode.java b/make/config/nativewindow/x11-CustomJavaCode.java
index d631c92cb..57f37bee7 100644
--- a/make/config/nativewindow/x11-CustomJavaCode.java
+++ b/make/config/nativewindow/x11-CustomJavaCode.java
@@ -24,8 +24,16 @@
/** Entry point to C language function: <code> XVisualInfo * XGetVisualInfo(Display * , long, XVisualInfo * , int * ); </code> */
private static native java.nio.ByteBuffer XGetVisualInfoCopied1(long arg0, long arg1, java.nio.ByteBuffer arg2, Object arg3, int arg3_byte_offset);
- public static native long XOpenDisplay(String arg0);
- public static native int XCloseDisplay(long display);
+ public static native long DefaultVisualID(long display, int screen);
+
+ /**
+ public static native long CreateDummyWindow(long display, int screen_index, long visualID);
+ public static native void DestroyDummyWindow(long display, long window); */
+
public static native long dlopen(String name);
public static native long dlsym(String name);
+ public static native int XCloseDisplay(long display);
+ public static native void XUnlockDisplay(long display);
+ public static native void XLockDisplay(long display);
+
diff --git a/make/config/nativewindow/x11-lib.cfg b/make/config/nativewindow/x11-lib.cfg
index 394dd230a..cf9642398 100644
--- a/make/config/nativewindow/x11-lib.cfg
+++ b/make/config/nativewindow/x11-lib.cfg
@@ -20,25 +20,25 @@ Opaque long Display *
Opaque boolean Bool
Opaque long GLXFBConfig
-# Manually implement XOpenDisplay, XCloseDisplay, catching XIOError
-ManuallyImplement XCloseDisplay
-ManuallyImplement XOpenDisplay
-
IncludeAs CustomJavaCode X11Lib x11-CustomJavaCode.java
-IncludeAs CustomCCode x11-CustomCCode.c
+# Now resides in x11/Xmisc.c: IncludeAs CustomCCode x11-CustomCCode.c
ArgumentIsString XOpenDisplay 0
-# Need to expose DefaultScreen and RootWindow macros to Java
-CustomJavaCode X11Lib public static native int DefaultScreen(long display);
-CustomJavaCode X11Lib public static native long DefaultVisualID(long display, int screen);
-CustomJavaCode X11Lib public static native long RootWindow(long display, int screen);
-
# We have Custom code for the following
Ignore XGetVisualInfo
+ManuallyImplement XCloseDisplay
+ManuallyImplement XUnlockDisplay
+ManuallyImplement XLockDisplay
+
# Helper routine to make the ReturnedArrayLength expression below work correctly
CustomJavaCode X11Lib private static int getFirstElement(IntBuffer buf) { return buf.get(buf.position()); }
CustomJavaCode X11Lib private static int getFirstElement(int[] arr, int offset) { return arr[offset]; }
CustomJavaCode XVisualInfo public static XVisualInfo create(XVisualInfo s) { XVisualInfo d = XVisualInfo.create(); d.getBuffer().put(s.getBuffer()); d.getBuffer().rewind(); s.getBuffer().rewind(); return d; }
+
+CustomCCode #include <inttypes.h>
+CustomCCode #include <X11/Xlib.h>
+CustomCCode #include <X11/Xutil.h>
+
diff --git a/make/stub_includes/x11/window-lib.c b/make/stub_includes/x11/window-lib.c
index 3096cde4c..8fca86263 100644
--- a/make/stub_includes/x11/window-lib.c
+++ b/make/stub_includes/x11/window-lib.c
@@ -17,6 +17,9 @@ extern void XLockDisplay(Display *display);
extern void XUnlockDisplay(Display *display);
+extern Window RootWindow(Display *display, int screen_number);
+extern int DefaultScreen(Display *display);
+
extern XVisualInfo *XGetVisualInfo(
Display* /* display */,
long /* vinfo_mask */,
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
index 35810678c..616640bad 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
@@ -54,13 +54,24 @@ import java.lang.reflect.*;
public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
protected static final boolean DEBUG = Debug.debug("GLDrawableFactory");
+ private boolean isValid = false;
+
public void shutdown() {
+ validate();
+ isValid = false;
+ }
+
+ protected final void validate() {
+ if(!isValid) {
+ throw new GLException("GLDrawableFactory is already shutdown!");
+ }
}
//---------------------------------------------------------------------------
// Dispatching GLDrawable construction in respect to the NativeWindow Capabilities
//
public GLDrawable createGLDrawable(NativeWindow target) {
+ validate();
if (target == null) {
throw new IllegalArgumentException("Null target");
}
@@ -124,6 +135,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
GLCapabilitiesChooser chooser,
int width,
int height) {
+ validate();
if(height<=0 || height<=0) {
throw new GLException("Width and height of pbuffer must be positive (were (" +
width + ", " + height + "))");
@@ -139,6 +151,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
int width,
int height,
GLContext shareWith) {
+ validate();
return new GLPbufferImpl( (GLDrawableImpl) createGLPbufferDrawable(capabilities, chooser, height, height),
shareWith);
}
@@ -155,6 +168,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
GLCapabilitiesChooser chooser,
int width,
int height) {
+ validate();
if(width<=0 || height<=0) {
throw new GLException("Width and height of pbuffer must be positive (were (" +
width + ", " + height + "))");
@@ -174,6 +188,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
protected GLDrawableFactoryImpl() {
super();
+ isValid = true;
}
protected void maybeDoSingleThreadedWorkaround(Runnable action) {
@@ -279,6 +294,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
* out-of-bounds
*/
public boolean setDisplayGamma(float gamma, float brightness, float contrast) throws IllegalArgumentException {
+ validate();
if ((brightness < -1.0f) || (brightness > 1.0f)) {
throw new IllegalArgumentException("Brightness must be between -1.0 and 1.0");
}
@@ -311,6 +327,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
}
public synchronized void resetDisplayGamma() {
+ validate();
if (gammaShutdownHook == null) {
throw new IllegalArgumentException("Should not call this unless setDisplayGamma called first");
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java
index c8bc4fe0d..2d5154442 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java
@@ -122,10 +122,11 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple
if ( onscreen ) {
res = ( 0 != (val & EGL.EGL_WINDOW_BIT) ) ;
} else {
- res = ( 0 != (val & EGL.EGL_PIXMAP_BIT) ) || usePBuffer ;
- }
- if ( usePBuffer ) {
- res = res && ( 0 != (val & EGL.EGL_PBUFFER_BIT) ) ;
+ if ( usePBuffer ) {
+ res = ( 0 != (val & EGL.EGL_PBUFFER_BIT) ) ;
+ } else {
+ res = ( 0 != (val & EGL.EGL_PIXMAP_BIT) ) ;
+ }
}
return res;
@@ -187,17 +188,13 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple
caps.setOnscreen( 0 != (val[0] & EGL.EGL_WINDOW_BIT) );
caps.setPBuffer ( 0 != (val[0] & EGL.EGL_PBUFFER_BIT) );
} else {
- throw new GLException("EGL_SURFACE_TYPE does not match !!!");
- }
- } else {
- if(relaxed) {
if(DEBUG) {
- System.err.println("Could not determine EGL_SURFACE_TYPE !!!");
+ System.err.println("EGL_SURFACE_TYPE does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (val[0] & EGL.EGL_WINDOW_BIT) )+", pbuffer "+( 0 != (val[0] & EGL.EGL_PBUFFER_BIT) )+", pixmap "+( 0 != (val[0] & EGL.EGL_PIXMAP_BIT) )+")");
}
return null;
- } else {
- throw new GLException("Could not determine EGL_SURFACE_TYPE !!!");
}
+ } else {
+ throw new GLException("Could not determine EGL_SURFACE_TYPE !!!");
}
return caps;
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java
index 5b34e40e1..aed4012a4 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -412,14 +412,16 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio
if ( onscreen ) {
res = ( 0 != (val & WINDOW_BIT) ) ;
} else {
- res = ( 0 != (val & BITMAP_BIT) ) || usePBuffer ;
- }
- if ( usePBuffer ) {
- res = res && ( 0 != (val & PBUFFER_BIT) ) ;
+ if ( usePBuffer ) {
+ res = ( 0 != (val & PBUFFER_BIT) ) ;
+ } else {
+ res = ( 0 != (val & BITMAP_BIT) ) ;
+ }
}
return res;
}
+
public static GLCapabilities AttribList2GLCapabilities(GLProfile glp, int[] iattribs,
int niattribs,
int[] iresults,
@@ -433,7 +435,10 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio
res.setOnscreen( 0 != (drawableTypeBits & WINDOW_BIT) );
res.setPBuffer ( 0 != (drawableTypeBits & PBUFFER_BIT) );
} else {
- throw new GLException("WGL DrawableType does not match !!!");
+ if(DEBUG) {
+ System.err.println("WGL DrawableType does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (drawableTypeBits & WINDOW_BIT) )+", pbuffer "+( 0 != (drawableTypeBits & PBUFFER_BIT) )+", pixmap "+( 0 != (drawableTypeBits & BITMAP_BIT))+")");
+ }
+ return null;
}
for (int i = 0; i < niattribs; i++) {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
index 55b30ef3a..1a375699c 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -260,9 +260,11 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio
}
pixelFormat = 1; // default ..
} else if ( pixelFormat > numFormats ) {
- throw new GLException("Invalid result " + pixelFormat +
- " from GLCapabilitiesChooser (should be between 1 and " +
- numFormats + ")");
+ // keep on going ..
+ if(DEBUG) {
+ System.err.println("GLCapabilitiesChooser specified invalid index (expected 1.." + numFormats + ", got "+pixelFormat+")");
+ }
+ pixelFormat = 1; // default ..
}
}
chosenCaps = availableCaps[pixelFormat-1];
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java
index 99c54332f..e3c1381f8 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java
@@ -54,13 +54,55 @@ public class GLXUtil {
/** Workaround for apparent issue with ATI's proprietary drivers
where direct contexts still send GLX tokens for GL calls */
- public static boolean isVendorATI(long display) {
+ public static String getVendorName(long display) {
try {
X11Lib.XLockDisplay(display);
- String vendor = GLX.glXGetClientString(display, GLX.GLX_VENDOR);
- return vendor != null && vendor.startsWith("ATI") ;
+ return GLX.glXGetClientString(display, GLX.GLX_VENDOR);
} finally {
X11Lib.XUnlockDisplay(display);
}
}
+
+ public static boolean isVendorNVIDIA(String vendor) {
+ return vendor != null && vendor.startsWith("NVIDIA") ;
+ }
+
+ public static boolean isVendorATI(String vendor) {
+ return vendor != null && vendor.startsWith("ATI") ;
+ }
+
+ public static boolean isVendorATI(long display) {
+ return isVendorATI(getVendorName(display));
+ }
+
+ public static boolean isVendorNVIDIA(long display) {
+ return isVendorNVIDIA(getVendorName(display));
+ }
+
+ public static void getGLXVersion(long display, int major[], int minor[]) {
+ if(0 == display) {
+ throw new GLException("null display handle");
+ }
+ if(major.length<1||minor.length<1) {
+ throw new GLException("passed int arrays size is not >= 1");
+ }
+
+ if (!GLX.glXQueryVersion(display, major, 0, minor, 0)) {
+ throw new GLException("glXQueryVersion failed");
+ }
+
+ // Work around bugs in ATI's Linux drivers where they report they
+ // only implement GLX version 1.2 on the server side
+ if (major[0] == 1 && minor[0] == 2) {
+ String str = GLX.glXGetClientString(display, GLX.GLX_VERSION);
+ try {
+ // e.g. "1.3"
+ major[0] = Integer.valueOf(str.substring(0, 1)).intValue();
+ minor[0] = Integer.valueOf(str.substring(2, 3)).intValue();
+ } catch (Exception e) {
+ major[0] = 1;
+ minor[0] = 2;
+ }
+ }
+ }
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java
index 097689967..a865e91e8 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java
@@ -42,6 +42,8 @@ import com.jogamp.nativewindow.impl.x11.*;
public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable {
+ // private long dummyWindow = 0;
+
/**
* Due to the ATI Bug https://bugzilla.mozilla.org/show_bug.cgi?id=486277,
* we cannot switch the Display as we please,
@@ -57,12 +59,17 @@ public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable {
X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)nw.getGraphicsConfiguration().getNativeGraphicsConfiguration();
GLCapabilities caps = (GLCapabilities) config.getChosenCapabilities();
- long dpy = config.getScreen().getDevice().getHandle();
- int scrn = config.getScreen().getIndex();
- // System.out.println("X11DummyGLXDrawable: dpy "+toHexString(dpy)+", scrn "+scrn);
+ X11GraphicsDevice device = (X11GraphicsDevice) screen.getDevice();
+ long dpy = device.getHandle();
+ int scrn = screen.getIndex();
+ // long visualID = config.getVisualID();
+ // System.out.println("X11DummyGLXDrawable: dpy "+toHexString(dpy)+", scrn "+scrn+", visualID "+toHexString(visualID));
+
X11Lib.XLockDisplay(dpy);
try{
nw.setSurfaceHandle( X11Lib.RootWindow(dpy, scrn) );
+ // dummyWindow = X11Lib.CreateDummyWindow(dpy, scrn, visualID);
+ // nw.setSurfaceHandle( dummyWindow );
} finally {
X11Lib.XUnlockDisplay(dpy);
}
@@ -80,6 +87,11 @@ public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable {
}
public void destroy() {
- // nothing to do, but allowed
+ /**
+ if(0!=dummyWindow) {
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ long dpy = config.getScreen().getDevice().getHandle();
+ X11Lib.DestroyDummyWindow(dpy, dummyWindow);
+ } */
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java
index 055e7236c..142da672a 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java
@@ -133,7 +133,7 @@ public abstract class X11GLXContext extends GLContextImpl {
}
GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities();
- isVendorATI = GLXUtil.isVendorATI(display);
+ isVendorATI = ((X11GLXDrawableFactory)(drawable.getFactoryImpl())).isVendorATI();
if(config.getFBConfigID()<0) {
// not able to use FBConfig
@@ -148,11 +148,11 @@ public abstract class X11GLXContext extends GLContextImpl {
drawable.getNativeWindow().getSurfaceHandle(),
drawableRead.getNativeWindow().getSurfaceHandle(),
context)) {
- throw new GLException("Error making temp context (old2) current: display 0x"+Long.toHexString(display)+", context 0x"+Long.toHexString(context)+", drawable "+drawable);
+ throw new GLException("Error making temp context (old2) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable);
}
setGLFunctionAvailability(true);
if(DEBUG) {
- System.err.println("X11GLXContext.createContext done (old2 ctx) 0x"+Long.toHexString(context));
+ System.err.println("X11GLXContext.createContext done (old2 ctx) "+toHexString(context));
}
} else {
@@ -167,7 +167,7 @@ public abstract class X11GLXContext extends GLContextImpl {
drawable.getNativeWindow().getSurfaceHandle(),
drawableRead.getNativeWindow().getSurfaceHandle(),
temp_context)) {
- throw new GLException("Error making temp context (old) current: display 0x"+Long.toHexString(display)+", context 0x"+Long.toHexString(context)+", drawable "+drawable);
+ throw new GLException("Error making temp context (old) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable);
}
setGLFunctionAvailability(true);
@@ -182,7 +182,7 @@ public abstract class X11GLXContext extends GLContextImpl {
// continue with temp context for GL < 3.0
context = temp_context;
if(DEBUG) {
- System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no GLX_ARB_create_context) 0x"+Long.toHexString(context));
+ System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no GLX_ARB_create_context) "+toHexString(context));
}
} else {
GLXExt glXExt = getGLXExt();
@@ -209,7 +209,7 @@ public abstract class X11GLXContext extends GLContextImpl {
/**
* don't stricten requirements any further, even compatible would be fine
*
- } else {
+ else {
attribs[8+0] = GLX.GLX_CONTEXT_PROFILE_MASK_ARB;
attribs[8+1] = GLX.GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
}
@@ -228,7 +228,7 @@ public abstract class X11GLXContext extends GLContextImpl {
GLX.glXDestroyContext(display, context);
context = 0;
} else if(DEBUG) {
- System.err.println("X11GLXContext.createContext >= 3.2 available 0x"+Long.toHexString(context));
+ System.err.println("X11GLXContext.createContext >= 3.2 available "+toHexString(context));
}
} else {
if(DEBUG) {
@@ -261,7 +261,7 @@ public abstract class X11GLXContext extends GLContextImpl {
GLX.glXDestroyContext(display, context);
context = 0;
} else if(DEBUG) {
- System.err.println("X11GLXContext.createContext >= 3.0 available 0x"+Long.toHexString(context));
+ System.err.println("X11GLXContext.createContext >= 3.0 available "+toHexString(context));
}
} else {
if(DEBUG) {
@@ -285,10 +285,10 @@ public abstract class X11GLXContext extends GLContextImpl {
context)) {
GLX.glXMakeContextCurrent(display, 0, 0, 0);
GLX.glXDestroyContext(display, temp_context);
- throw new GLException("Error making context (old) current: display 0x"+Long.toHexString(display)+", context 0x"+Long.toHexString(context)+", drawable "+drawable);
+ throw new GLException("Error making context (old) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable);
}
if(DEBUG) {
- System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no 3.0) 0x"+Long.toHexString(context));
+ System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no 3.0) "+toHexString(context));
}
} else {
GLX.glXDestroyContext(display, temp_context);
@@ -296,7 +296,7 @@ public abstract class X11GLXContext extends GLContextImpl {
// need to update the GL func table ..
updateGLProcAddressTable();
if(DEBUG) {
- System.err.println("X11GLXContext.createContext done (new ctx >= 3.0) 0x"+Long.toHexString(context));
+ System.err.println("X11GLXContext.createContext done (new ctx >= 3.0) "+toHexString(context));
}
}
}
@@ -337,6 +337,8 @@ public abstract class X11GLXContext extends GLContextImpl {
}
protected int makeCurrentImplAfterLock() throws GLException {
+ long dpy = drawable.getNativeWindow().getDisplayHandle();
+
getDrawableImpl().getFactoryImpl().lockToolkit();
try {
if (drawable.getNativeWindow().getSurfaceHandle() == 0) {
@@ -356,7 +358,7 @@ public abstract class X11GLXContext extends GLContextImpl {
if (GLX.glXGetCurrentContext() != context) {
- if (!GLX.glXMakeContextCurrent(drawable.getNativeWindow().getDisplayHandle(),
+ if (!GLX.glXMakeContextCurrent(dpy,
drawable.getNativeWindow().getSurfaceHandle(),
drawableRead.getNativeWindow().getSurfaceHandle(),
context)) {
@@ -364,7 +366,7 @@ public abstract class X11GLXContext extends GLContextImpl {
}
if (DEBUG && (VERBOSE || created)) {
System.err.println(getThreadName() + ": glXMakeCurrent(display " +
- toHexString(drawable.getNativeWindow().getDisplayHandle()) +
+ toHexString(dpy)+
", drawable " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) +
", drawableRead " + toHexString(drawableRead.getNativeWindow().getSurfaceHandle()) +
", context " + toHexString(context) + ") succeeded");
@@ -397,10 +399,10 @@ public abstract class X11GLXContext extends GLContextImpl {
try {
if (context != 0) {
if (DEBUG) {
- System.err.println("glXDestroyContext(0x" +
- Long.toHexString(drawable.getNativeWindow().getDisplayHandle()) +
- ", 0x" +
- Long.toHexString(context) + ")");
+ System.err.println("glXDestroyContext(" +
+ toHexString(drawable.getNativeWindow().getDisplayHandle()) +
+ ", " +
+ toHexString(context) + ")");
}
GLX.glXDestroyContext(drawable.getNativeWindow().getDisplayHandle(), context);
if (DEBUG) {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
index 60ee431dc..eda480d5f 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
@@ -48,6 +48,7 @@ import com.jogamp.nativewindow.impl.NWReflection;
import com.jogamp.nativewindow.impl.x11.*;
public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements DynamicLookupHelper {
+
public X11GLXDrawableFactory() {
super();
// Must initialize GLX support eagerly in case a pbuffer is the
@@ -60,64 +61,121 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
NWReflection.createInstance("com.jogamp.opengl.impl.x11.glx.awt.X11AWTGLXGraphicsConfigurationFactory",
new Object[] {});
} catch (Throwable t) { }
+
+ X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.createThreadLocalDisplay(null));
+ vendorName = GLXUtil.getVendorName(sharedDevice.getHandle());
+ isVendorATI = GLXUtil.isVendorATI(vendorName);
+ isVendorNVIDIA = GLXUtil.isVendorNVIDIA(vendorName);
+ if( isVendorATI() ) {
+ X11Util.markGlobalDisplayUndeletable(sharedDevice.getHandle()); // ATI hack ..
+ }
+ sharedScreen = new X11GraphicsScreen(sharedDevice, 0);
+ if (DEBUG) {
+ System.err.println("!!! Vendor: "+vendorName+", ATI: "+isVendorATI+", NV: "+isVendorNVIDIA);
+ System.err.println("!!! SharedScreen: "+sharedScreen);
+ }
+ }
+
+ private X11GraphicsScreen sharedScreen;
+ private String vendorName;
+ private boolean isVendorATI;
+ private boolean isVendorNVIDIA;
+
+ public String getVendorName() { return vendorName; }
+ public boolean isVendorATI() { return isVendorATI; }
+ public boolean isVendorNVIDIA() { return isVendorNVIDIA; }
+
+ private X11DummyGLXDrawable sharedDrawable=null;
+ private GLContext sharedContext=null;
+
+ private void initShared() {
+ if(null==sharedDrawable) {
+ X11Lib.XLockDisplay(sharedScreen.getDevice().getHandle());
+ sharedDrawable = new X11DummyGLXDrawable(sharedScreen, this, null);
+ sharedContext = sharedDrawable.createContext(null);
+ sharedContext.makeCurrent();
+ sharedContext.release();
+ X11Lib.XUnlockDisplay(sharedScreen.getDevice().getHandle());
+ if (DEBUG) {
+ System.err.println("!!! SharedContext: "+sharedContext);
+ }
+ }
+ }
+
+ public void shutdown() {
+ super.shutdown();
+ if (DEBUG) {
+ System.err.println("!!! Shutdown Shared:");
+ System.err.println("!!! CTX : "+sharedContext);
+ System.err.println("!!! Drawable: "+sharedDrawable);
+ System.err.println("!!! Screen : "+sharedScreen);
+ Exception e = new Exception("Debug");
+ e.printStackTrace();
+ }
+ if(null!=sharedContext) {
+ sharedContext.destroy(); // implies release, if current
+ }
+ if(null!=sharedDrawable) {
+ sharedDrawable.destroy();
+ }
+ if(null!=sharedScreen) {
+ X11GraphicsDevice sharedDevice = (X11GraphicsDevice) sharedScreen.getDevice();
+ if(null!=sharedDevice) {
+ X11Util.closeThreadLocalDisplay(null);
+ }
+ sharedScreen = null;
+ }
+ X11Util.shutdown( !isVendorATI(), DEBUG );
}
public GLDrawableImpl createOnscreenDrawable(NativeWindow target) {
+ validate();
if (target == null) {
throw new IllegalArgumentException("Null target");
}
+ if( isVendorATI() ) {
+ X11Util.markGlobalDisplayUndeletable(target.getDisplayHandle()); // ATI hack ..
+ }
return new X11OnscreenGLXDrawable(this, target);
}
protected GLDrawableImpl createOffscreenDrawable(NativeWindow target) {
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ if( isVendorATI() ) {
+ X11Util.markGlobalDisplayUndeletable(target.getDisplayHandle()); // ATI hack ..
+ }
+ initShared();
return new X11OffscreenGLXDrawable(this, target);
}
public boolean canCreateGLPbuffer(AbstractGraphicsDevice device) {
+ validate();
return glxVersionGreaterEqualThan(device, 1, 3);
}
private boolean glxVersionsQueried = false;
private int glxVersionMajor=0, glxVersionMinor=0;
public boolean glxVersionGreaterEqualThan(AbstractGraphicsDevice device, int majorReq, int minorReq) {
+ validate();
if (!glxVersionsQueried) {
if(null == device) {
- GLContext ctx = GLContext.getCurrent();
- if( null != ctx) {
- device = ctx.getGLDrawable().getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
- }
+ device = (X11GraphicsDevice) sharedScreen.getDevice();
}
if(null == device) {
- GLException gle = new GLException("FIXME: No AbstractGraphicsDevice (passed or queried via current context - Fallback to ThreadLocal Display ..");
- gle.printStackTrace();
-
- device = new X11GraphicsDevice(X11Util.getThreadLocalDisplay(null));
+ throw new GLException("FIXME: No AbstractGraphicsDevice (passed or shared-device");
}
long display = device.getHandle();
int[] major = new int[1];
int[] minor = new int[1];
- if (!GLX.glXQueryVersion(display, major, 0, minor, 0)) {
- throw new GLException("glXQueryVersion failed");
- }
+ GLXUtil.getGLXVersion(display, major, minor);
if (DEBUG) {
System.err.println("!!! GLX version: major " + major[0] +
", minor " + minor[0]);
}
- // Work around bugs in ATI's Linux drivers where they report they
- // only implement GLX version 1.2 on the server side
- if (major[0] == 1 && minor[0] == 2) {
- String str = GLX.glXGetClientString(display, GLX.GLX_VERSION);
- try {
- major[0] = Integer.valueOf(str.substring(0, 1)).intValue();
- minor[0] = Integer.valueOf(str.substring(2, 3)).intValue();
- } catch (NumberFormatException nfe) {
- major[0] = 1;
- minor[0] = 2;
- }
- }
-
glxVersionMajor = major[0];
glxVersionMinor = minor[0];
glxVersionsQueried = true;
@@ -127,8 +185,6 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
protected GLDrawableImpl createGLPbufferDrawableImpl(final NativeWindow target) {
GLDrawableImpl pbufferDrawable;
- X11DummyGLXDrawable dummyDrawable=null;
- GLContext dummyContext=null;
/**
* Due to the ATI Bug https://bugzilla.mozilla.org/show_bug.cgi?id=486277,
@@ -136,21 +192,20 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
* The dummy context shall also use the same Display,
* since switching Display in this regard is another ATI bug.
*/
- if( null == GLContext.getCurrent() ) {
- X11GraphicsScreen screen = (X11GraphicsScreen) target.getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen();
- dummyDrawable = new X11DummyGLXDrawable(screen, this, null);
- dummyContext = dummyDrawable.createContext(null);
- dummyContext.makeCurrent();
+ boolean usedSharedContext=false;
+ if( isVendorATI() && null == GLContext.getCurrent() ) {
+ initShared();
+ sharedContext.makeCurrent();
+ usedSharedContext=true;
+ }
+ if( isVendorATI() ) {
+ X11Util.markGlobalDisplayUndeletable(target.getDisplayHandle()); // ATI hack ..
}
try {
pbufferDrawable = new X11PbufferGLXDrawable(this, target);
} finally {
- if(null!=dummyContext) {
- dummyContext.release();
- dummyContext.destroy();
- }
- if(null!=dummyDrawable) {
- dummyDrawable.destroy();
+ if(usedSharedContext) {
+ sharedContext.release();
}
}
return pbufferDrawable;
@@ -158,25 +213,30 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
protected NativeWindow createOffscreenWindow(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) {
- AbstractGraphicsScreen screen = X11GraphicsScreen.createDefault();
- NullWindow nw = new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capabilities, chooser, screen));
+ X11Lib.XLockDisplay(sharedScreen.getDevice().getHandle());
+ NullWindow nw = new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capabilities, chooser, sharedScreen));
+ X11Lib.XUnlockDisplay(sharedScreen.getDevice().getHandle());
nw.setSize(width, height);
return nw;
}
public GLContext createExternalGLContext() {
+ validate();
return X11ExternalGLXContext.create(this, null);
}
public boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device) {
+ validate();
return canCreateGLPbuffer(device);
}
public GLDrawable createExternalGLDrawable() {
+ validate();
return X11ExternalGLXDrawable.create(this, null);
}
public void loadGLULibrary() {
+ validate();
X11Lib.dlopen("/usr/lib/libGLU.so");
}
@@ -191,6 +251,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
}
public boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device) {
+ validate();
return false;
}
@@ -210,9 +271,10 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
return gammaRampLength;
}
- long display = X11Util.getThreadLocalDefaultDisplay();
+ long display = sharedScreen.getDevice().getHandle();
+
+ X11Lib.XLockDisplay(display);
try {
- X11Lib.XLockDisplay(display);
int[] size = new int[1];
boolean res = X11Lib.XF86VidModeGetGammaRampSize(display,
X11Lib.DefaultScreen(display),
@@ -235,9 +297,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
rampData[i] = (short) (ramp[i] * 65535);
}
- long display = X11Util.getThreadLocalDefaultDisplay();
+ long display = sharedScreen.getDevice().getHandle();
+ X11Lib.XLockDisplay(display);
try {
- X11Lib.XLockDisplay(display);
boolean res = X11Lib.XF86VidModeSetGammaRamp(display,
X11Lib.DefaultScreen(display),
rampData.length,
@@ -262,9 +324,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
rampData.position(2 * size);
rampData.limit(3 * size);
ShortBuffer blueRampData = rampData.slice();
- long display = X11Util.getThreadLocalDefaultDisplay();
+ long display = sharedScreen.getDevice().getHandle();
+ X11Lib.XLockDisplay(display);
try {
- X11Lib.XLockDisplay(display);
boolean res = X11Lib.XF86VidModeGetGammaRamp(display,
X11Lib.DefaultScreen(display),
size,
@@ -298,9 +360,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
rampData.position(2 * size);
rampData.limit(3 * size);
ShortBuffer blueRampData = rampData.slice();
- long display = X11Util.getThreadLocalDefaultDisplay();
+ long display = sharedScreen.getDevice().getHandle();
+ X11Lib.XLockDisplay(display);
try {
- X11Lib.XLockDisplay(display);
X11Lib.XF86VidModeSetGammaRamp(display,
X11Lib.DefaultScreen(display),
size,
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java
index b3a6e5b8c..35daf0ae0 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -64,18 +64,18 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
int screen = x11Screen.getIndex();
long fbcfg = glXFBConfigID2FBConfig(display, screen, fbcfgID);
if(0==fbcfg) {
- throw new GLException("FBConfig null of 0x"+Integer.toHexString(fbcfgID));
+ throw new GLException("FBConfig null of "+toHexString(fbcfgID));
}
if(null==glp) {
glp = GLProfile.getDefault();
}
GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display));
if(null==caps) {
- throw new GLException("GLCapabilities null of 0x"+Long.toHexString(fbcfg));
+ throw new GLException("GLCapabilities null of "+toHexString(fbcfg));
}
XVisualInfo xvi = GLX.glXGetVisualFromFBConfigCopied(display, fbcfg);
if(null==xvi) {
- throw new GLException("XVisualInfo null of 0x"+Long.toHexString(fbcfg));
+ throw new GLException("XVisualInfo null of "+toHexString(fbcfg));
}
return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser(), xvi, fbcfg, fbcfgID);
}
@@ -104,6 +104,10 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
}
+ private static int nonZeroOrDontCare(int value) {
+ return value != 0 ? value : (int)GLX.GLX_DONT_CARE ;
+ }
+
public static int[] GLCapabilities2AttribList(GLCapabilities caps,
boolean forFBAttr,
boolean isMultisampleAvailable,
@@ -222,10 +226,11 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
if ( onscreen ) {
res = ( 0 != (val & GLX.GLX_WINDOW_BIT) ) ;
} else {
- res = ( 0 != (val & GLX.GLX_PIXMAP_BIT) ) || usePBuffer ;
- }
- if ( usePBuffer ) {
- res = res && ( 0 != (val & GLX.GLX_PBUFFER_BIT) ) ;
+ if ( usePBuffer ) {
+ res = ( 0 != (val & GLX.GLX_PBUFFER_BIT) ) ;
+ } else {
+ res = ( 0 != (val & GLX.GLX_PIXMAP_BIT) ) ;
+ }
}
return res;
@@ -237,7 +242,10 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
int val;
val = glXGetFBConfig(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0);
if (val != GLX.GLX_RGBA_BIT) {
- throw new GLException("Visual does not support RGBA");
+ if(DEBUG) {
+ System.err.println("FBConfig ("+toHexString(fbcfg)+") does not support RGBA: "+toHexString(val));
+ }
+ return null;
}
GLCapabilities res = new GLCapabilities(glp);
@@ -249,7 +257,10 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
res.setOnscreen( 0 != (val & GLX.GLX_WINDOW_BIT) );
res.setPBuffer ( 0 != (val & GLX.GLX_PBUFFER_BIT) );
} else {
- throw new GLException("GLX_DRAWABLE_TYPE does not match !!!");
+ if(DEBUG) {
+ System.err.println("FBConfig ("+toHexString(fbcfg)+") GLX_DRAWABLE_TYPE does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (val & GLX.GLX_WINDOW_BIT) )+", pbuffer "+( 0 != (val & GLX.GLX_PBUFFER_BIT) )+", pixmap "+( 0 != (val & GLX.GLX_PIXMAP_BIT) )+")");
+ }
+ return null;
}
res.setDoubleBuffered(glXGetFBConfig(display, fbcfg, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0);
res.setStereo (glXGetFBConfig(display, fbcfg, GLX.GLX_STEREO, tmp, 0) != 0);
@@ -302,7 +313,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
int res = GLX.glXGetFBConfigAttrib(display, cfg, attrib, tmp, tmp_offset);
if (res != 0) {
- throw new GLException("glXGetFBConfig(0x"+Long.toHexString(attrib)+") failed: error code " + glXGetFBConfigErrorCode(res));
+ throw new GLException("glXGetFBConfig("+toHexString(attrib)+") failed: error code " + glXGetFBConfigErrorCode(res));
}
return tmp[tmp_offset];
}
@@ -340,8 +351,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
}
if (DEBUG) {
- System.err.println("!!! Fetched XVisualInfo for visual ID 0x" + Long.toHexString(visualID));
- System.err.println("!!! Resulting XVisualInfo: visualid = 0x" + Long.toHexString(res.getVisualid()));
+ System.err.println("!!! Fetched XVisualInfo for visual ID " + toHexString(visualID));
+ System.err.println("!!! Resulting XVisualInfo: visualid = " + toHexString(res.getVisualid()));
}
return res;
}
@@ -350,11 +361,17 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
int[] tmp = new int[1];
int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0);
if (val == 0) {
- throw new GLException("Visual does not support OpenGL");
+ if(DEBUG) {
+ System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support OpenGL");
+ }
+ return null;
}
val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp, 0);
if (val == 0) {
- throw new GLException("Visual does not support RGBA");
+ if(DEBUG) {
+ System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support RGBA");
+ }
+ return null;
}
GLCapabilities res = new GLCapabilities(glp);
res.setOnscreen (onscreen);
@@ -399,13 +416,21 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
int res = GLX.glXGetConfig(display, info, attrib, tmp, tmp_offset);
if (res != 0) {
- throw new GLException("glXGetConfig(0x"+Long.toHexString(attrib)+") failed: error code " + glXGetConfigErrorCode(res));
+ throw new GLException("glXGetConfig("+toHexString(attrib)+") failed: error code " + glXGetConfigErrorCode(res));
}
return tmp[tmp_offset];
}
+ public static String toHexString(int val) {
+ return "0x"+Integer.toHexString(val);
+ }
+
+ public static String toHexString(long val) {
+ return "0x"+Long.toHexString(val);
+ }
+
public String toString() {
- return "X11GLXGraphicsConfiguration["+getScreen()+", visualID 0x" + Long.toHexString(getVisualID()) + ", fbConfigID 0x" + Long.toHexString(fbConfigID) +
+ return "X11GLXGraphicsConfiguration["+getScreen()+", visualID " + toHexString(getVisualID()) + ", fbConfigID " + toHexString(fbConfigID) +
",\n\trequested " + getRequestedCapabilities()+
",\n\tchosen " + getChosenCapabilities()+
"]";
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java
index 72551f928..477f2473c 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java
@@ -79,9 +79,10 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
//
GLCapabilities capsFB = null;
long display = x11Screen.getDevice().getHandle();
+
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ X11Lib.XLockDisplay(display);
try {
- NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
- X11Lib.XLockDisplay(display);
int screen = x11Screen.getIndex();
boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
@@ -154,14 +155,14 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
x11Screen);
if(null==res) {
if(usePBuffer) {
- throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig");
+ throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for "+caps2);
}
res = chooseGraphicsConfigurationXVisual((GLCapabilities) caps2,
(GLCapabilitiesChooser) chooser,
x11Screen);
}
if(null==res) {
- throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration");
+ throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig and XVisual for "+caps2);
}
if(DEBUG) {
System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationStatic("+x11Screen+","+caps2+"): "+res);
@@ -172,6 +173,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig(GLCapabilities capabilities,
GLCapabilitiesChooser chooser,
X11GraphicsScreen x11Screen) {
+ long recommendedFBConfig = 0;
int recommendedIndex = -1;
GLCapabilities[] caps = null;
PointerBuffer fbcfgsL = null;
@@ -186,37 +188,66 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
//
AbstractGraphicsDevice absDevice = x11Screen.getDevice();
long display = absDevice.getHandle();
+
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ X11Lib.XLockDisplay(display);
try {
- NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
- X11Lib.XLockDisplay(display);
int screen = x11Screen.getIndex();
boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, true, isMultisampleAvailable, display, screen);
int[] count = { -1 };
+ // determine the recommended FBConfig ..
fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0);
if (fbcfgsL == null || fbcfgsL.limit()<1) {
if(DEBUG) {
System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig ("+x11Screen+","+capabilities+"): "+fbcfgsL+", "+count[0]);
}
- return null;
+ } else if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(0) ) ) {
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: ("+x11Screen+","+capabilities+"): "+fbcfgsL+", fbcfg: "+toHexString(fbcfgsL.get(0)));
+ }
+ } else {
+ recommendedFBConfig = fbcfgsL.get(0);
}
- if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(0) ) ) {
+
+ // get all, glXChooseFBConfig(.. attribs==null ..) == glXGetFBConfig(..)
+ fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, null, 0, count, 0);
+ if (fbcfgsL == null || fbcfgsL.limit()<1) {
if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: ("+x11Screen+","+capabilities+"): "+fbcfgsL+", fbcfg: 0x"+Long.toHexString(fbcfgsL.get(0)));
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetFBConfig ("+x11Screen+"): "+fbcfgsL+", "+count[0]);
}
return null;
}
- recommendedIndex = 0; // 1st match is always recommended ..
+
+ // make GLCapabilities and seek the recommendedIndex
caps = new GLCapabilities[fbcfgsL.limit()];
for (int i = 0; i < fbcfgsL.limit(); i++) {
- caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i),
- false, onscreen, usePBuffer, isMultisampleAvailable);
+ if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) {
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid: ("+x11Screen+","+capabilities+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
+ }
+ } else {
+ caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i),
+ false, onscreen, usePBuffer, isMultisampleAvailable);
+ if(caps[i]!=null && recommendedFBConfig==fbcfgsL.get(i)) {
+ recommendedIndex=i;
+ if (DEBUG) {
+ System.err.println("!!! glXChooseFBConfig recommended "+i+", "+caps[i]);
+ }
+ }
+ }
}
if(null==chooser) {
- chosen = recommendedIndex;
- } else {
+ chosen = recommendedIndex; // may still be -1 in case nothing was recommended (-1)
+ }
+
+ if (chosen < 0) {
+ if(null==chooser) {
+ // nothing recommended .. so use our default implementation
+ chooser = new DefaultGLCapabilitiesChooser();
+ }
try {
chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex);
} catch (NativeWindowException e) {
@@ -231,9 +262,20 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
if(DEBUG) {
System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. unable to choose config, using first");
}
- chosen = 0; // default ..
+ // seek first available one ..
+ for(chosen = 0; chosen < caps.length && caps[chosen]==null; chosen++) ;
+ if(chosen==caps.length) {
+ // give up ..
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. nothing available, bail out");
+ }
+ return null;
+ }
} else if (chosen >= caps.length) {
- throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")");
+ if(DEBUG) {
+ System.err.println("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ", got "+chosen+")");
+ }
+ return null;
}
retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosen));
@@ -276,9 +318,10 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
AbstractGraphicsDevice absDevice = x11Screen.getDevice();
long display = absDevice.getHandle();
+
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ X11Lib.XLockDisplay(display);
try {
- NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
- X11Lib.XLockDisplay(display);
int screen = x11Screen.getIndex();
boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, false, isMultisampleAvailable, display, screen);
@@ -290,7 +333,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
if (recommendedVis == null) {
System.err.println("null visual");
} else {
- System.err.println("visual id 0x" + Long.toHexString(recommendedVis.getVisualid()));
+ System.err.println("visual id " + toHexString(recommendedVis.getVisualid()));
}
}
int[] count = new int[1];
@@ -326,7 +369,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")");
}
if (infos[chosen] == null) {
- throw new GLException("GLCapabilitiesChooser chose an invalid visual");
+ throw new GLException("GLCapabilitiesChooser chose an invalid visual for "+caps[chosen]);
}
retXVisualInfo = XVisualInfo.create(infos[chosen]);
} finally {
@@ -335,5 +378,14 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
}
return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], capabilities, chooser, retXVisualInfo, 0, -1);
}
+
+ public static String toHexString(int val) {
+ return "0x"+Integer.toHexString(val);
+ }
+
+ public static String toHexString(long val) {
+ return "0x"+Long.toHexString(val);
+ }
+
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java
index ea855d28d..41f012122 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java
@@ -75,9 +75,9 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable {
int screen = aScreen.getIndex();
getFactoryImpl().lockToolkit();
+ X11Lib.XLockDisplay(dpy);
try {
- X11Lib.XLockDisplay(dpy);
- pixmap = X11Lib.XCreatePixmap(dpy, (int) X11Lib.RootWindow(dpy, screen),
+ pixmap = X11Lib.XCreatePixmap(dpy, X11Lib.RootWindow(dpy, screen),
component.getWidth(), component.getHeight(), bitsPerPixel);
if (pixmap == 0) {
throw new GLException("XCreatePixmap failed");
@@ -105,10 +105,10 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable {
NativeWindow nw = getNativeWindow();
long display = nw.getDisplayHandle();
- try {
- getFactoryImpl().lockToolkit();
- X11Lib.XLockDisplay(display);
+ getFactoryImpl().lockToolkit();
+ X11Lib.XLockDisplay(display);
+ try {
long drawable = nw.getSurfaceHandle();
if (DEBUG) {
System.err.println("Destroying pixmap " + toHexString(pixmap) +
@@ -135,11 +135,11 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable {
X11Lib.XFreePixmap(display, pixmap);
drawable = 0;
pixmap = 0;
- display = 0;
((SurfaceChangeable)nw).setSurfaceHandle(0);
} finally {
X11Lib.XUnlockDisplay(display);
getFactoryImpl().unlockToolkit();
+ display = 0;
}
}
protected void swapBuffersImpl() {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java
index 63b350bd3..dc6c60664 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java
@@ -92,7 +92,7 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfiguration
try {
long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(device);
if(0==displayHandle) {
- displayHandle = X11Util.getThreadLocalDefaultDisplay();
+ displayHandle = X11Util.createThreadLocalDefaultDisplay();
if(DEBUG) {
System.err.println("X11AWTGLXGraphicsConfigurationFactory: using a thread local X11 display");
}
diff --git a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
index 8603c7184..c5ded88f6 100644
--- a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
+++ b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
@@ -89,11 +89,17 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
int windowSystemRecommendedChoice) {
GLCapabilities _desired = (GLCapabilities) desired;
GLCapabilities[] _available = (GLCapabilities[]) available;
+ int availnum = 0;
+
+ for (int i = 0; i < _available.length; i++) {
+ if(null != _available[i]) { availnum++; }
+ }
if (DEBUG) {
System.err.println("Desired: " + _desired);
+ System.err.println("Available: Valid " + availnum + "/" + _available.length);
for (int i = 0; i < _available.length; i++) {
- System.err.println("Available " + i + ": " + _available[i]);
+ System.err.println(i + ": " + _available[i]);
}
System.err.println("Window system's recommended choice: " + windowSystemRecommendedChoice);
}
@@ -132,6 +138,9 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
if (_desired.isOnscreen() != cur.isOnscreen()) {
continue;
}
+ if (_desired.isPBuffer() != cur.isPBuffer()) {
+ continue;
+ }
if (_desired.getStereo() != cur.getStereo()) {
continue;
}
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index 71cb3cb3b..80c2c10e2 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -216,6 +216,7 @@ public abstract class GLDrawableFactory {
/**
* Returns true if it is possible to create a GLPbuffer. Some older
* graphics cards do not have this capability.
+ * @param passing the device for the query, may be null
*/
public abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device);
@@ -278,6 +279,7 @@ public abstract class GLDrawableFactory {
/**
* Returns true if it is possible to create an external GLDrawable
* object via {@link #createExternalGLDrawable}.
+ * @param passing the device for the query, may be null
*/
public abstract boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device);
diff --git a/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java b/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java
index fa15e3fef..5abf02b97 100755
--- a/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java
+++ b/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java
@@ -40,6 +40,8 @@ import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.AfterClass;
+import org.junit.After;
import org.junit.Test;
import javax.media.opengl.*;
@@ -50,21 +52,29 @@ import com.jogamp.newt.opengl.*;
public class TestDrawable01NEWT {
static GLProfile glp;
+ static GLDrawableFactory factory;
static int width, height;
GLCapabilities caps;
Window window;
GLDrawable drawable;
GLContext context;
- GLDrawableFactory factory;
@BeforeClass
public static void initClass() {
glp = GLProfile.getDefault();
Assert.assertNotNull(glp);
+ factory = GLDrawableFactory.getFactory(glp);
+ Assert.assertNotNull(factory);
width = 640;
height = 480;
}
+ @AfterClass
+ public static void releaseClass() {
+ factory.shutdown();
+ factory=null;
+ }
+
@Before
public void initTest() {
caps = new GLCapabilities(glp);
@@ -106,8 +116,6 @@ public class TestDrawable01NEWT {
Assert.assertTrue(glCaps.getDoubleBuffered()==!onscreen);
Assert.assertTrue(glCaps.getDepthBits()>4);
- factory = GLDrawableFactory.getFactory(glCaps.getGLProfile());
- Assert.assertNotNull(factory);
drawable = factory.createGLDrawable(window);
Assert.assertNotNull(drawable);
// System.out.println("Pre: "+drawable);
@@ -149,10 +157,6 @@ public class TestDrawable01NEWT {
drawable = null;
context = null;
window = null;
-
- // test code cont ..
- factory.shutdown();
- factory = null;
}
@Test
@@ -174,7 +178,22 @@ public class TestDrawable01NEWT {
}
public static void main(String args[]) {
- org.junit.runner.JUnitCore.main(TestDrawable01NEWT.class.getName());
+ String tstname = TestDrawable01NEWT.class.getName();
+ try {
+ org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] {
+ tstname,
+ "filtertrace=true",
+ "haltOnError=false",
+ "haltOnFailure=false",
+ "showoutput=true",
+ "outputtoformatters=true",
+ "logfailedtests=true",
+ "logtestlistenerevents=true",
+ "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter",
+ "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } );
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
}
diff --git a/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java b/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java
index 436167dbf..e5e7c4a52 100755
--- a/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java
+++ b/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java
@@ -40,6 +40,8 @@ import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.AfterClass;
+import org.junit.After;
import org.junit.Test;
import javax.media.opengl.*;
@@ -52,48 +54,223 @@ import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears;
import com.jogamp.test.junit.jogl.demos.es1.RedSquare;
public class TestOffscreen01NEWT {
- int width, height;
- GLProfile glp;
+ static GLProfile glp;
+ static GLDrawableFactory factory;
+ static int width, height;
GLCapabilities caps;
- @Before
- public void init() {
+ @BeforeClass
+ public static void initClass() {
glp = GLProfile.getDefault();
+ Assert.assertNotNull(glp);
+ factory = GLDrawableFactory.getFactory(glp);
+ Assert.assertNotNull(factory);
width = 640;
height = 480;
+ }
+
+ @AfterClass
+ public static void releaseClass() {
+ factory.shutdown();
+ factory=null;
+ }
+
+ @Before
+ public void init() {
caps = new GLCapabilities(glp);
}
+ private void do01OffscreenWindowPBuffer(GLCapabilities caps) {
+ Display display = NewtFactory.createDisplay(null); // local display
+ Assert.assertNotNull(display);
+ Screen screen = NewtFactory.createScreen(display, 0); // screen 0
+ Assert.assertNotNull(screen);
+ Window window = NewtFactory.createWindow(screen, caps, false /* undecorated */);
+ Assert.assertNotNull(window);
+ window.setSize(width, height);
+ GLWindow glWindow = GLWindow.create(window);
+ Assert.assertNotNull(glWindow);
+ glWindow.setVisible(true);
+ GLEventListener demo = new RedSquare();
+ WindowUtilNEWT.setDemoFields(demo, window, glWindow, false);
+
+ while ( glWindow.getTotalFrames() < 2) {
+ glWindow.display();
+ }
+
+ if(null!=glWindow) {
+ glWindow.destroy();
+ }
+ if(null!=window) {
+ window.destroy();
+ }
+ if(null!=screen) {
+ screen.destroy();
+ }
+ if(null!=display) {
+ display.destroy();
+ }
+ }
+
+ @Test
+ public void test01aOffscreenWindowPBuffer() {
+ GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);
+ do01OffscreenWindowPBuffer(caps2);
+ }
+
+ @Test
+ public void test01bOffscreenWindowPBufferStencil() {
+ GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);
+ caps2.setStencilBits(8);
+ do01OffscreenWindowPBuffer(caps2);
+ }
+
@Test
- public void test01OffscreenWindow() {
+ public void test01cOffscreenWindowPBufferStencilAlpha() {
GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);
+ caps2.setStencilBits(8);
+ caps2.setAlphaBits(8);
+ do01OffscreenWindowPBuffer(caps2);
+ }
+
+ @Test
+ public void test01cOffscreenWindowPBuffer555() {
+ GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);
+ caps2.setRedBits(5);
+ caps2.setGreenBits(5);
+ caps2.setBlueBits(5);
+ do01OffscreenWindowPBuffer(caps2);
+ }
+
+ @Test
+ public void test02Offscreen3Windows1DisplayPBuffer() {
+ GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);
+ int winnum = 3, i;
+ Window windows[] = new Window[winnum];
+ GLWindow glWindows[] = new GLWindow[winnum];
+ GLEventListener demos[] = new GLEventListener[winnum];
Display display = NewtFactory.createDisplay(null); // local display
Assert.assertNotNull(display);
Screen screen = NewtFactory.createScreen(display, 0); // screen 0
Assert.assertNotNull(screen);
+
+ for(i=0; i<winnum; i++) {
+ System.out.println("Create Window "+i);
+ windows[i] = NewtFactory.createWindow(screen, caps2, false /* undecorated */);
+ Assert.assertNotNull(windows[i]);
+ windows[i].setSize(width, height);
+ glWindows[i] = GLWindow.create(windows[i]);
+ Assert.assertNotNull(glWindows[i]);
+ glWindows[i].setVisible(true);
+ demos[i] = new RedSquare();
+ WindowUtilNEWT.setDemoFields(demos[i], windows[i], glWindows[i], false);
+ }
+
+ while ( glWindows[0].getTotalFrames() < 2) {
+ for(i=0; i<winnum; i++) {
+ glWindows[i].display();
+ }
+ }
+
+ for(i=0; i<winnum; i++) {
+ if(null!=glWindows[i]) {
+ glWindows[i].destroy();
+ }
+ if(null!=windows[i]) {
+ windows[i].destroy();
+ }
+ }
+ if(null!=screen) {
+ screen.destroy();
+ }
+ if(null!=display) {
+ display.destroy();
+ }
+ }
+
+ @Test
+ public void test03Offscreen3Windows3DisplaysPBuffer() {
+ GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);
+ int winnum = 3, i;
+ Display displays[] = new Display[winnum];
+ Screen screens[] = new Screen[winnum];
+ Window windows[] = new Window[winnum];
+ GLWindow glWindows[] = new GLWindow[winnum];
+ GLEventListener demos[] = new GLEventListener[winnum];
+
+ for(i=0; i<winnum; i++) {
+ System.out.println("Create Window "+i);
+ displays[i] = NewtFactory.createDisplay(null); // local display
+ Assert.assertNotNull(displays[i]);
+ screens[i] = NewtFactory.createScreen(displays[i], 0); // screen 0
+ Assert.assertNotNull(screens[i]);
+ windows[i] = NewtFactory.createWindow(screens[i], caps2, false /* undecorated */);
+ Assert.assertNotNull(windows[i]);
+ windows[i].setSize(width, height);
+ glWindows[i] = GLWindow.create(windows[i]);
+ Assert.assertNotNull(glWindows[i]);
+ glWindows[i].setVisible(true);
+ demos[i] = new RedSquare();
+ WindowUtilNEWT.setDemoFields(demos[i], windows[i], glWindows[i], false);
+ }
+
+ while ( glWindows[0].getTotalFrames() < 2) {
+ for(i=0; i<winnum; i++) {
+ glWindows[i].display();
+ }
+ }
+
+ for(i=0; i<winnum; i++) {
+ if(null!=glWindows[i]) {
+ glWindows[i].destroy();
+ }
+ if(null!=windows[i]) {
+ windows[i].destroy();
+ }
+ if(null!=screens[i]) {
+ screens[i].destroy();
+ }
+ if(null!=displays[i]) {
+ displays[i].destroy();
+ }
+ }
+ }
+
+ @Test
+ public void test04OffscreenSnapshotWithDemoPBuffer() {
+ GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);
+
+ System.out.println("Create Window 1");
+ Display display = NewtFactory.createDisplay(null); // local display
+ Assert.assertNotNull(display);
+ Screen screen = NewtFactory.createScreen(display, 0); // screen 0
+ Assert.assertNotNull(screen);
Window window = NewtFactory.createWindow(screen, caps2, false /* undecorated */);
Assert.assertNotNull(window);
window.setSize(width, height);
- GLWindow windowOffScreen = GLWindow.create(window);
- Assert.assertNotNull(windowOffScreen);
- windowOffScreen.setVisible(true);
+ GLWindow glWindow = GLWindow.create(window);
+ Assert.assertNotNull(glWindow);
+ glWindow.setVisible(true);
GLWindow windowOnScreen = null;
WindowListener wl=null;
MouseListener ml=null;
SurfaceUpdatedListener ul=null;
- WindowUtilNEWT.run(windowOffScreen, null, windowOnScreen, wl, ml, ul, 2, false /*snapshot*/, false /*debug*/);
- try {
- Thread.sleep(1000); // 1000 ms
- } catch (Exception e) {}
+ GLEventListener demo = new RedSquare();
+ Assert.assertNotNull(demo);
+
+ WindowUtilNEWT.run(glWindow, demo, windowOnScreen, wl, ml, ul, 2, true /*snapshot*/, false /*debug*/);
if(null!=windowOnScreen) {
windowOnScreen.destroy();
}
- if(null!=windowOffScreen) {
- windowOffScreen.destroy();
+ if(null!=glWindow) {
+ glWindow.destroy();
+ }
+ if(null!=window) {
+ window.destroy();
}
if(null!=screen) {
screen.destroy();
@@ -104,8 +281,8 @@ public class TestOffscreen01NEWT {
}
@Test
- public void test02OffscreenSnapshotWithDemo() {
- GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);
+ public void test11OffscreenWindowPixmap() {
+ GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, false, false);
Display display = NewtFactory.createDisplay(null); // local display
Assert.assertNotNull(display);
@@ -114,9 +291,45 @@ public class TestOffscreen01NEWT {
Window window = NewtFactory.createWindow(screen, caps2, false /* undecorated */);
Assert.assertNotNull(window);
window.setSize(width, height);
- GLWindow windowOffScreen = GLWindow.create(window);
- Assert.assertNotNull(windowOffScreen);
- windowOffScreen.setVisible(true);
+ GLWindow glWindow = GLWindow.create(window);
+ Assert.assertNotNull(glWindow);
+ glWindow.setVisible(true);
+ GLEventListener demo = new RedSquare();
+ WindowUtilNEWT.setDemoFields(demo, window, glWindow, false);
+
+ while ( glWindow.getTotalFrames() < 2) {
+ glWindow.display();
+ }
+
+ if(null!=glWindow) {
+ glWindow.destroy();
+ }
+ if(null!=window) {
+ window.destroy();
+ }
+ if(null!=screen) {
+ screen.destroy();
+ }
+ if(null!=display) {
+ display.destroy();
+ }
+ }
+
+ @Test
+ public void test14OffscreenSnapshotWithDemoPixmap() {
+ GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, false, false);
+
+ System.out.println("Create Window 1");
+ Display display = NewtFactory.createDisplay(null); // local display
+ Assert.assertNotNull(display);
+ Screen screen = NewtFactory.createScreen(display, 0); // screen 0
+ Assert.assertNotNull(screen);
+ Window window = NewtFactory.createWindow(screen, caps2, false /* undecorated */);
+ Assert.assertNotNull(window);
+ window.setSize(width, height);
+ GLWindow glWindow = GLWindow.create(window);
+ Assert.assertNotNull(glWindow);
+ glWindow.setVisible(true);
GLWindow windowOnScreen = null;
WindowListener wl=null;
@@ -126,16 +339,16 @@ public class TestOffscreen01NEWT {
GLEventListener demo = new RedSquare();
Assert.assertNotNull(demo);
- WindowUtilNEWT.run(windowOffScreen, demo, windowOnScreen, wl, ml, ul, 2, true /*snapshot*/, false /*debug*/);
- try {
- Thread.sleep(1000); // 1000 ms
- } catch (Exception e) {}
+ WindowUtilNEWT.run(glWindow, demo, windowOnScreen, wl, ml, ul, 2, true /*snapshot*/, false /*debug*/);
if(null!=windowOnScreen) {
windowOnScreen.destroy();
}
- if(null!=windowOffScreen) {
- windowOffScreen.destroy();
+ if(null!=glWindow) {
+ glWindow.destroy();
+ }
+ if(null!=window) {
+ window.destroy();
}
if(null!=screen) {
screen.destroy();
@@ -144,7 +357,6 @@ public class TestOffscreen01NEWT {
display.destroy();
}
}
-
public static void main(String args[]) {
String tstname = TestOffscreen01NEWT.class.getName();
try {
diff --git a/src/junit/com/jogamp/test/junit/jogl/offscreen/WindowUtilNEWT.java b/src/junit/com/jogamp/test/junit/jogl/offscreen/WindowUtilNEWT.java
index f6a6dc4be..7afa7b1e5 100755
--- a/src/junit/com/jogamp/test/junit/jogl/offscreen/WindowUtilNEWT.java
+++ b/src/junit/com/jogamp/test/junit/jogl/offscreen/WindowUtilNEWT.java
@@ -52,22 +52,27 @@ public class WindowUtilNEWT {
return caps2;
}
+ public static void setDemoFields(GLEventListener demo, Window window, GLWindow glWindow, boolean debug) {
+ Assert.assertNotNull(demo);
+ Assert.assertNotNull(window);
+ if(debug) {
+ MiscUtils.setField(demo, "glDebug", new Boolean(true));
+ MiscUtils.setField(demo, "glTrace", new Boolean(true));
+ }
+ if(!MiscUtils.setField(demo, "window", window)) {
+ MiscUtils.setField(demo, "glWindow", glWindow);
+ }
+ }
+
public static void run(GLWindow windowOffScreen, GLEventListener demo,
GLWindow windowOnScreen, WindowListener wl, MouseListener ml,
SurfaceUpdatedListener ul, int frames, boolean snapshot, boolean debug) {
try {
Assert.assertNotNull(windowOffScreen);
+ Assert.assertNotNull(demo);
- if(debug && null!=demo) {
- MiscUtils.setField(demo, "glDebug", new Boolean(true));
- MiscUtils.setField(demo, "glTrace", new Boolean(true));
- }
- if(null!=demo) {
- if(!MiscUtils.setField(demo, "window", windowOffScreen)) {
- MiscUtils.setField(demo, "glWindow", windowOffScreen);
- }
- windowOffScreen.addGLEventListener(demo);
- }
+ setDemoFields(demo, windowOffScreen, windowOffScreen, debug);
+ windowOffScreen.addGLEventListener(demo);
if ( null != windowOnScreen ) {
if(null!=wl) {
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java
index 95fd6c72b..41ffccc42 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java
@@ -34,6 +34,9 @@ package com.jogamp.nativewindow.impl.x11;
import java.util.HashMap;
import java.util.Map;
+import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Iterator;
import javax.media.nativewindow.*;
@@ -41,7 +44,7 @@ import com.jogamp.nativewindow.impl.*;
/**
* Contains a thread safe X11 utility to retrieve thread local display connection,<br>
- * as well as the static global discplay connection.<br>
+ * as well as the static global display connection.<br>
*
* The TLS variant is thread safe per se, but be aware of the memory leak risk
* where an application heavily utilizing this class on temporary new threads.<br>
@@ -51,27 +54,98 @@ public class X11Util {
static {
NativeLibLoaderBase.loadNativeWindow("x11");
+ installIOErrorHandler();
}
private X11Util() {}
private static ThreadLocal currentDisplayMap = new ThreadLocal();
+ // not exactly thread safe, but good enough for our purpose,
+ // which is to tag a NamedDisplay uncloseable after creation.
+ private static Object globalLock = new Object();
+ private static Collection globalNamedDisplayActive = new ArrayList();
+ private static Collection globalNamedDisplayPassive = new ArrayList();
+
+ public static final String nullDeviceName = "nil" ;
+
public static class NamedDisplay implements Cloneable {
- private String name;
- private long handle;
+ String name;
+ long handle;
+ int refCount;
+ boolean unCloseable;
protected NamedDisplay(String name, long handle) {
this.name=name;
this.handle=handle;
+ this.refCount=1;
+ this.unCloseable=false;
}
- public String getName() { return name; }
- public long getHandle() { return handle; }
+ public final String getName() { return name; }
+ public final String getNameSafe() { return null == name ? nullDeviceName : name; }
+ public final long getHandle() { return handle; }
+ public final int getRefCount() { return refCount; }
+ public final boolean isUncloseable() { return unCloseable; }
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
+
+ public String toString() {
+ return "NamedX11Display["+name+", 0x"+Long.toHexString(handle)+", refCount "+refCount+", unCloseable "+unCloseable+"]";
+ }
+ }
+
+ /** Returns the number of unclosed X11 Displays.
+ * @param realXClosePendingDisplays if true, call XCloseDisplay on the remaining ones
+ */
+ public static int shutdown(boolean realXClosePendingDisplays, boolean verbose) {
+ int num=0;
+ String msg;
+ if(DEBUG||verbose) {
+ msg = "X11Util.Display: Shutdown (active: "+globalNamedDisplayActive.size()+
+ ", passive: "+globalNamedDisplayPassive.size() + ")";
+ if(DEBUG) {
+ Exception e = new Exception(msg);
+ e.printStackTrace();
+ } else if(verbose) {
+ System.err.println(msg);
+ }
+ }
+
+ msg = realXClosePendingDisplays ? "Close" : "Keep" ;
+
+ synchronized(globalLock) {
+ // for all passive displays ..
+ Collection namedDisplays = globalNamedDisplayPassive;
+ globalNamedDisplayPassive = new ArrayList();
+ for(Iterator iter=namedDisplays.iterator(); iter.hasNext(); ) {
+ NamedDisplay ndpy = (NamedDisplay)iter.next();
+ if(DEBUG||verbose) {
+ System.err.println(msg+" passive: "+ndpy);
+ }
+ if(realXClosePendingDisplays) {
+ X11Lib.XCloseDisplay(ndpy.getHandle());
+ }
+ num++;
+ }
+
+ // for all active displays ..
+ namedDisplays = globalNamedDisplayActive;
+ globalNamedDisplayActive = new ArrayList();
+ for(Iterator iter=namedDisplays.iterator(); iter.hasNext(); ) {
+ NamedDisplay ndpy = (NamedDisplay)iter.next();
+ if(DEBUG||verbose) {
+ System.err.println(msg+" active: "+ndpy);
+ }
+ if(realXClosePendingDisplays) {
+ X11Lib.XCloseDisplay(ndpy.getHandle());
+ }
+ num++;
+ }
+ }
+ return num;
}
/** Returns a clone of the thread local display map, you may {@link Object#wait()} on it */
@@ -79,48 +153,120 @@ public class X11Util {
return (Map) ((HashMap)getCurrentDisplayMapImpl()).clone();
}
- /** Returns this thread current default display. If it doesn not exist, it is being created */
- public static long getThreadLocalDefaultDisplay() {
- return getThreadLocalDisplay(null);
+ /** Returns this thread current default display. If it doesn not exist, it is being created, otherwise the reference count is increased */
+ public static long createThreadLocalDefaultDisplay() {
+ return createThreadLocalDisplay(null);
}
- /** Returns this thread named display. If it doesn not exist, it is being created */
- public static long getThreadLocalDisplay(String name) {
+ /** Returns this thread named display. If it doesn not exist, it is being created, otherwise the reference count is increased */
+ public static long createThreadLocalDisplay(String name) {
NamedDisplay namedDpy = getCurrentDisplay(name);
if(null==namedDpy) {
+ synchronized(globalLock) {
+ namedDpy = getNamedDisplay(globalNamedDisplayPassive, name);
+ if(null != namedDpy) {
+ if(!globalNamedDisplayPassive.remove(namedDpy)) { throw new RuntimeException("Internal: "+namedDpy); }
+ globalNamedDisplayActive.add(namedDpy);
+ addCurrentDisplay( namedDpy );
+ }
+ }
+ }
+ if(null==namedDpy) {
long dpy = X11Lib.XOpenDisplay(name);
if(0==dpy) {
throw new NativeWindowException("X11Util.Display: Unable to create a display("+name+") connection in Thread "+Thread.currentThread().getName());
}
namedDpy = new NamedDisplay(name, dpy);
- setCurrentDisplay( namedDpy );
+ synchronized(globalLock) {
+ globalNamedDisplayActive.add(namedDpy);
+ addCurrentDisplay( namedDpy );
+ }
if(DEBUG) {
- Exception e = new Exception("X11Util.Display: Created new TLS display("+name+") connection 0x"+Long.toHexString(dpy)+" in thread "+Thread.currentThread().getName());
+ Exception e = new Exception("X11Util.Display: Created new TLS "+namedDpy+" in thread "+Thread.currentThread().getName());
+ e.printStackTrace();
+ }
+ } else {
+ namedDpy.refCount++;
+ if(DEBUG) {
+ Exception e = new Exception("X11Util.Display: Reused TLS "+namedDpy+" in thread "+Thread.currentThread().getName());
e.printStackTrace();
}
}
return namedDpy.getHandle();
}
- /** Closes this thread named display. It returns the handle of the closed display or 0, if it does not exist. */
+ /** Decrease the reference count of this thread named display. If it reaches 0, close it.
+ It returns the handle of the to be closed display.
+ It throws a RuntimeException in case the named display does not exist,
+ or the reference count goes below 0.
+ */
public static long closeThreadLocalDisplay(String name) {
- NamedDisplay namedDpy = removeCurrentDisplay(name);
+ NamedDisplay namedDpy = getCurrentDisplay(name);
if(null==namedDpy) {
+ throw new RuntimeException("X11Util.Display: Display("+name+") with given handle is not mapped to TLS in thread "+Thread.currentThread().getName());
+ }
+ if(0==namedDpy.refCount) {
+ throw new RuntimeException("X11Util.Display: "+namedDpy+" has refCount already 0 in thread "+Thread.currentThread().getName());
+ }
+ long dpy = namedDpy.getHandle();
+ namedDpy.refCount--;
+ if(0==namedDpy.refCount) {
+ synchronized(globalLock) {
+ if(!globalNamedDisplayActive.remove(namedDpy)) { throw new RuntimeException("Internal: "+namedDpy); }
+ if(namedDpy.isUncloseable()) {
+ globalNamedDisplayPassive.add(namedDpy);
+ } else {
+ X11Lib.XCloseDisplay(dpy);
+ }
+ removeCurrentDisplay(namedDpy);
+ }
if(DEBUG) {
- Exception e = new Exception("X11Util.Display: Display("+name+") with given handle is not mapped to TLS in thread "+Thread.currentThread().getName());
+ String type = namedDpy.isUncloseable() ? "passive" : "real" ;
+ Exception e = new Exception("X11Util.Display: Closing ( "+type+" ) TLS "+namedDpy+" in thread "+Thread.currentThread().getName());
e.printStackTrace();
}
- return 0;
- }
- long dpy = namedDpy.getHandle();
- if(DEBUG) {
- Exception e = new Exception("X11Util.Display: Closing TLS Display("+name+") with handle 0x"+Long.toHexString(dpy)+" in thread "+Thread.currentThread().getName());
+ } else if(DEBUG) {
+ Exception e = new Exception("X11Util.Display: Keep TLS "+namedDpy+" in thread "+Thread.currentThread().getName());
e.printStackTrace();
}
- X11Lib.XCloseDisplay(dpy);
return dpy;
}
+ public static String getThreadLocalDisplayName(long handle) {
+ NamedDisplay ndpy = getNamedDisplay(getCurrentDisplayMapImpl().values(), handle);
+ return null != ndpy ? ndpy.getName() : null;
+ }
+
+ public static boolean markThreadLocalDisplayUndeletable(long handle) {
+ NamedDisplay ndpy = getNamedDisplay(getCurrentDisplayMapImpl().values(), handle);
+ if( null != ndpy ) {
+ ndpy.unCloseable=true;
+ return true;
+ }
+ return false;
+ }
+
+ public static String getGlobalDisplayName(long handle, boolean active) {
+ String name;
+ synchronized(globalLock) {
+ NamedDisplay ndpy = getNamedDisplay(active ? globalNamedDisplayActive : globalNamedDisplayPassive, handle);
+ name = null != ndpy ? ndpy.getName() : null;
+ }
+ return name;
+ }
+
+ public static boolean markGlobalDisplayUndeletable(long handle) {
+ boolean r=false;
+ synchronized(globalLock) {
+ NamedDisplay ndpy = getNamedDisplay(globalNamedDisplayActive, handle);
+ if( null != ndpy ) {
+ ndpy.unCloseable=true;
+ r=true;
+ }
+ }
+ return r;
+ }
+
private static Map getCurrentDisplayMapImpl() {
Map displayMap = (Map) currentDisplayMap.get();
if(null==displayMap) {
@@ -132,12 +278,11 @@ public class X11Util {
/** maps the given display to the thread local display map
* and notifies all threads synchronized to this display map. */
- private static NamedDisplay setCurrentDisplay(NamedDisplay newDisplay) {
+ private static NamedDisplay addCurrentDisplay(NamedDisplay newDisplay) {
Map displayMap = getCurrentDisplayMapImpl();
NamedDisplay oldDisplay = null;
synchronized(displayMap) {
- String name = (null==newDisplay.getName())?"nil":newDisplay.getName();
- oldDisplay = (NamedDisplay) displayMap.put(name, newDisplay);
+ oldDisplay = (NamedDisplay) displayMap.put(newDisplay.getNameSafe(), newDisplay);
displayMap.notifyAll();
}
return oldDisplay;
@@ -145,22 +290,45 @@ public class X11Util {
/** removes the mapping of the given name from the thread local display map
* and notifies all threads synchronized to this display map. */
- private static NamedDisplay removeCurrentDisplay(String name) {
+ private static NamedDisplay removeCurrentDisplay(NamedDisplay ndpy) {
Map displayMap = getCurrentDisplayMapImpl();
- NamedDisplay oldDisplay = null;
synchronized(displayMap) {
- if(null==name) name="nil";
- oldDisplay = (NamedDisplay) displayMap.remove(name);
+ NamedDisplay ndpyDel = (NamedDisplay) displayMap.remove(ndpy.getNameSafe());
+ if(ndpyDel!=ndpy) {
+ throw new RuntimeException("Wrong mapping req: "+ndpy+", got "+ndpyDel);
+ }
displayMap.notifyAll();
}
- return oldDisplay;
+ return ndpy;
}
/** Returns the thread local display mapped to the given name */
private static NamedDisplay getCurrentDisplay(String name) {
- if(null==name) name="nil";
+ if(null==name) name=nullDeviceName;
Map displayMap = getCurrentDisplayMapImpl();
return (NamedDisplay) displayMap.get(name);
}
+ private static NamedDisplay getNamedDisplay(Collection namedDisplays, String name) {
+ if(null==name) name=nullDeviceName;
+ for(Iterator iter=namedDisplays.iterator(); iter.hasNext(); ) {
+ NamedDisplay ndpy = (NamedDisplay)iter.next();
+ if (ndpy.getNameSafe().equals(name)) {
+ return ndpy;
+ }
+ }
+ return null;
+ }
+
+ private static NamedDisplay getNamedDisplay(Collection namedDisplays, long handle) {
+ for(Iterator iter=namedDisplays.iterator(); iter.hasNext(); ) {
+ NamedDisplay ndpy = (NamedDisplay)iter.next();
+ if (ndpy.getHandle()==handle) {
+ return ndpy;
+ }
+ }
+ return null;
+ }
+
+ private static native void installIOErrorHandler();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
index 52f48660a..69ace3c52 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
@@ -57,7 +57,7 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
/** Creates a new X11GraphicsScreen using a thread local display connection */
public static AbstractGraphicsScreen createDefault() {
NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
- long display = X11Util.getThreadLocalDefaultDisplay();
+ long display = X11Util.createThreadLocalDefaultDisplay();
try {
X11Lib.XLockDisplay(display);
int scrnIdx = X11Lib.DefaultScreen(display);
diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c
new file mode 100644
index 000000000..4320a8f12
--- /dev/null
+++ b/src/nativewindow/native/x11/Xmisc.c
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 2010 Sven Gothel. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name Sven Gothel or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+/* Linux headers don't work properly */
+#define __USE_GNU
+#include <dlfcn.h>
+#undef __USE_GNU
+
+/* Current versions of Solaris don't expose the XF86 extensions,
+ although with the recent transition to Xorg this will probably
+ happen in an upcoming release */
+#if !defined(__sun) && !defined(_HPUX)
+#include <X11/extensions/xf86vmode.h>
+#else
+/* Need to provide stubs for these */
+Bool XF86VidModeGetGammaRampSize(
+ Display *display,
+ int screen,
+ int* size)
+{
+ return False;
+}
+
+Bool XF86VidModeGetGammaRamp(
+ Display *display,
+ int screen,
+ int size,
+ unsigned short *red_array,
+ unsigned short *green_array,
+ unsigned short *blue_array) {
+ return False;
+}
+Bool XF86VidModeSetGammaRamp(
+ Display *display,
+ int screen,
+ int size,
+ unsigned short *red_array,
+ unsigned short *green_array,
+ unsigned short *blue_array) {
+ return False;
+}
+#endif /* defined(__sun) || defined(_HPUX) */
+
+/* HP-UX doesn't define RTLD_DEFAULT. */
+#if defined(_HPUX) && !defined(RTLD_DEFAULT)
+#define RTLD_DEFAULT NULL
+#endif
+
+#include "com_jogamp_nativewindow_impl_x11_X11Lib.h"
+
+// #define VERBOSE_ON 1
+
+#ifdef VERBOSE_ON
+ // Workaround for ancient compiler on Solaris/SPARC
+ // #define DBG_PRINT(args...) fprintf(stderr, args);
+ #define DBG_PRINT0(str) fprintf(stderr, str);
+ #define DBG_PRINT1(str, arg1) fprintf(stderr, str, arg1);
+ #define DBG_PRINT2(str, arg1, arg2) fprintf(stderr, str, arg1, arg2);
+ #define DBG_PRINT3(str, arg1, arg2, arg3) fprintf(stderr, str, arg1, arg2, arg3);
+ #define DBG_PRINT4(str, arg1, arg2, arg3, arg4) fprintf(stderr, str, arg1, arg2, arg3, arg4);
+ #define DBG_PRINT5(str, arg1, arg2, arg3, arg4, arg5) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5);
+ #define DBG_PRINT6(str, arg1, arg2, arg3, arg4, arg5, arg6) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6);
+ #define DBG_PRINT7(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+ #define DBG_PRINT8(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+
+#else
+
+ // Workaround for ancient compiler on Solaris/SPARC
+ // #define DBG_PRINT(args...)
+ #define DBG_PRINT0(str)
+ #define DBG_PRINT1(str, arg1)
+ #define DBG_PRINT2(str, arg1, arg2)
+ #define DBG_PRINT3(str, arg1, arg2, arg3)
+ #define DBG_PRINT4(str, arg1, arg2, arg3, arg4)
+ #define DBG_PRINT5(str, arg1, arg2, arg3, arg4, arg5)
+ #define DBG_PRINT6(str, arg1, arg2, arg3, arg4, arg5, arg6)
+ #define DBG_PRINT7(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+ #define DBG_PRINT8(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
+
+#endif
+
+/* Need to pull this in as we don't have a stub header for it */
+extern Bool XineramaEnabled(Display* display);
+
+static void _FatalError(JNIEnv *env, const char* msg, ...)
+{
+ char buffer[512];
+ va_list ap;
+
+ va_start(ap, msg);
+ vsnprintf(buffer, sizeof(buffer), msg, ap);
+ va_end(ap);
+
+ fprintf(stderr, buffer);
+ (*env)->FatalError(env, buffer);
+}
+
+static const char * const ClazzNameInternalBufferUtil = "com/jogamp/nativewindow/impl/InternalBufferUtil";
+static const char * const ClazzNameInternalBufferUtilStaticCstrName = "copyByteBuffer";
+static const char * const ClazzNameInternalBufferUtilStaticCstrSignature = "(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;";
+static const char * const ClazzNameByteBuffer = "java/nio/ByteBuffer";
+static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException";
+static jclass clazzInternalBufferUtil = NULL;
+static jmethodID cstrInternalBufferUtil = NULL;
+static jclass clazzByteBuffer = NULL;
+static jclass clazzRuntimeException=NULL;
+
+static void _initClazzAccess(JNIEnv *env) {
+ jclass c;
+
+ if(NULL!=clazzRuntimeException) return ;
+
+ c = (*env)->FindClass(env, ClazzNameRuntimeException);
+ if(NULL==c) {
+ _FatalError(env, "Nativewindow X11Lib: can't find %s", ClazzNameRuntimeException);
+ }
+ clazzRuntimeException = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==clazzRuntimeException) {
+ _FatalError(env, "FatalError: NEWT X11Window: can't use %s", ClazzNameRuntimeException);
+ }
+
+ c = (*env)->FindClass(env, ClazzNameInternalBufferUtil);
+ if(NULL==c) {
+ _FatalError(env, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNameInternalBufferUtil);
+ }
+ clazzInternalBufferUtil = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==clazzInternalBufferUtil) {
+ _FatalError(env, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNameInternalBufferUtil);
+ }
+ c = (*env)->FindClass(env, ClazzNameByteBuffer);
+ if(NULL==c) {
+ _FatalError(env, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNameByteBuffer);
+ }
+ clazzByteBuffer = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==c) {
+ _FatalError(env, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNameByteBuffer);
+ }
+
+ cstrInternalBufferUtil = (*env)->GetStaticMethodID(env, clazzInternalBufferUtil,
+ ClazzNameInternalBufferUtilStaticCstrName, ClazzNameInternalBufferUtilStaticCstrSignature);
+ if(NULL==cstrInternalBufferUtil) {
+ _FatalError(env, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib:: can't create %s.%s %s",
+ ClazzNameInternalBufferUtil, ClazzNameInternalBufferUtilStaticCstrName, ClazzNameInternalBufferUtilStaticCstrSignature);
+ }
+}
+
+static void _throwNewRuntimeException(Display * unlockDisplay, JNIEnv *env, const char* msg, ...)
+{
+ char buffer[512];
+ va_list ap;
+
+ if(NULL!=unlockDisplay) {
+ XUnlockDisplay(unlockDisplay);
+ }
+
+ _initClazzAccess(env);
+
+ va_start(ap, msg);
+ vsnprintf(buffer, sizeof(buffer), msg, ap);
+ va_end(ap);
+
+ (*env)->ThrowNew(env, clazzRuntimeException, buffer);
+}
+
+static XIOErrorHandler origIOErrorHandler = NULL;
+static JNIEnv * displayIOErrorHandlerJNIEnv = NULL;
+
+static int displayIOErrorHandler(Display *dpy)
+{
+ _FatalError(displayIOErrorHandlerJNIEnv, "Nativewindow X11 IOError: Display %p not available", dpy);
+ origIOErrorHandler(dpy);
+ return 0;
+}
+
+static void displayIOErrorHandlerEnable(int onoff, JNIEnv * env) {
+ if(onoff) {
+ if(NULL==origIOErrorHandler) {
+ displayIOErrorHandlerJNIEnv = env;
+ origIOErrorHandler = XSetIOErrorHandler(displayIOErrorHandler);
+ }
+ } else {
+ XSetIOErrorHandler(origIOErrorHandler);
+ origIOErrorHandler = NULL;
+ displayIOErrorHandlerJNIEnv = NULL;
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_com_jogamp_nativewindow_impl_x11_X11Util_installIOErrorHandler(JNIEnv *env, jclass _unused) {
+ displayIOErrorHandlerEnable(1, env);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_jogamp_nativewindow_impl_x11_X11Lib_dlopen(JNIEnv *env, jclass _unused, jstring name) {
+ const jbyte* chars;
+ void* res;
+ chars = (*env)->GetStringUTFChars(env, name, NULL);
+ res = dlopen(chars, RTLD_LAZY | RTLD_GLOBAL);
+ (*env)->ReleaseStringUTFChars(env, name, chars);
+ return (jlong) ((intptr_t) res);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_jogamp_nativewindow_impl_x11_X11Lib_dlsym(JNIEnv *env, jclass _unused, jstring name) {
+ const jbyte* chars;
+ void* res;
+ chars = (*env)->GetStringUTFChars(env, name, NULL);
+ res = dlsym(RTLD_DEFAULT, chars);
+ (*env)->ReleaseStringUTFChars(env, name, chars);
+ return (jlong) ((intptr_t) res);
+}
+
+/* Java->C glue code:
+ * Java package: com.jogamp.nativewindow.impl.x11.X11Lib
+ * Java method: XVisualInfo XGetVisualInfo(long arg0, long arg1, XVisualInfo arg2, java.nio.IntBuffer arg3)
+ * C function: XVisualInfo * XGetVisualInfo(Display * , long, XVisualInfo * , int * );
+ */
+JNIEXPORT jobject JNICALL
+Java_com_jogamp_nativewindow_impl_x11_X11Lib_XGetVisualInfoCopied1__JJLjava_nio_ByteBuffer_2Ljava_lang_Object_2I(JNIEnv *env, jclass _unused, jlong arg0, jlong arg1, jobject arg2, jobject arg3, jint arg3_byte_offset) {
+ XVisualInfo * _ptr2 = NULL;
+ int * _ptr3 = NULL;
+ XVisualInfo * _res;
+ int count;
+ jobject jbyteSource;
+ jobject jbyteCopy;
+ if(0==arg0) {
+ _FatalError(env, "invalid display connection..");
+ }
+ if (arg2 != NULL) {
+ _ptr2 = (XVisualInfo *) (((char*) (*env)->GetDirectBufferAddress(env, arg2)) + 0);
+ }
+ if (arg3 != NULL) {
+ _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, arg3, NULL)) + arg3_byte_offset);
+ }
+ _res = XGetVisualInfo((Display *) (intptr_t) arg0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3);
+ count = _ptr3[0];
+ if (arg3 != NULL) {
+ (*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0);
+ }
+ if (_res == NULL) return NULL;
+
+ _initClazzAccess(env);
+
+ jbyteSource = (*env)->NewDirectByteBuffer(env, _res, count * sizeof(XVisualInfo));
+ jbyteCopy = (*env)->CallStaticObjectMethod(env,
+ clazzInternalBufferUtil, cstrInternalBufferUtil, jbyteSource);
+
+ XFree(_res);
+
+ return jbyteCopy;
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_jogamp_nativewindow_impl_x11_X11Lib_DefaultVisualID(JNIEnv *env, jclass _unused, jlong display, jint screen) {
+ jlong r;
+ if(0==display) {
+ _FatalError(env, "invalid display connection..");
+ }
+ r = (jlong) XVisualIDFromVisual( DefaultVisual( (Display*) (intptr_t) display, screen ) );
+ return r;
+}
+
+/* Java->C glue code:
+ * Java package: com.jogamp.nativewindow.impl.x11.X11Lib
+ * Java method: void XLockDisplay(long display)
+ * C function: void XLockDisplay(Display * display);
+ */
+JNIEXPORT void JNICALL
+Java_com_jogamp_nativewindow_impl_x11_X11Lib_XLockDisplay__J(JNIEnv *env, jclass _unused, jlong display) {
+ if(0==display) {
+ _FatalError(env, "invalid display connection..");
+ }
+ XLockDisplay((Display *) (intptr_t) display);
+}
+
+/* Java->C glue code:
+ * Java package: com.jogamp.nativewindow.impl.x11.X11Lib
+ * Java method: void XUnlockDisplay(long display)
+ * C function: void XUnlockDisplay(Display * display);
+ */
+JNIEXPORT void JNICALL
+Java_com_jogamp_nativewindow_impl_x11_X11Lib_XUnlockDisplay__J(JNIEnv *env, jclass _unused, jlong display) {
+ if(0==display) {
+ _FatalError(env, "invalid display connection..");
+ }
+ XUnlockDisplay((Display *) (intptr_t) display);
+}
+
+
+/* Java->C glue code:
+ * Java package: com.jogamp.nativewindow.impl.x11.X11Lib
+ * Java method: int XCloseDisplay(long display)
+ * C function: int XCloseDisplay(Display * display);
+ */
+JNIEXPORT jint JNICALL
+Java_com_jogamp_nativewindow_impl_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclass _unused, jlong display) {
+ int _res;
+ if(0==display) {
+ _FatalError(env, "invalid display connection..");
+ }
+ _res = XCloseDisplay((Display *) (intptr_t) display);
+ return _res;
+}
+
+/*
+ * Class: com_jogamp_nativewindow_impl_x11_X11Lib
+ * Method: CreateDummyWindow
+ * Signature: (JIJ)J
+JNIEXPORT jlong JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_CreateDummyWindow
+ (JNIEnv *env, jobject obj, jlong display, jint screen_index, jlong visualID)
+{
+ Display * dpy = (Display *)(intptr_t)display;
+ int scrn_idx = (int)screen_index;
+ Window windowParent = 0;
+ Window window = 0;
+
+ XVisualInfo visualTemplate;
+ XVisualInfo *pVisualQuery = NULL;
+ Visual *visual = NULL;
+ int depth;
+
+ XSetWindowAttributes xswa;
+ unsigned long attrMask;
+ int n;
+
+ Screen* scrn;
+
+ if(NULL==dpy) {
+ _FatalError(env, "invalid display connection..");
+ return 0;
+ }
+
+ if(visualID<0) {
+ _throwNewRuntimeException(NULL, env, "invalid VisualID ..\n");
+ return 0;
+ }
+
+ XLockDisplay(dpy) ;
+
+ XSync(dpy, False);
+
+ scrn = ScreenOfDisplay(dpy, scrn_idx);
+
+ // try given VisualID on screen
+ memset(&visualTemplate, 0, sizeof(XVisualInfo));
+ visualTemplate.screen = scrn_idx;
+ visualTemplate.visualid = (VisualID)visualID;
+ pVisualQuery = XGetVisualInfo(dpy, VisualIDMask|VisualScreenMask, &visualTemplate,&n);
+ if(pVisualQuery!=NULL) {
+ visual = pVisualQuery->visual;
+ depth = pVisualQuery->depth;
+ visualID = (jlong)pVisualQuery->visualid;
+ XFree(pVisualQuery);
+ pVisualQuery=NULL;
+ }
+ DBG_PRINT5( "X11: [CreateWindow] trying given (dpy %p, screen %d, visualID: %d, parent %p) found: %p\n", dpy, scrn_idx, (int)visualID, windowParent, visual);
+
+ if (visual==NULL)
+ {
+ _throwNewRuntimeException(dpy, env, "could not query Visual by given VisualID, bail out!\n");
+ return 0;
+ }
+
+ if(pVisualQuery!=NULL) {
+ XFree(pVisualQuery);
+ pVisualQuery=NULL;
+ }
+
+ if(0==windowParent) {
+ windowParent = XRootWindowOfScreen(scrn);
+ }
+
+ attrMask = (CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect) ;
+
+ memset(&xswa, 0, sizeof(xswa));
+ xswa.override_redirect = True; // not decorated
+ xswa.border_pixel = 0;
+ xswa.background_pixel = 0;
+ xswa.event_mask = 0 ; // no events
+ xswa.colormap = XCreateColormap(dpy,
+ XRootWindow(dpy, scrn_idx),
+ visual,
+ AllocNone);
+
+ window = XCreateWindow(dpy,
+ windowParent,
+ 0, 0,
+ 64, 64,
+ 0, // border width
+ depth,
+ InputOutput,
+ visual,
+ attrMask,
+ &xswa);
+
+ XSync(dpy, False);
+
+ XUnlockDisplay(dpy) ;
+
+ DBG_PRINT2( "X11: [CreateWindow] created window %p on display %p\n", window, dpy);
+
+ return (jlong) window;
+}
+ */
+
+
+/*
+ * Class: com_jogamp_nativewindow_impl_x11_X11Lib
+ * Method: DestroyDummyWindow
+ * Signature: (JJ)V
+JNIEXPORT void JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_DestroyDummyWindow
+ (JNIEnv *env, jobject obj, jlong display, jlong window)
+{
+ Display * dpy = (Display *)(intptr_t)display;
+ Window w = (Window) window;
+
+ if(NULL==dpy) {
+ _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
+ return;
+ }
+ XLockDisplay(dpy) ;
+
+ XSync(dpy, False);
+ XUnmapWindow(dpy, w);
+ XSync(dpy, False);
+ XDestroyWindow(dpy, w);
+ XSync(dpy, False);
+
+ XUnlockDisplay(dpy) ;
+}
+ */
+
diff --git a/src/newt/classes/com/jogamp/newt/x11/X11Display.java b/src/newt/classes/com/jogamp/newt/x11/X11Display.java
index b8eb80b39..5fd6d9640 100755
--- a/src/newt/classes/com/jogamp/newt/x11/X11Display.java
+++ b/src/newt/classes/com/jogamp/newt/x11/X11Display.java
@@ -61,7 +61,7 @@ public class X11Display extends Display {
}
protected void createNative() {
- long handle= X11Util.getThreadLocalDisplay(name);
+ long handle= X11Util.createThreadLocalDisplay(name);
if (handle == 0 ) {
throw new RuntimeException("Error creating display: "+name);
}
@@ -75,9 +75,7 @@ public class X11Display extends Display {
}
protected void closeNative() {
- if(0==X11Util.closeThreadLocalDisplay(name)) {
- throw new NativeWindowException(this+" was not mapped");
- }
+ X11Util.closeThreadLocalDisplay(name);
}
protected void dispatchMessages() {
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 0fccc94bb..33c5324e2 100755
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -149,6 +149,19 @@ static jint X11KeySym2NewtVKey(KeySym keySym) {
return keySym;
}
+static void _FatalError(JNIEnv *env, const char* msg, ...)
+{
+ char buffer[512];
+ va_list ap;
+
+ va_start(ap, msg);
+ vsnprintf(buffer, sizeof(buffer), msg, ap);
+ va_end(ap);
+
+ fprintf(stderr, buffer);
+ (*env)->FatalError(env, buffer);
+}
+
static const char * const ClazzNameRuntimeException =
"java/lang/RuntimeException";
static jclass runtimeExceptionClz=NULL;
@@ -217,26 +230,6 @@ static void displayDispatchErrorHandlerEnable(int onoff) {
}
}
-static XIOErrorHandler origIOErrorHandler = NULL;
-
-static int displayDispatchIOErrorHandler(Display *dpy)
-{
- fprintf(stderr, "Fatal: NEWT X11 IOError: Display %p not available\n", dpy);
- return 0;
-}
-
-static void displayDispatchIOErrorHandlerEnable(int onoff) {
- if(onoff) {
- if(NULL==origIOErrorHandler) {
- origIOErrorHandler = XSetIOErrorHandler(displayDispatchIOErrorHandler);
- }
- } else {
- XSetIOErrorHandler(origIOErrorHandler);
- origIOErrorHandler = NULL;
- }
-}
-
-
/*
* Class: com_jogamp_newt_x11_X11Display
* Method: initIDs
@@ -259,28 +252,24 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_x11_X11Display_initIDs
if(NULL==newtWindowClz) {
c = (*env)->FindClass(env, ClazzNameNewtWindow);
if(NULL==c) {
- fprintf(stderr, "FatalError: NEWT X11Window: can't find %s\n", ClazzNameNewtWindow);
- return JNI_FALSE;
+ _FatalError(env, "NEWT X11Window: can't find %s", ClazzNameNewtWindow);
}
newtWindowClz = (jclass)(*env)->NewGlobalRef(env, c);
(*env)->DeleteLocalRef(env, c);
if(NULL==newtWindowClz) {
- fprintf(stderr, "FatalError: NEWT X11Window: can't use %s\n", ClazzNameNewtWindow);
- return JNI_FALSE;
+ _FatalError(env, "NEWT X11Window: can't use %s", ClazzNameNewtWindow);
}
}
if(NULL==runtimeExceptionClz) {
c = (*env)->FindClass(env, ClazzNameRuntimeException);
if(NULL==c) {
- fprintf(stderr, "FatalError: NEWT X11Window: can't find %s\n", ClazzNameRuntimeException);
- return JNI_FALSE;
+ _FatalError(env, "NEWT X11Window: can't find %s", ClazzNameRuntimeException);
}
runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c);
(*env)->DeleteLocalRef(env, c);
if(NULL==runtimeExceptionClz) {
- fprintf(stderr, "FatalError: NEWT X11Window: can't use %s\n", ClazzNameRuntimeException);
- return JNI_FALSE;
+ _FatalError(env, "NEWT X11Window: can't use %s", ClazzNameRuntimeException);
}
}
@@ -297,7 +286,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Display_LockDisplay
{
Display * dpy = (Display *)(intptr_t)display;
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "given display connection is NULL\n");
+ _FatalError(env, "invalid display connection..");
}
XLockDisplay(dpy) ;
DBG_PRINT1( "X11: LockDisplay 0x%X\n", dpy);
@@ -314,7 +303,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Display_UnlockDisplay
{
Display * dpy = (Display *)(intptr_t)display;
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "given display connection is NULL\n");
+ _FatalError(env, "invalid display connection..");
}
XUnlockDisplay(dpy) ;
DBG_PRINT1( "X11: UnlockDisplay 0x%X\n", dpy);
@@ -334,7 +323,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Display_CompleteDisplay
jlong windowDeleteAtom;
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "given display connection is NULL\n");
+ _FatalError(env, "invalid display connection..");
}
XLockDisplay(dpy) ;
@@ -447,8 +436,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Display_DispatchMessages
return;
}
- displayDispatchIOErrorHandlerEnable(1);
-
// Periodically take a break
while( num_events > 0 ) {
jobject jwindow = NULL;
@@ -462,7 +449,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Display_DispatchMessages
// num_events = XPending(dpy); // XEventsQueued(dpy, QueuedAfterFlush); // I/O Flush ..
// num_events = XEventsQueued(dpy, QueuedAlready); // Better, no I/O ..
if ( 0 >= XEventsQueued(dpy, QueuedAlready) ) {
- displayDispatchIOErrorHandlerEnable(0);
XUnlockDisplay(dpy) ;
return;
}
@@ -470,8 +456,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Display_DispatchMessages
XNextEvent(dpy, &evt);
num_events--;
- displayDispatchIOErrorHandlerEnable(0);
-
if( 0==evt.xany.window ) {
_throwNewRuntimeException(dpy, env, "event window NULL, bail out!\n");
return ;
@@ -606,8 +590,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_x11_X11Screen_GetScreen
Screen * scrn= NULL;
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
- return 0;
+ _FatalError(env, "invalid display connection..");
}
XLockDisplay(dpy);
@@ -698,8 +681,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_x11_X11Window_CreateWindow
DBG_PRINT4( "X11: CreateWindow %x/%d %dx%d\n", x, y, width, height);
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
- return 0;
+ _FatalError(env, "invalid display connection..");
}
if(visualID<0) {
@@ -711,7 +693,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_x11_X11Window_CreateWindow
XSync(dpy, False);
- scrn = ScreenOfDisplay(dpy, screen_index);
+ scrn = ScreenOfDisplay(dpy, scrn_idx);
// try given VisualID on screen
memset(&visualTemplate, 0, sizeof(XVisualInfo));
@@ -809,8 +791,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Window_CloseWindow
jobject jwindow;
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
- return;
+ _FatalError(env, "invalid display connection..");
}
XLockDisplay(dpy) ;
@@ -854,8 +835,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Window_setVisible0
DBG_PRINT1( "X11: setVisible0 vis %d\n", visible);
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
- return;
+ _FatalError(env, "invalid display connection..");
}
XLockDisplay(dpy) ;
@@ -903,8 +883,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Window_setSize0
DBG_PRINT6( "X11: setSize0 %d/%d %dx%d, dec %d, vis %d\n", x, y, width, height, decorationToggle, setVisible);
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
- return;
+ _FatalError(env, "invalid display connection..");
}
XLockDisplay(dpy) ;
@@ -963,8 +942,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Window_setPosition0
DBG_PRINT2( "X11: setPos0 . XConfigureWindow %d/%d\n", x, y);
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
- return;
+ _FatalError(env, "invalid display connection..");
}
XLockDisplay(dpy) ;