diff options
-rw-r--r-- | make/config/jogl/glx-CustomCCode.c | 63 | ||||
-rw-r--r-- | make/config/jogl/glx-CustomJavaCode.java | 19 | ||||
-rw-r--r-- | make/config/jogl/glx-x11.cfg | 2 | ||||
-rw-r--r-- | make/config/jogl/glxext.cfg | 2 | ||||
-rw-r--r-- | src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java | 39 | ||||
-rw-r--r-- | src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java | 8 |
6 files changed, 122 insertions, 11 deletions
diff --git a/make/config/jogl/glx-CustomCCode.c b/make/config/jogl/glx-CustomCCode.c index 5c73dfea6..3f5cf1121 100644 --- a/make/config/jogl/glx-CustomCCode.c +++ b/make/config/jogl/glx-CustomCCode.c @@ -12,6 +12,8 @@ #define RTLD_DEFAULT NULL #endif +#include <string.h> + /* We expect glXGetProcAddressARB to be defined */ extern void (*glXGetProcAddressARB(const GLubyte *procname))(); @@ -124,7 +126,7 @@ Java_jogamp_opengl_x11_glx_GLX_dispatch_1glXChooseFBConfig(JNIEnv *env, jclass _ int * _attribList_ptr = NULL; int * _nitems_ptr = NULL; GLXFBConfig * _res; - int count; + int count, i; jobject jbyteSource; jobject jbyteCopy; if ( NULL != attribList ) { @@ -139,6 +141,65 @@ Java_jogamp_opengl_x11_glx_GLX_dispatch_1glXChooseFBConfig(JNIEnv *env, jclass _ count = _nitems_ptr[0]; if (NULL == _res) return NULL; + /** Bug 961: Validate returned 'GLXFBConfig *', i.e. remove NULL pointer. */ + // fprintf(stderr, "glXChooseFBConfig.0: Count %d\n", count); + i=0; + while( i < count ) { + if( NULL == _res[i] ) { + if( 0 < count-i-1 ) { + memmove(_res+i, _res+i+1, count-i-1); + } + count--; + } else { + i++; + } + } + // fprintf(stderr, "glXChooseFBConfig.X: Count %d\n", count); + _initClazzAccess(env); + + jbyteSource = (*env)->NewDirectByteBuffer(env, _res, count * sizeof(GLXFBConfig)); + jbyteCopy = (*env)->CallStaticObjectMethod(env, clazzBuffers, cstrBuffers, jbyteSource); + (*env)->DeleteLocalRef(env, jbyteSource); + XFree(_res); + + return jbyteCopy; +} + +/* Java->C glue code: + * Java package: jogamp.opengl.x11.glx.GLX + * Java method: com.jogamp.common.nio.PointerBuffer dispatch_glXGetFBConfigs(long dpy, int screen, java.nio.IntBuffer nelements) + * C function: GLXFBConfig * glXGetFBConfigs(Display * dpy, int screen, int * nelements); + */ +JNIEXPORT jobject JNICALL +Java_jogamp_opengl_x11_glx_GLX_dispatch_1glXGetFBConfigs(JNIEnv *env, jclass _unused, jlong dpy, jint screen, jobject nelements, jint nelements_byte_offset, jlong procAddress) { + typedef GLXFBConfig * (APIENTRY*_local_PFNGLXGETFBCONFIGSPROC)(Display * dpy, int screen, int * nelements); + _local_PFNGLXGETFBCONFIGSPROC ptr_glXGetFBConfigs; + int * _nelements_ptr = NULL; + GLXFBConfig * _res; + int count, i; + jobject jbyteSource; + jobject jbyteCopy; + if ( NULL != nelements ) { + _nelements_ptr = (int *) (((char*) (*env)->GetDirectBufferAddress(env, nelements)) + nelements_byte_offset); + } + ptr_glXGetFBConfigs = (_local_PFNGLXGETFBCONFIGSPROC) (intptr_t) procAddress; + assert(ptr_glXGetFBConfigs != NULL); + _res = (* ptr_glXGetFBConfigs) ((Display *) (intptr_t) dpy, (int) screen, (int *) _nelements_ptr); + count = _nelements_ptr[0]; + if (NULL == _res) return NULL; + + /** Bug 961: Validate returned 'GLXFBConfig *', i.e. remove NULL pointer. */ + i=0; + while( i < count ) { + if( NULL == _res[i] ) { + if( 0 < count-i-1 ) { + memmove(_res+i, _res+i+1, count-i-1); + } + count--; + } else { + i++; + } + } _initClazzAccess(env); jbyteSource = (*env)->NewDirectByteBuffer(env, _res, count * sizeof(GLXFBConfig)); diff --git a/make/config/jogl/glx-CustomJavaCode.java b/make/config/jogl/glx-CustomJavaCode.java index 4cce05dda..5a3ea392b 100644 --- a/make/config/jogl/glx-CustomJavaCode.java +++ b/make/config/jogl/glx-CustomJavaCode.java @@ -60,6 +60,25 @@ @param nitems a direct only {@link java.nio.IntBuffer} */ private static native ByteBuffer dispatch_glXChooseFBConfig(long dpy, int screen, Object attribList, int attribList_byte_offset, Object nitems, int nitems_byte_offset, long procAddress); + /** Entry point to C language function: <code> GLXFBConfig * glXGetFBConfigs(Display * dpy, int screen, int * nelements); </code> <br>Part of <code>GLX_VERSION_1_3</code> + @param nelements a direct only {@link java.nio.IntBuffer} */ + public static PointerBuffer glXGetFBConfigs(long dpy, int screen, IntBuffer nelements) { + + if (!Buffers.isDirect(nelements)) + throw new GLException("Argument \"nelements\" is not a direct buffer"); + final long __addr_ = glxProcAddressTable._addressof_glXGetFBConfigs; + if (__addr_ == 0) { + throw new GLException(String.format("Method \"%s\" not available", "glXGetFBConfigs")); + } + final ByteBuffer _res = dispatch_glXGetFBConfigs(dpy, screen, nelements, Buffers.getDirectBufferByteOffset(nelements), __addr_); + if (_res == null) return null; + return PointerBuffer.wrap(Buffers.nativeOrder(_res)); + } + + /** Entry point to C language function: <code> GLXFBConfig * glXGetFBConfigs(Display * dpy, int screen, int * nelements); </code> <br>Part of <code>GLX_VERSION_1_3</code> + @param nelements a direct only {@link java.nio.IntBuffer} */ + private static native ByteBuffer dispatch_glXGetFBConfigs(long dpy, int screen, Object nelements, int nelements_byte_offset, long procAddress); + /** Entry point to C language function: <code> XVisualInfo * glXChooseVisual(Display * dpy, int screen, int * attribList); </code> <br>Part of <code>GLX_VERSION_1_X</code> @param attribList a direct only {@link java.nio.IntBuffer} */ diff --git a/make/config/jogl/glx-x11.cfg b/make/config/jogl/glx-x11.cfg index 5955e0a38..1c138c8ae 100644 --- a/make/config/jogl/glx-x11.cfg +++ b/make/config/jogl/glx-x11.cfg @@ -44,9 +44,11 @@ Ignore glXCreateContextAttribsARB Ignore glXGetVisualFromFBConfigSGIX ManuallyImplement glXGetVisualFromFBConfig ManuallyImplement glXChooseFBConfig +ManuallyImplement glXGetFBConfigs ManuallyImplement glXChooseVisual ForceProcAddressGen glXGetVisualFromFBConfig ForceProcAddressGen glXChooseFBConfig +ForceProcAddressGen glXGetFBConfigs ForceProcAddressGen glXChooseVisual # Ignore everything not in the GLX core (up through GLX 1.4) diff --git a/make/config/jogl/glxext.cfg b/make/config/jogl/glxext.cfg index c73753e3c..d158d241f 100644 --- a/make/config/jogl/glxext.cfg +++ b/make/config/jogl/glxext.cfg @@ -60,6 +60,7 @@ CustomJavaCode GLXExtImpl private X11GLXContext _context; Ignore glXGetVisualFromFBConfig Ignore glXGetVisualFromFBConfigSGIX Ignore glXChooseFBConfig +Ignore glXGetFBConfigs Ignore glXChooseVisual Ignore glXCreateContext Ignore glXDestroyContext @@ -81,7 +82,6 @@ Ignore glXQueryExtensionsString Ignore glXQueryServerString Ignore glXGetClientString Ignore glXGetCurrentDisplay -Ignore glXChooseFBConfig Ignore glXGetFBConfigAttrib Ignore glXGetFBConfigs Ignore glXGetVisualFromFBConfig diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java index ee3e1a3d7..c0a3b46df 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java @@ -254,7 +254,13 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem int val = 0; final IntBuffer tmp = Buffers.newDirectIntBuffer(1); - int fbtype = glXGetFBConfig(device.getHandle(), fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp); + if( !glXGetFBConfig(device.getHandle(), fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.FBCfgDrawableTypeBits: FBConfig invalid: fbcfg: "+toHexString(fbcfg)); + } + return 0; + } + final int fbtype = tmp.get(0); if ( 0 != ( fbtype & GLX.GLX_WINDOW_BIT ) ) { val |= GLGraphicsConfigurationUtil.WINDOW_BIT | @@ -314,8 +320,19 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem final long display = device.getHandle(); final int allDrawableTypeBits = FBCfgDrawableTypeBits(device, fbcfg); int drawableTypeBits = winattrmask & allDrawableTypeBits; - + if( 0 == allDrawableTypeBits || 0 == drawableTypeBits ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities: zero drawablebits: allDrawableTypeBits: "+toHexString(allDrawableTypeBits)+", drawableTypeBits "+toHexString(drawableTypeBits)); + } + return null; + } final int fbcfgid = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfg); + if( VisualIDHolder.VID_UNDEFINED == fbcfgid ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities: FBConfig invalid (0): fbcfg: "+toHexString(fbcfg)); + } + return null; + } final XVisualInfo visualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfg); if(null == visualInfo) { if(DEBUG) { @@ -415,20 +432,26 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem } } - static int glXGetFBConfig(long display, long cfg, int attrib, IntBuffer tmp) { + static boolean glXGetFBConfig(long display, long cfg, int attrib, IntBuffer tmp) { if (display == 0) { throw new GLException("No display connection"); } - int res = GLX.glXGetFBConfigAttrib(display, cfg, attrib, tmp); - if (res != 0) { - throw new GLException("glXGetFBConfig("+toHexString(attrib)+") failed: error code " + glXGetFBConfigErrorCode(res)); + final boolean res = GLX.GLX_BAD_ATTRIBUTE != GLX.glXGetFBConfigAttrib(display, cfg, attrib, tmp); + if( !res ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.glXGetFBConfig: FBConfig invalid: fbcfg: "+toHexString(cfg)); + } } - return tmp.get(tmp.position()); + return res; } static int glXFBConfig2FBConfigID(long display, long cfg) { final IntBuffer tmpID = Buffers.newDirectIntBuffer(1); - return glXGetFBConfig(display, cfg, GLX.GLX_FBCONFIG_ID, tmpID); + if( glXGetFBConfig(display, cfg, GLX.GLX_FBCONFIG_ID, tmpID) ) { + return tmpID.get(0); + } else { + return VisualIDHolder.VID_UNDEFINED; // error + } } static long glXFBConfigID2FBConfig(long display, int screen, int id) { diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java index 1f92960bc..75771f884 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java @@ -258,13 +258,19 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF final long fbcfg = X11GLXGraphicsConfiguration.glXFBConfigID2FBConfig(display, screen, fbID); if( 0 == fbcfg || !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfg ) ) { if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: ("+x11Screen+","+toHexString(fbID)+"): fbcfg: "+toHexString(fbcfg)); + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed.0 - GLX FBConfig invalid: ("+x11Screen+","+toHexString(fbID)+"): fbcfg: "+toHexString(fbcfg)); } return null; } final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory(); final X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(x11Device, glp, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, factory.isGLXMultisampleAvailable(x11Device)); + if(null==caps) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed.1 - GLX FBConfig invalid: ("+x11Screen+","+toHexString(fbID)+"): fbcfg: "+toHexString(fbcfg)); + } + return null; + } return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser()); } |