summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/jogamp/opengl/x11
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-11-04 15:07:14 +0100
committerSven Gothel <[email protected]>2013-11-04 15:07:14 +0100
commit613e33ee8ffc1f2b9c5db1e1b5bb5253a159ed6d (patch)
tree761c21e05e274bcea3852406fdbc63c25f266b10 /src/jogl/classes/jogamp/opengl/x11
parent7433e513c1f109f75aa34c224b1f5f14b612cba8 (diff)
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).
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/x11')
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java144
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java46
2 files changed, 129 insertions, 61 deletions
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<GLCapabilitiesImmutable> 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<GLCapabilitiesImmutable> result = new ArrayList<GLCapabilitiesImmutable>();
+ 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<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen);
+ List<GLCapabilitiesImmutable> 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<GLCapabilitiesImmutable>();
}
// 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<availableCaps.size(); ) {
- VisualIDHolder vidh = (VisualIDHolder) availableCaps.get(i);
+ final VisualIDHolder vidh = availableCaps.get(i);
if(vidh.getVisualID(VIDType.X11_XVISUAL) != xvisualID ) {
availableCaps.remove(i);
} else {
@@ -365,7 +358,12 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
}
- int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex);
+ final int chosenIndex;
+ if( skipCapsChooser && 0 <= recommendedIndex ) {
+ chosenIndex = recommendedIndex;
+ } else {
+ chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex);
+ }
if ( 0 > 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<availableCaps.size(); ) {
- VisualIDHolder vidh = (VisualIDHolder) availableCaps.get(i);
+ VisualIDHolder vidh = availableCaps.get(i);
if(vidh.getVisualID(VIDType.X11_XVISUAL) != xvisualID ) {
availableCaps.remove(i);
} else {