From 5deb97e50abf0c19dc37aa69add1dfa2447825ad Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Tue, 30 Oct 2012 17:04:42 +0100 Subject: GLX/GLXExt Robustness: Use NIODirectOnly for all bindings. For these internal APIs, critical array is not required, hence redundant. --- make/config/jogl/glx-CustomJavaCode.java | 56 ++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 25 deletions(-) (limited to 'make/config/jogl/glx-CustomJavaCode.java') diff --git a/make/config/jogl/glx-CustomJavaCode.java b/make/config/jogl/glx-CustomJavaCode.java index 36ad10031..ed126a5c9 100644 --- a/make/config/jogl/glx-CustomJavaCode.java +++ b/make/config/jogl/glx-CustomJavaCode.java @@ -16,43 +16,49 @@ private static native java.nio.ByteBuffer dispatch_glXGetVisualFromFBConfig(long dpy, long config, long procAddr); - /** Interface to C language function:
- Alias for:
GLXFBConfig * glXChooseFBConfigSGIX, glXChooseFBConfig(Display * dpy, int screen, const int * attribList, int * nitems); */ - public static com.jogamp.common.nio.PointerBuffer glXChooseFBConfig(long dpy, int screen, int[] attribList, int attribList_offset, int[] nitems, int nitems_offset) - { + /** Entry point to C language function: GLXFBConfig * glXChooseFBConfig(Display * dpy, int screen, const int * attribList, int * nitems);
Part of CORE FUNC + @param attribList a direct only {@link java.nio.IntBuffer} + @param nitems a direct only {@link java.nio.IntBuffer} */ + public static PointerBuffer glXChooseFBConfig(long dpy, int screen, IntBuffer attribList, IntBuffer nitems) { + + if (!Buffers.isDirect(attribList)) + throw new GLException("Argument \"attribList\" is not a direct buffer"); + if (!Buffers.isDirect(nitems)) + throw new GLException("Argument \"nitems\" is not a direct buffer"); final long __addr_ = glxProcAddressTable._addressof_glXChooseFBConfig; if (__addr_ == 0) { - throw new GLException("Method \"glXChooseFBConfig\" not available"); + throw new GLException("Method \"glXChooseFBConfig\" not available"); } - if(attribList != null && attribList.length <= attribList_offset) - throw new GLException("array offset argument \"attribList_offset\" (" + attribList_offset + ") equals or exceeds array length (" + attribList.length + ")"); - if(nitems != null && nitems.length <= nitems_offset) - throw new GLException("array offset argument \"nitems_offset\" (" + nitems_offset + ") equals or exceeds array length (" + nitems.length + ")"); - java.nio.ByteBuffer _res; - _res = dispatch_glXChooseFBConfig(dpy, screen, attribList, Buffers.SIZEOF_INT * attribList_offset, nitems, Buffers.SIZEOF_INT * nitems_offset, __addr_); - + final ByteBuffer _res; + _res = dispatch_glXChooseFBConfig(dpy, screen, attribList, Buffers.getDirectBufferByteOffset(attribList), nitems, Buffers.getDirectBufferByteOffset(nitems), __addr_); if (_res == null) return null; + Buffers.nativeOrder(_res); return PointerBuffer.wrap(_res); } - /** Entry point to C language function: - Alias for:
GLXFBConfig * glXChooseFBConfigSGIX, glXChooseFBConfig(Display * dpy, int screen, const int * attribList, int * nitems); */ - private static native java.nio.ByteBuffer dispatch_glXChooseFBConfig(long dpy, int screen, Object attribList, int attribList_byte_offset, Object nitems, int nitems_byte_offset, long procAddr); + /** Entry point to C language function: GLXFBConfig * glXChooseFBConfig(Display * dpy, int screen, const int * attribList, int * nitems);
Part of CORE FUNC + @param attribList a direct only {@link java.nio.IntBuffer} + @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); - /** Interface to C language function:
- Alias for:
XVisualInfo * glXChooseVisual(Display * dpy, int screen, int * attribList); */ - public static XVisualInfo glXChooseVisual(long dpy, int screen, int[] attribList, int attribList_offset) - { + + /** Entry point to C language function: XVisualInfo * glXChooseVisual(Display * dpy, int screen, int * attribList);
Part of GLX_VERSION_1_X + @param attribList a direct only {@link java.nio.IntBuffer} */ + public static XVisualInfo glXChooseVisual(long dpy, int screen, IntBuffer attribList) { + + if (!Buffers.isDirect(attribList)) + throw new GLException("Argument \"attribList\" is not a direct buffer"); final long __addr_ = glxProcAddressTable._addressof_glXChooseVisual; if (__addr_ == 0) { - throw new GLException("Method \"glXChooseVisual\" not available"); + throw new GLException("Method \"glXChooseVisual\" not available"); } - if(attribList != null && attribList.length <= attribList_offset) - throw new GLException("array offset argument \"attribList_offset\" (" + attribList_offset + ") equals or exceeds array length (" + attribList.length + ")"); - java.nio.ByteBuffer _res; - _res = dispatch_glXChooseVisual(dpy, screen, attribList, Buffers.SIZEOF_INT * attribList_offset, __addr_); - + final ByteBuffer _res; + _res = dispatch_glXChooseVisual(dpy, screen, attribList, Buffers.getDirectBufferByteOffset(attribList), __addr_); if (_res == null) return null; - return XVisualInfo.create(_res); + return XVisualInfo.create(Buffers.nativeOrder(_res)); } - /** Entry point to C language function: - Alias for:
XVisualInfo * glXChooseVisual(Display * dpy, int screen, int * attribList); */ - private static native java.nio.ByteBuffer dispatch_glXChooseVisual(long dpy, int screen, Object attribList, int attribList_byte_offset, long procAddr); + /** Entry point to C language function: XVisualInfo * glXChooseVisual(Display * dpy, int screen, int * attribList);
Part of GLX_VERSION_1_X + @param attribList a direct only {@link java.nio.IntBuffer} */ + private static native ByteBuffer dispatch_glXChooseVisual(long dpy, int screen, Object attribList, int attribList_byte_offset, long procAddress); -- cgit v1.2.3 From da8717097df2afba3fc7e9ef648ce6bc4ebd4f9f Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Tue, 7 May 2013 23:28:08 +0200 Subject: GLX: Put native ByteBuffer to native-order in 'glXGetVisualFromFBConfig' and minor edits (final, same 'nativeOrder()' call style) --- make/config/jogl/glx-CustomJavaCode.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'make/config/jogl/glx-CustomJavaCode.java') diff --git a/make/config/jogl/glx-CustomJavaCode.java b/make/config/jogl/glx-CustomJavaCode.java index ed126a5c9..f3e743930 100644 --- a/make/config/jogl/glx-CustomJavaCode.java +++ b/make/config/jogl/glx-CustomJavaCode.java @@ -6,10 +6,9 @@ if (__addr_ == 0) { throw new GLException("Method \"glXGetVisualFromFBConfig\" not available"); } - java.nio.ByteBuffer _res; - _res = dispatch_glXGetVisualFromFBConfig(dpy, config, __addr_); + final java.nio.ByteBuffer _res = dispatch_glXGetVisualFromFBConfig(dpy, config, __addr_); if (_res == null) return null; - return XVisualInfo.create(_res); + return XVisualInfo.create(Buffers.nativeOrder(_res)); } /** Entry point to C language function: - Alias for:
XVisualInfo * glXGetVisualFromFBConfigSGIX, glXGetVisualFromFBConfig(Display * dpy, GLXFBConfig config); */ @@ -29,11 +28,9 @@ if (__addr_ == 0) { throw new GLException("Method \"glXChooseFBConfig\" not available"); } - final ByteBuffer _res; - _res = dispatch_glXChooseFBConfig(dpy, screen, attribList, Buffers.getDirectBufferByteOffset(attribList), nitems, Buffers.getDirectBufferByteOffset(nitems), __addr_); + final ByteBuffer _res = dispatch_glXChooseFBConfig(dpy, screen, attribList, Buffers.getDirectBufferByteOffset(attribList), nitems, Buffers.getDirectBufferByteOffset(nitems), __addr_); if (_res == null) return null; - Buffers.nativeOrder(_res); - return PointerBuffer.wrap(_res); + return PointerBuffer.wrap(Buffers.nativeOrder(_res)); } /** Entry point to C language function: GLXFBConfig * glXChooseFBConfig(Display * dpy, int screen, const int * attribList, int * nitems);
Part of CORE FUNC @@ -52,8 +49,7 @@ if (__addr_ == 0) { throw new GLException("Method \"glXChooseVisual\" not available"); } - final ByteBuffer _res; - _res = dispatch_glXChooseVisual(dpy, screen, attribList, Buffers.getDirectBufferByteOffset(attribList), __addr_); + final ByteBuffer _res = dispatch_glXChooseVisual(dpy, screen, attribList, Buffers.getDirectBufferByteOffset(attribList), __addr_); if (_res == null) return null; return XVisualInfo.create(Buffers.nativeOrder(_res)); } -- cgit v1.2.3 From 613e33ee8ffc1f2b9c5db1e1b5bb5253a159ed6d Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Mon, 4 Nov 2013 15:07:14 +0100 Subject: Bug 888 - Validate CPU Runtime Performance: X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(..) X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(..) ran over all FB configs and for each it grabbed native config values separately. Fetching them in bulk mode saves around 7% of this function's cost. Also reuse XRenderPictFormat instance for 'XRenderDirectFormat XRenderFindVisualFormat(..)' call, saving a few NIO creation cycles w/ StructAccessor. Biggest savior is X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationFBConfig()'s fast path w/o chooser and usable 1st FBConfig. Here we only issue 'GLXFBConfig2GLCapabilities(..)' on the first valid entry. Test w/ 50 X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationFBConfig() invocations: - pre change: 1.708 ms - post change: 650 ms Time is no spent almost solely on native glXChooseFBConfig (546ms). --- make/config/jogl/glx-CustomCCode.c | 25 ++++ make/config/jogl/glx-CustomJavaCode.java | 22 ++++ make/config/nativewindow/x11-CustomJavaCode.java | 15 +++ .../x11/glx/X11GLXGraphicsConfiguration.java | 144 +++++++++++++++------ .../glx/X11GLXGraphicsConfigurationFactory.java | 46 ++++--- src/nativewindow/native/x11/Xmisc.c | 15 +++ 6 files changed, 206 insertions(+), 61 deletions(-) (limited to 'make/config/jogl/glx-CustomJavaCode.java') diff --git a/make/config/jogl/glx-CustomCCode.c b/make/config/jogl/glx-CustomCCode.c index 71dc68b08..5c73dfea6 100644 --- a/make/config/jogl/glx-CustomCCode.c +++ b/make/config/jogl/glx-CustomCCode.c @@ -59,6 +59,31 @@ static void _initClazzAccess(JNIEnv *env) { } } +/* Java->C glue code: + * Java package: jogamp.opengl.x11.glx.GLX + * Java method: int glXGetFBConfigAttributes(long dpy, long config, IntBuffer attributes, IntBuffer values) + */ +JNIEXPORT jint JNICALL +Java_jogamp_opengl_x11_glx_GLX_dispatch_1glXGetFBConfigAttributes(JNIEnv *env, jclass _unused, jlong dpy, jlong config, jint attributeCount, jobject attributes, jint attributes_byte_offset, jobject values, jint values_byte_offset, jlong procAddress) { + typedef int (APIENTRY*_local_PFNGLXGETFBCONFIGATTRIBPROC)(Display * dpy, GLXFBConfig config, int attribute, int * value); + _local_PFNGLXGETFBCONFIGATTRIBPROC ptr_glXGetFBConfigAttrib = (_local_PFNGLXGETFBCONFIGATTRIBPROC) (intptr_t) procAddress; + assert(ptr_glXGetFBConfigAttrib != NULL); + + int err = 0; + if ( attributeCount > 0 && NULL != attributes ) { + int i; + int * attributes_ptr = (int *) (((char*) (*env)->GetDirectBufferAddress(env, attributes)) + attributes_byte_offset); + int * values_ptr = (int *) (((char*) (*env)->GetDirectBufferAddress(env, values)) + values_byte_offset); + for(i=0; 0 == err && iC glue code: * Java package: jogamp.opengl.x11.glx.GLX * Java method: XVisualInfo glXGetVisualFromFBConfig(long dpy, long config) diff --git a/make/config/jogl/glx-CustomJavaCode.java b/make/config/jogl/glx-CustomJavaCode.java index f3e743930..4cce05dda 100644 --- a/make/config/jogl/glx-CustomJavaCode.java +++ b/make/config/jogl/glx-CustomJavaCode.java @@ -1,4 +1,26 @@ + /** + * Returns the GLX error value, i.e. 0 for no error. In case of an error values.get(values.getPosition()) contains the attributes index causing the error. + *

+ * Entry point to C language function: int glXGetFBConfigAttrib(Display * dpy, GLXFBConfig config, int attribute, int * value);
Part of GLX_VERSION_1_3 + *

+ */ + public static int glXGetFBConfigAttributes(long dpy, long config, IntBuffer attributes, IntBuffer values) { + if( attributes == null || values == null ) { + throw new RuntimeException("arrays buffers are null"); + } + if( !Buffers.isDirect(attributes) || !Buffers.isDirect(values) ) { + throw new RuntimeException("arrays buffers are not direct"); + } + if( attributes.remaining() > values.remaining() ) { + throw new RuntimeException("not enough values "+values+" for attributes "+attributes); + } + final long __addr = glxProcAddressTable._addressof_glXGetFBConfigAttrib; + return dispatch_glXGetFBConfigAttributes(dpy, config, attributes.remaining(), attributes, Buffers.getDirectBufferByteOffset(attributes), + values, Buffers.getDirectBufferByteOffset(values), __addr); + } + private static native int dispatch_glXGetFBConfigAttributes(long dpy, long config, int attributeCount, Object attributes, int attributes_byte_offset, Object values, int valuesOffset, long procAddr); + /** Interface to C language function:
- Alias for:
XVisualInfo * glXGetVisualFromFBConfigSGIX, glXGetVisualFromFBConfig(Display * dpy, GLXFBConfig config); */ public static XVisualInfo glXGetVisualFromFBConfig(long dpy, long config) { diff --git a/make/config/nativewindow/x11-CustomJavaCode.java b/make/config/nativewindow/x11-CustomJavaCode.java index 4240c5e2f..d1e011184 100644 --- a/make/config/nativewindow/x11-CustomJavaCode.java +++ b/make/config/nativewindow/x11-CustomJavaCode.java @@ -1,4 +1,19 @@ + /** Interface to C language function:
XRenderPictFormat * XRenderFindVisualFormat(Display * dpy, const Visual * visual); */ + public static boolean XRenderFindVisualFormat(long dpy, long visual, XRenderPictFormat dest) { + if( dest == null ) { + throw new RuntimeException("dest is null"); + } + final ByteBuffer destBuffer = dest.getBuffer(); + if( !Buffers.isDirect(destBuffer) ) { + throw new RuntimeException("dest buffer is not direct"); + } + return XRenderFindVisualFormat1(dpy, visual, destBuffer); + } + /** Entry point to C language function: XVisualInfo * XGetVisualInfo(Display * , long, XVisualInfo * , int * ); */ + private static native boolean XRenderFindVisualFormat1(long dpy, long visual, ByteBuffer xRenderPictFormat); + + /** Interface to C language function:
XVisualInfo * XGetVisualInfo(Display * , long, XVisualInfo * , int * ); */ public static XVisualInfo[] XGetVisualInfo(long arg0, long arg1, XVisualInfo arg2, int[] arg3, int arg3_offset) { diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java index 4d1ed3985..ee3e1a3d7 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java @@ -34,6 +34,8 @@ package jogamp.opengl.x11.glx; import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.List; import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.GraphicsConfigurationFactory; @@ -61,7 +63,7 @@ import com.jogamp.nativewindow.x11.X11GraphicsScreen; public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implements Cloneable { public static final int MAX_ATTRIBS = 128; - private GLCapabilitiesChooser chooser; + private final GLCapabilitiesChooser chooser; X11GLXGraphicsConfiguration(X11GraphicsScreen screen, X11GLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { @@ -274,15 +276,47 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem } return renderPictFmt.getDirect(); } + static XRenderDirectFormat XVisual2XRenderMask(long dpy, long visual, XRenderPictFormat dest) { + if( !X11Lib.XRenderFindVisualFormat(dpy, visual, dest) ) { + return null; + } else { + return dest.getDirect(); + } + } + + static X11GLCapabilities GLXFBConfig2GLCapabilities(final X11GraphicsDevice device, final GLProfile glp, final long fbcfg, + final int winattrmask, final boolean isMultisampleAvailable) { + final IntBuffer tmp = Buffers.newDirectIntBuffer(1); + final XRenderPictFormat xRenderPictFormat= XRenderPictFormat.create(); + return GLXFBConfig2GLCapabilities(device, glp, fbcfg, winattrmask, isMultisampleAvailable, tmp, xRenderPictFormat); + } - static X11GLCapabilities GLXFBConfig2GLCapabilities(X11GraphicsDevice device, GLProfile glp, long fbcfg, - int winattrmask, boolean isMultisampleAvailable) { + static List GLXFBConfig2GLCapabilities(final X11GraphicsDevice device, final GLProfile glp, final PointerBuffer fbcfgsL, + final int winattrmask, final boolean isMultisampleAvailable, boolean onlyFirstValid) { + final IntBuffer tmp = Buffers.newDirectIntBuffer(1); + final XRenderPictFormat xRenderPictFormat= XRenderPictFormat.create(); + final List result = new ArrayList(); + for (int i = 0; i < fbcfgsL.limit(); i++) { + final long fbcfg = fbcfgsL.get(i); + final GLCapabilitiesImmutable c = GLXFBConfig2GLCapabilities(device, glp, fbcfg, winattrmask, isMultisampleAvailable, tmp, xRenderPictFormat); + if( null != c ) { + result.add(c); + if( onlyFirstValid ) { + break; + } + } + } + return result; + } + static X11GLCapabilities GLXFBConfig2GLCapabilities(final X11GraphicsDevice device, final GLProfile glp, final long fbcfg, + final int winattrmask, final boolean isMultisampleAvailable, + final IntBuffer tmp, final XRenderPictFormat xRenderPictFormat) { + final long display = device.getHandle(); final int allDrawableTypeBits = FBCfgDrawableTypeBits(device, fbcfg); int drawableTypeBits = winattrmask & allDrawableTypeBits; - final long display = device.getHandle(); - int fbcfgid = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfg); - XVisualInfo visualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfg); + final int fbcfgid = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfg); + final XVisualInfo visualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfg); if(null == visualInfo) { if(DEBUG) { System.err.println("X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities: Null XVisualInfo for FBConfigID 0x" + Integer.toHexString(fbcfgid)); @@ -290,51 +324,87 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem // onscreen must have an XVisualInfo drawableTypeBits &= ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.FBO_BIT); } - if( 0 == drawableTypeBits ) { - return null; + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities: zero drawablebits: winattrmask: "+toHexString(winattrmask)+", offscreen "+(null == visualInfo)); + } + return null; } - final IntBuffer tmp = Buffers.newDirectIntBuffer(1); if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp)) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities: FBConfig invalid (1): fbcfg: "+toHexString(fbcfg)); + } return null; } if( 0 == ( GLX.GLX_RGBA_BIT & tmp.get(0) ) ) { - return null; // no RGBA -> color index not supported + // no RGBA -> color index not supported + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities: FBConfig not RGBA (2): fbcfg: "+toHexString(fbcfg)); + } + return null; } - final X11GLCapabilities res = new X11GLCapabilities(visualInfo, fbcfg, fbcfgid, glp); - if (isMultisampleAvailable) { - res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp) != 0); - res.setNumSamples (glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLES, tmp)); - } + final X11GLCapabilities caps = new X11GLCapabilities(visualInfo, fbcfg, fbcfgid, glp); + final XRenderDirectFormat xrmask = ( null != visualInfo ) ? - XVisual2XRenderMask( display, visualInfo.getVisual() ) : + XVisual2XRenderMask( display, visualInfo.getVisual(), xRenderPictFormat) : null ; + + final int _attributes[] = { + GLX.GLX_SAMPLE_BUFFERS, + GLX.GLX_SAMPLES, + GLX.GLX_DOUBLEBUFFER, + GLX.GLX_STEREO, + GLX.GLX_CONFIG_CAVEAT, + GLX.GLX_RED_SIZE, + GLX.GLX_GREEN_SIZE, + GLX.GLX_BLUE_SIZE, + GLX.GLX_ALPHA_SIZE, + GLX.GLX_ACCUM_RED_SIZE, + GLX.GLX_ACCUM_GREEN_SIZE, + GLX.GLX_ACCUM_BLUE_SIZE, + GLX.GLX_ACCUM_ALPHA_SIZE, + GLX.GLX_DEPTH_SIZE, + GLX.GLX_STENCIL_SIZE + }; + final int offset = isMultisampleAvailable ? 0 : 2; + final IntBuffer attributes = Buffers.newDirectIntBuffer(_attributes); + attributes.position(offset); + final IntBuffer values = Buffers.newDirectIntBuffer(attributes.remaining()); + final int err = GLX.glXGetFBConfigAttributes(display, fbcfg, attributes, values); + if (0 != err) { + throw new GLException("glXGetFBConfig("+toHexString(attributes.get(offset+values.get(0)))+") failed: error code " + glXGetFBConfigErrorCode(err)); + } + int j=0; + if (isMultisampleAvailable) { + caps.setSampleBuffers(values.get(j++) != 0); + caps.setNumSamples (values.get(j++)); + } final int alphaMask = ( null != xrmask ) ? xrmask.getAlphaMask() : 0; - res.setBackgroundOpaque( 0 >= alphaMask ); - if( !res.isBackgroundOpaque() ) { - res.setTransparentRedValue(xrmask.getRedMask()); - res.setTransparentGreenValue(xrmask.getGreenMask()); - res.setTransparentBlueValue(xrmask.getBlueMask()); - res.setTransparentAlphaValue(alphaMask); + caps.setBackgroundOpaque( 0 >= alphaMask ); + if( !caps.isBackgroundOpaque() ) { + caps.setTransparentRedValue(xrmask.getRedMask()); + caps.setTransparentGreenValue(xrmask.getGreenMask()); + caps.setTransparentBlueValue(xrmask.getBlueMask()); + caps.setTransparentAlphaValue(alphaMask); } // ALPHA shall be set at last - due to it's auto setting by the above (!opaque / samples) - res.setDoubleBuffered(glXGetFBConfig(display, fbcfg, GLX.GLX_DOUBLEBUFFER, tmp) != 0); - res.setStereo (glXGetFBConfig(display, fbcfg, GLX.GLX_STEREO, tmp) != 0); - res.setHardwareAccelerated(glXGetFBConfig(display, fbcfg, GLX.GLX_CONFIG_CAVEAT, tmp) != GLX.GLX_SLOW_CONFIG); - res.setRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_RED_SIZE, tmp)); - res.setGreenBits (glXGetFBConfig(display, fbcfg, GLX.GLX_GREEN_SIZE, tmp)); - res.setBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_BLUE_SIZE, tmp)); - res.setAlphaBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ALPHA_SIZE, tmp)); - res.setAccumRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_RED_SIZE, tmp)); - res.setAccumGreenBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_GREEN_SIZE, tmp)); - res.setAccumBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_BLUE_SIZE, tmp)); - res.setAccumAlphaBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_ALPHA_SIZE, tmp)); - res.setDepthBits (glXGetFBConfig(display, fbcfg, GLX.GLX_DEPTH_SIZE, tmp)); - res.setStencilBits (glXGetFBConfig(display, fbcfg, GLX.GLX_STENCIL_SIZE, tmp)); - - return (X11GLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res); + caps.setDoubleBuffered(values.get(j++) != 0); + caps.setStereo (values.get(j++) != 0); + caps.setHardwareAccelerated(values.get(j++) != GLX.GLX_SLOW_CONFIG); + caps.setRedBits (values.get(j++)); + caps.setGreenBits (values.get(j++)); + caps.setBlueBits (values.get(j++)); + caps.setAlphaBits (values.get(j++)); + caps.setAccumRedBits (values.get(j++)); + caps.setAccumGreenBits(values.get(j++)); + caps.setAccumBlueBits (values.get(j++)); + caps.setAccumAlphaBits(values.get(j++)); + caps.setDepthBits (values.get(j++)); + caps.setStencilBits (values.get(j++)); + + return (X11GLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, caps); } private static String glXGetFBConfigErrorCode(int err) { diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java index 6050dabbb..5c84597d5 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java @@ -287,24 +287,23 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF final IntBuffer attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, true, isMultisampleAvailable, display, screen); final IntBuffer count = Buffers.newDirectIntBuffer(1); count.put(0, -1); - List availableCaps = new ArrayList(); final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen); + List availableCaps; // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice, // skipped if xvisualID is given + final boolean hasGLXChosenCaps; if( VisualIDHolder.VID_UNDEFINED == xvisualID ) { fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, count); + hasGLXChosenCaps = fbcfgsL != null && fbcfgsL.limit()>0; + } else { + hasGLXChosenCaps = false; } - if (fbcfgsL != null && fbcfgsL.limit()>0) { - for (int i = 0; i < fbcfgsL.limit(); i++) { - final GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(x11Device, glProfile, fbcfgsL.get(i), winattrmask, isMultisampleAvailable); - if( null != caps ) { - availableCaps.add(caps); - } else if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (1): ("+x11Screen+","+capsChosen+"): fbcfg: "+toHexString(fbcfgsL.get(i))); - } - } + final boolean useRecommendedIndex = hasGLXChosenCaps && capsChosen.isBackgroundOpaque(); // only use recommended idx if not translucent + final boolean skipCapsChooser = null == chooser && useRecommendedIndex; // fast path: skip choosing if using recommended idx and null chooser is used + if (hasGLXChosenCaps) { + availableCaps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(x11Device, glProfile, fbcfgsL, winattrmask, isMultisampleAvailable, skipCapsChooser /* onlyFirstValid */); if(availableCaps.size() > 0) { - recommendedIndex = capsChosen.isBackgroundOpaque() ? 0 : -1; // only use recommended idx if not translucent + recommendedIndex = useRecommendedIndex ? 0 : -1; if (DEBUG) { System.err.println("glXChooseFBConfig recommended fbcfg " + toHexString(fbcfgsL.get(0)) + ", idx " + recommendedIndex); System.err.println("user caps " + capsChosen); @@ -314,6 +313,8 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF System.err.println("glXChooseFBConfig no caps for recommended fbcfg " + toHexString(fbcfgsL.get(0))); System.err.println("user caps " + capsChosen); } + } else { + availableCaps = new ArrayList(); } // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available @@ -328,15 +329,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF } return null; } - - for (int i = 0; i < fbcfgsL.limit(); i++) { - final GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(x11Device, glProfile, fbcfgsL.get(i), winattrmask, isMultisampleAvailable); - if( null != caps ) { - availableCaps.add(caps); - } else if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i))); - } - } + availableCaps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(x11Device, glProfile, fbcfgsL, winattrmask, isMultisampleAvailable, false /* onlyOneValid */); } if(DEBUG) { @@ -346,9 +339,9 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF } } - if( VisualIDHolder.VID_UNDEFINED != xvisualID ) { + if( VisualIDHolder.VID_UNDEFINED != xvisualID ) { // implies !hasGLXChosenCaps for(int i=0; i chosenIndex ) { if (DEBUG) { System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: failed, return null"); @@ -445,7 +443,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF if( VisualIDHolder.VID_UNDEFINED != xvisualID ) { for(int i=0; i +#include + // #define VERBOSE_ON 1 #ifdef VERBOSE_ON @@ -320,6 +322,19 @@ Java_jogamp_nativewindow_x11_X11Util_setX11ErrorHandler0(JNIEnv *env, jclass _un NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 1, onoff ? 1 : 0, quiet ? 1 : 0, 0 /* no dpy, force, no sync */); } +/* Java->C glue code: + * Java package: jogamp.nativewindow.x11.X11Lib + * Java method: boolean XRenderFindVisualFormat(long dpy, long visual, XRenderPictFormat dest) + */ +JNIEXPORT jboolean JNICALL +Java_jogamp_nativewindow_x11_X11Lib_XRenderFindVisualFormat1(JNIEnv *env, jclass _unused, jlong dpy, jlong visual, jobject xRenderPictFormat) { + XRenderPictFormat * dest = (XRenderPictFormat *) (*env)->GetDirectBufferAddress(env, xRenderPictFormat); + XRenderPictFormat * src = XRenderFindVisualFormat((Display *) (intptr_t) dpy, (Visual *) (intptr_t) visual); + if (NULL == src) return JNI_FALSE; + memcpy(dest, src, sizeof(XRenderPictFormat)); + return JNI_TRUE; +} + /* Java->C glue code: * Java package: jogamp.nativewindow.x11.X11Lib * Java method: XVisualInfo XGetVisualInfo(long arg0, long arg1, XVisualInfo arg2, java.nio.IntBuffer arg3) -- cgit v1.2.3