aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java')
-rw-r--r--src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java268
1 files changed, 218 insertions, 50 deletions
diff --git a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
index d7958c7f1..702fb77de 100644
--- a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
+++ b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
@@ -28,17 +28,22 @@
package jogamp.opengl;
-import java.util.ArrayList;
-
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLProfile;
+
+import com.jogamp.opengl.GLRendererQuirks;
public class GLGraphicsConfigurationUtil {
public static final String NV_coverage_sample = "NV_coverage_sample";
public static final int WINDOW_BIT = 1 << 0;
public static final int BITMAP_BIT = 1 << 1;
public static final int PBUFFER_BIT = 1 << 2;
- public static final int ALL_BITS = WINDOW_BIT | BITMAP_BIT | PBUFFER_BIT ;
+ public static final int FBO_BIT = 1 << 3; // generic bit must be mapped to native one at impl. level
+ public static final int ALL_BITS = WINDOW_BIT | BITMAP_BIT | PBUFFER_BIT | FBO_BIT ;
public static final StringBuilder winAttributeBits2String(StringBuilder sb, int winattrbits) {
if(null==sb) {
@@ -61,74 +66,184 @@ public class GLGraphicsConfigurationUtil {
sb.append(", ");
}
sb.append("PBUFFER");
+ seperator=true;
+ }
+ if( 0 != ( FBO_BIT & winattrbits ) ) {
+ if(seperator) {
+ sb.append(", ");
+ }
+ sb.append("FBO");
}
return sb;
}
/**
- * @return bitmask representing the input boolean in exclusive or logic, ie only one bit will be set
- */
- public static final int getWinAttributeBits(boolean isOnscreen, boolean isPBuffer) {
+ public static final int getWinAttributeBits(boolean isOnscreen, boolean isFBO, boolean isPBuffer, boolean isBitmap) {
int winattrbits = 0;
if(isOnscreen) {
winattrbits |= WINDOW_BIT;
- } else if (!isPBuffer) {
+ }
+ if(isFBO) {
+ winattrbits |= FBO_BIT;
+ }
+ if(isPBuffer ){
+ winattrbits |= PBUFFER_BIT;
+ }
+ if(isBitmap) {
winattrbits |= BITMAP_BIT;
+ }
+ return winattrbits;
+ }
+ public static final int getWinAttributeBits(GLCapabilitiesImmutable caps) {
+ return getWinAttributeBits(caps.isOnscreen(), caps.isFBO(), caps.isPBuffer(), caps.isBitmap());
+ } */
+
+ /**
+ * @return bitmask representing the input boolean in exclusive or logic, ie only one bit will be set.
+ */
+ public static final int getExclusiveWinAttributeBits(boolean isOnscreen, boolean isFBO, boolean isPBuffer, boolean isBitmap) {
+ final int winattrbits;
+ if(isOnscreen) {
+ winattrbits = WINDOW_BIT;
+ } else if(isFBO) {
+ winattrbits = FBO_BIT;
+ } else if(isPBuffer ){
+ winattrbits = PBUFFER_BIT;
+ } else if(isBitmap) {
+ winattrbits = BITMAP_BIT;
} else {
- winattrbits |= PBUFFER_BIT;
+ throw new InternalError("Empty bitmask");
}
return winattrbits;
}
/**
- * @see #getWinAttributeBits(boolean, boolean)
+ * @see #getExclusiveWinAttributeBits(boolean, boolean, boolean, boolean)
*/
- public static final int getWinAttributeBits(GLCapabilitiesImmutable caps) {
- return getWinAttributeBits(caps.isOnscreen(), caps.isPBuffer());
+ public static final int getExclusiveWinAttributeBits(GLCapabilitiesImmutable caps) {
+ return getExclusiveWinAttributeBits(caps.isOnscreen(), caps.isFBO(), caps.isPBuffer(), caps.isBitmap());
}
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public static final boolean addGLCapabilitiesPermutations(ArrayList capsBucket, GLCapabilitiesImmutable temp, int winattrbits) {
- int preSize = capsBucket.size();
- if( 0 != ( WINDOW_BIT & winattrbits ) ) {
- GLCapabilities cpy = (GLCapabilities) temp.cloneMutable();
- cpy.setOnscreen(true);
- capsBucket.add(cpy);
- }
- if( 0 != ( PBUFFER_BIT & winattrbits ) ) {
- GLCapabilities cpy = (GLCapabilities) temp.cloneMutable();
- cpy.setPBuffer(true);
- capsBucket.add(cpy);
+ public static final GLCapabilities fixWinAttribBitsAndHwAccel(AbstractGraphicsDevice device, int winattrbits, GLCapabilities caps) {
+ caps.setBitmap ( 0 != ( BITMAP_BIT & winattrbits ) );
+ caps.setPBuffer ( 0 != ( PBUFFER_BIT & winattrbits ) );
+ caps.setFBO ( 0 != ( FBO_BIT & winattrbits ) );
+ // we reflect availability semantics, hence setting onscreen at last (maybe overwritten above)!
+ caps.setOnscreen( 0 != ( WINDOW_BIT & winattrbits ) );
+
+ final int accel = GLContext.isHardwareRasterizer( device, caps.getGLProfile() );
+ if(0 == accel && caps.getHardwareAccelerated() ) {
+ caps.setHardwareAccelerated(false);
}
- if( 0 != ( BITMAP_BIT & winattrbits ) ) {
- GLCapabilities cpy = (GLCapabilities) temp.cloneMutable();
- cpy.setOnscreen(false);
- cpy.setPBuffer(false);
- capsBucket.add(cpy);
+
+ return caps;
+ }
+
+ /**
+ * Fixes the requested {@link GLCapabilitiesImmutable} according to on- and offscreen usage.
+ * <p>
+ * No modification will be made for onscreen usage, for offscreen usage see
+ * {@link #fixOffscreenGLCapabilities(GLCapabilitiesImmutable, GLDrawableFactory, AbstractGraphicsDevice)}.
+ * </p>
+ * @param capsRequested the requested {@link GLCapabilitiesImmutable}
+ * @param factory the {@link GLDrawableFactory} used to validate the requested capabilities and later used to create the drawable.
+ * @param device the device on which the drawable will be created, maybe null for the {@link GLDrawableFactory#getDefaultDevice() default device}.
+ * @return either the given requested {@link GLCapabilitiesImmutable} instance if no modifications were required, or a modified {@link GLCapabilitiesImmutable} instance.
+ */
+ public static GLCapabilitiesImmutable fixGLCapabilities(GLCapabilitiesImmutable capsRequested,
+ GLDrawableFactory factory, AbstractGraphicsDevice device) {
+ if( !capsRequested.isOnscreen() ) {
+ return fixOffscreenGLCapabilities(capsRequested, factory, device);
}
- return capsBucket.size() > preSize;
+ return capsRequested;
}
- public static GLCapabilitiesImmutable fixGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean pbufferAvailable)
+ public static GLCapabilitiesImmutable fixOnscreenGLCapabilities(GLCapabilitiesImmutable capsRequested)
{
- if( !capsRequested.isOnscreen() ) {
- return fixOffScreenGLCapabilities(capsRequested, pbufferAvailable);
+ if( !capsRequested.isOnscreen() || capsRequested.isFBO() || capsRequested.isPBuffer() || capsRequested.isBitmap() ) {
+ // fix caps ..
+ final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
+ caps2.setBitmap (false);
+ caps2.setPBuffer (false);
+ caps2.setFBO (false);
+ caps2.setOnscreen(true);
+ return caps2;
}
return capsRequested;
}
- public static GLCapabilitiesImmutable fixOffScreenGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean pbufferAvailable)
+ public static GLCapabilitiesImmutable fixOffscreenBitOnly(GLCapabilitiesImmutable capsRequested)
{
- if( capsRequested.getDoubleBuffered() ||
- capsRequested.isOnscreen() ||
- ( !pbufferAvailable && capsRequested.isPBuffer() ) )
+ if( capsRequested.isOnscreen() ) {
+ // fix caps ..
+ final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
+ caps2.setOnscreen(false);
+ return caps2;
+ }
+ return capsRequested;
+ }
+
+ /**
+ * Fixes the requested {@link GLCapabilitiesImmutable} according to:
+ * <ul>
+ * <li>offscreen usage</li>
+ * <li>availability of FBO, PBuffer, Bitmap</li>
+ * <li>{@link GLRendererQuirks}</li>
+ * </ul>
+ * @param capsRequested the requested {@link GLCapabilitiesImmutable}
+ * @param factory the {@link GLDrawableFactory} used to validate the requested capabilities and later used to create the drawable.
+ * @param device the device on which the drawable will be created, maybe null for the {@link GLDrawableFactory#getDefaultDevice() default device}.
+ * @return either the given requested {@link GLCapabilitiesImmutable} instance if no modifications were required, or a modified {@link GLCapabilitiesImmutable} instance.
+ */
+ public static GLCapabilitiesImmutable fixOffscreenGLCapabilities(GLCapabilitiesImmutable capsRequested,
+ GLDrawableFactory factory, AbstractGraphicsDevice device) {
+ if(null == device) {
+ device = factory.getDefaultDevice();
+ }
+ final GLProfile glp = capsRequested.getGLProfile();
+ final boolean fboAvailable = GLContext.isFBOAvailable(device, glp);
+ final boolean pbufferAvailable = factory.canCreateGLPbuffer(device, glp);
+
+ final GLRendererQuirks glrq = factory.getRendererQuirks(device);
+ final boolean bitmapAvailable;
+ final boolean doubleBufferAvailable;
+
+ if(null != glrq) {
+ bitmapAvailable = !glrq.exist(GLRendererQuirks.NoOffscreenBitmap);
+ if( capsRequested.getDoubleBuffered() &&
+ ( capsRequested.isPBuffer() && glrq.exist(GLRendererQuirks.NoDoubleBufferedPBuffer) ) ||
+ ( capsRequested.isBitmap() && glrq.exist(GLRendererQuirks.NoDoubleBufferedBitmap) ) ) {
+ doubleBufferAvailable = false;
+ } else {
+ doubleBufferAvailable = true;
+ }
+ } else {
+ bitmapAvailable = true;
+ doubleBufferAvailable = true;
+ }
+
+ final boolean auto = !( fboAvailable && capsRequested.isFBO() ) &&
+ !( pbufferAvailable && capsRequested.isPBuffer() ) &&
+ !( bitmapAvailable && capsRequested.isBitmap() ) ;
+
+ final boolean useFBO = fboAvailable && ( auto || capsRequested.isFBO() ) ;
+ final boolean usePbuffer = !useFBO && pbufferAvailable && ( auto || capsRequested.isPBuffer() ) ;
+ final boolean useBitmap = !useFBO && !usePbuffer && bitmapAvailable && ( auto || capsRequested.isBitmap() ) ;
+
+ if( capsRequested.isOnscreen() ||
+ useFBO != capsRequested.isFBO() ||
+ usePbuffer != capsRequested.isPBuffer() ||
+ useBitmap != capsRequested.isBitmap() ||
+ !doubleBufferAvailable && capsRequested.getDoubleBuffered() )
{
// fix caps ..
- GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
- caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN
+ final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
caps2.setOnscreen(false);
- if(caps2.isPBuffer() && !pbufferAvailable) {
- caps2.setPBuffer(false);
+ caps2.setFBO( useFBO );
+ caps2.setPBuffer( usePbuffer );
+ caps2.setBitmap( useBitmap );
+ if( !doubleBufferAvailable ) {
+ caps2.setDoubleBuffered(false);
}
return caps2;
}
@@ -137,28 +252,81 @@ public class GLGraphicsConfigurationUtil {
public static GLCapabilitiesImmutable fixGLPBufferGLCapabilities(GLCapabilitiesImmutable capsRequested)
{
- if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || !capsRequested.isPBuffer()) {
+ if( capsRequested.isOnscreen() ||
+ !capsRequested.isPBuffer() ||
+ capsRequested.isFBO() )
+ {
// fix caps ..
- GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
- caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN - we don't need to be single buffered ..
+ final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
caps2.setOnscreen(false);
+ caps2.setFBO(false);
caps2.setPBuffer(true);
+ caps2.setBitmap(false);
return caps2;
}
return capsRequested;
}
- public static GLCapabilitiesImmutable fixOpaqueGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean isOpaque)
+ /** Fix opaque setting while preserve alpha bits */
+ public static GLCapabilities fixOpaqueGLCapabilities(GLCapabilities capsRequested, boolean isOpaque)
{
- GLCapabilities caps2 = null;
-
if( capsRequested.isBackgroundOpaque() != isOpaque) {
- // fix caps ..
- caps2 = (GLCapabilities) capsRequested.cloneMutable();
- caps2.setBackgroundOpaque(isOpaque);
+ final int alphaBits = capsRequested.getAlphaBits();
+ capsRequested.setBackgroundOpaque(isOpaque);
+ capsRequested.setAlphaBits(alphaBits);
+ }
+ return capsRequested;
+ }
+
+ /** Fix double buffered setting */
+ public static GLCapabilitiesImmutable fixDoubleBufferedGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean doubleBuffered)
+ {
+ if( capsRequested.getDoubleBuffered() != doubleBuffered) {
+ final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
+ caps2.setDoubleBuffered(doubleBuffered);
return caps2;
}
return capsRequested;
}
-
+
+ public static GLCapabilitiesImmutable clipRGBAGLCapabilities(GLCapabilitiesImmutable caps, boolean allowRGB555, boolean allowAlpha)
+ {
+ final int iR = caps.getRedBits();
+ final int iG = caps.getGreenBits();
+ final int iB = caps.getBlueBits();
+ final int iA = caps.getAlphaBits();
+ final int oR = clipColor(iR, allowRGB555);
+ final int oG = clipColor(iG, allowRGB555);
+ final int oB = clipColor(iB, allowRGB555);
+ final int oA = ( allowAlpha && 0 < iA ) ? oR : 0 ; // align alpha to red if requested and allowed
+ if( iR != oR || iG != oG || iB != oB || iA != oA ) {
+ final GLCapabilities caps2 = (GLCapabilities) caps.cloneMutable();
+ caps2.setRedBits(oR);
+ caps2.setGreenBits(oG);
+ caps2.setBlueBits(oB);
+ caps2.setAlphaBits(oA);
+ return caps2;
+ }
+ return caps;
+ }
+
+ public static int clipColor(final int compIn, final boolean allowRGB555) {
+ final int compOut;
+ if( 5 < compIn || !allowRGB555 ) {
+ compOut = 8;
+ } else {
+ compOut = 5;
+ }
+ return compOut;
+ }
+
+ public static GLCapabilitiesImmutable fixGLProfile(GLCapabilitiesImmutable caps, GLProfile glp)
+ {
+ if( caps.getGLProfile() != glp ) {
+ final GLCapabilities caps2 = (GLCapabilities) caps.cloneMutable();
+ caps2.setGLProfile(glp);
+ return caps2;
+ }
+ return caps;
+ }
}