diff options
Diffstat (limited to 'src/jogl')
34 files changed, 1802 insertions, 1005 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java index 7a8e41cce..c597e5d88 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java @@ -40,15 +40,17 @@ package com.jogamp.opengl.impl; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + import com.jogamp.common.os.DynamicLookupHelper; import com.jogamp.common.util.ReflectionUtil; import com.jogamp.gluegen.runtime.FunctionAddressResolver; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLExtensionNames; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Map; + import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; @@ -556,15 +558,9 @@ public abstract class GLContextImpl extends GLContext { ctp |= CTX_PROFILE_COMPAT ; } - // FIXME GL3GL4: - // To avoid OpenGL implementation bugs and raise compatibility - // within JOGL, we map to the proper GL version. - // This may change later when GL3 and GL4 drivers become more mature! - // Bug: To ensure GL profile compatibility within the JOGL application - // Bug: we always try to map against the highest GL version, - // Bug: so the use can always cast to a higher one - // Bug: int majorMax=GLContext.getMaxMajor(); - // Bug: int minorMax=GLContext.getMaxMinor(majorMax); + // To ensure GL profile compatibility within the JOGL application + // we always try to map against the highest GL version, + // so the user can always cast to the highest available one. int majorMax, minorMax; int majorMin, minorMin; int major[] = new int[1]; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java index 01e0b8298..32a4f5e70 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java @@ -165,7 +165,6 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { // fix caps .. GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable(); caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN - caps2.setOnscreen(false); caps2.setPBuffer(true); capsChosen = caps2; } else { @@ -175,7 +174,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { GLDrawableImpl drawable = null; device.lock(); try { - drawable = (GLDrawableImpl) createGLDrawable( createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, height, height) ); + drawable = (GLDrawableImpl) createGLDrawable( createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height) ); } finally { device.unlock(); } @@ -207,20 +206,8 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { if(null == device) { throw new GLException("No shared device for requested: "+deviceReq); } - GLCapabilitiesImmutable capsChosen; + GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffScreenGLCapabilities(capsRequested, canCreateGLPbuffer(deviceReq)); - if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || capsRequested.isPBuffer()) { - // fix caps .. - GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable(); - caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN - caps2.setOnscreen(false); - if(caps2.isPBuffer() && !canCreateGLPbuffer(device)) { - caps2.setPBuffer(false); - } - capsChosen = caps2; - } else { - capsChosen = capsRequested; - } device.lock(); try { return createGLDrawable( createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height) ); @@ -233,25 +220,12 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) { - GLCapabilitiesImmutable capsChosen; - AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq); if(null == device) { throw new GLException("No shared device for requested: "+deviceReq); } + GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffScreenGLCapabilities(capsRequested, canCreateGLPbuffer(deviceReq)); - if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || capsRequested.isPBuffer()) { - // fix caps .. - GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable(); - caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN - caps2.setOnscreen(false); - if(caps2.isPBuffer() && !canCreateGLPbuffer(device)) { - caps2.setPBuffer(false); - } - capsChosen = caps2; - } else { - capsChosen = capsRequested; - } device.lock(); try { return createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactoryImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactory.java index 4dae603c7..62770daf8 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactoryImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactory.java @@ -28,16 +28,27 @@ package com.jogamp.opengl.impl; +import java.util.List; import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.GraphicsConfigurationFactory; import javax.media.nativewindow.NativeWindowException; import javax.media.opengl.DefaultGLCapabilitiesChooser; -public abstract class GLGraphicsConfigurationFactoryImpl extends GraphicsConfigurationFactory { +public abstract class GLGraphicsConfigurationFactory extends GraphicsConfigurationFactory { + + protected static int chooseCapabilities(CapabilitiesChooser chooser, CapabilitiesImmutable capsRequested, + List /*<CapabilitiesImmutable>*/ availableCaps, int recommendedIndex) { + if (null == capsRequested) { + throw new NativeWindowException("Null requested capabilities"); + } + if ( 0 == availableCaps.size() ) { + if (DEBUG) { + System.err.println("Empty available capabilities"); + } + return -1; // none available + } - protected static int chooseCapabilities(CapabilitiesChooser chooser, - CapabilitiesImmutable capsRequested, CapabilitiesImmutable[] availableCaps, int recommendedIndex) { if(null == chooser && 0 <= recommendedIndex) { if (DEBUG) { System.err.println("chooseCapabilities: Using recommendedIndex: idx " + recommendedIndex); @@ -66,10 +77,10 @@ public abstract class GLGraphicsConfigurationFactoryImpl extends GraphicsConfigu // keep on going .. // seek first available one .. - for (chosenIndex = 0; chosenIndex < availableCaps.length && availableCaps[chosenIndex] == null; chosenIndex++) { + for (chosenIndex = 0; chosenIndex < availableCaps.size() && availableCaps.get(chosenIndex) == null; chosenIndex++) { // nop } - if (chosenIndex == availableCaps.length) { + if (chosenIndex == availableCaps.size()) { // give up .. if (DEBUG) { System.err.println("chooseCapabilities: Failed .. nothing available, bail out"); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationUtil.java b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationUtil.java new file mode 100644 index 000000000..53d42259a --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationUtil.java @@ -0,0 +1,133 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions 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. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.impl; + +import java.util.ArrayList; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; + +public class GLGraphicsConfigurationUtil { + 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 StringBuffer winAttributeBits2String(StringBuffer sb, int winattrbits) { + if(null==sb) { + sb = new StringBuffer(); + } + boolean seperator = false; + if( 0 != ( WINDOW_BIT & winattrbits ) ) { + sb.append("WINDOW"); + seperator=true; + } + if( 0 != ( BITMAP_BIT & winattrbits ) ) { + if(seperator) { + sb.append(", "); + } + sb.append("BITMAP"); + seperator=true; + } + if( 0 != ( PBUFFER_BIT & winattrbits ) ) { + if(seperator) { + sb.append(", "); + } + sb.append("PBUFFER"); + } + 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) { + int winattrbits = 0; + if(isOnscreen) { + winattrbits |= WINDOW_BIT; + } else if (!isPBuffer) { + winattrbits |= BITMAP_BIT; + } else { + winattrbits |= PBUFFER_BIT; + } + return winattrbits; + } + + /** + * @see #getWinAttributeBits(boolean, boolean) + */ + public static final int getWinAttributeBits(GLCapabilitiesImmutable caps) { + return getWinAttributeBits(caps.isOnscreen(), caps.isPBuffer()); + } + + 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); + } + if( 0 != ( BITMAP_BIT & winattrbits ) ) { + GLCapabilities cpy = (GLCapabilities) temp.cloneMutable(); + cpy.setOnscreen(false); + cpy.setPBuffer(false); + capsBucket.add(cpy); + } + return capsBucket.size() > preSize; + } + + public static GLCapabilitiesImmutable fixGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean pbufferAvailable) + { + if( !capsRequested.isOnscreen() ) { + return fixOffScreenGLCapabilities(capsRequested, pbufferAvailable); + } + return capsRequested; + } + public static GLCapabilitiesImmutable fixOffScreenGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean pbufferAvailable) + { + if( capsRequested.getDoubleBuffered() || + capsRequested.isOnscreen() || + ( !pbufferAvailable && capsRequested.isPBuffer() ) ) + { + // fix caps .. + GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable(); + caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN + caps2.setOnscreen(false); + if(caps2.isPBuffer() && !pbufferAvailable) { + caps2.setPBuffer(false); + } + return caps2; + } + return capsRequested; + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java index f451cb9bc..c32f2f22c 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java @@ -37,13 +37,16 @@ package com.jogamp.opengl.impl.egl; import javax.media.nativewindow.*; +import javax.media.nativewindow.egl.EGLGraphicsDevice; import javax.media.opengl.*; + import com.jogamp.common.JogampRuntimeException; import com.jogamp.common.util.*; import com.jogamp.opengl.impl.*; import com.jogamp.nativewindow.impl.ProxySurface; + import java.util.HashMap; -import javax.media.nativewindow.egl.EGLGraphicsDevice; +import java.util.List; public class EGLDrawableFactory extends GLDrawableFactoryImpl { @@ -166,6 +169,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { return null; } + SharedResource getOrCreateSharedResource(AbstractGraphicsDevice device) { + return (SharedResource) getOrCreateShared(device); + } + public GLDynamicLookupHelper getGLDynamicLookupHelper(int esProfile) { if (2==esProfile) { if(null==eglES2DynamicLookupHelper) { @@ -184,6 +191,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { protected final void shutdownInstance() {} + protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) { + return EGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device); + } + protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGLCapabilities.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGLCapabilities.java new file mode 100644 index 000000000..db6d485e3 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGLCapabilities.java @@ -0,0 +1,96 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions 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. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.impl.egl; + +import java.util.Comparator; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; + +public class EGLGLCapabilities extends GLCapabilities { + long eglcfg; + int eglcfgid; + + /** Comparing EGLConfig ID only */ + public static class EglCfgIDComparator implements Comparator { + + public int compare(Object o1, Object o2) { + if ( ! ( o1 instanceof EGLGLCapabilities ) ) { + Class c = (null != o1) ? o1.getClass() : null ; + throw new ClassCastException("arg1 not a EGLGLCapabilities object: " + c); + } + if ( ! ( o2 instanceof EGLGLCapabilities ) ) { + Class c = (null != o2) ? o2.getClass() : null ; + throw new ClassCastException("arg2 not a EGLGLCapabilities object: " + c); + } + + final EGLGLCapabilities caps1 = (EGLGLCapabilities) o1; + final long id1 = caps1.getEGLConfigID(); + + final EGLGLCapabilities caps2 = (EGLGLCapabilities) o2; + final long id2 = caps2.getEGLConfigID(); + + if(id1 > id2) { + return 1; + } else if(id1 < id2) { + return -1; + } + return 0; + } + } + + public EGLGLCapabilities(long eglcfg, int eglcfgid, GLProfile glp) { + super(glp); + this.eglcfg = eglcfg; + this.eglcfgid = eglcfgid; + } + + public Object cloneMutable() { + return clone(); + } + + public Object clone() { + try { + return super.clone(); + } catch (RuntimeException e) { + throw new GLException(e); + } + } + + final public long getEGLConfig() { return eglcfg; } + final public int getEGLConfigID() { return eglcfgid; } + + public StringBuffer toString(StringBuffer sink) { + if(null == sink) { + sink = new StringBuffer(); + } + sink.append("0x").append(Long.toHexString(eglcfgid)).append(": "); + return super.toString(sink); + } +}
\ No newline at end of file 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 b655fc511..eca324046 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java @@ -36,31 +36,29 @@ package com.jogamp.opengl.impl.egl; -import com.jogamp.common.nio.PointerBuffer; -import com.jogamp.common.util.ReflectionUtil; +import java.util.ArrayList; import javax.media.nativewindow.*; import javax.media.nativewindow.egl.*; import javax.media.opengl.*; +import com.jogamp.common.nio.PointerBuffer; +import com.jogamp.common.util.ReflectionUtil; import com.jogamp.opengl.impl.*; public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable { protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); - public long getNativeConfig() { - return config; + public final long getNativeConfig() { + return ((EGLGLCapabilities)capabilitiesChosen).getEGLConfig(); } - public int getNativeConfigID() { - return configID; + public final int getNativeConfigID() { + return ((EGLGLCapabilities)capabilitiesChosen).getEGLConfigID(); } EGLGraphicsConfiguration(AbstractGraphicsScreen absScreen, - GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, - long cfg, int cfgID) { + EGLGLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { super(absScreen, capsChosen, capsRequested); this.chooser = chooser; - config = cfg; - configID = cfgID; } public static EGLGraphicsConfiguration create(GLCapabilitiesImmutable capsRequested, AbstractGraphicsScreen absScreen, int cfgID) { @@ -74,8 +72,8 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple } GLProfile glp = capsRequested.getGLProfile(); long cfg = EGLConfigId2EGLConfig(glp, dpy, cfgID); - GLCapabilitiesImmutable caps = EGLConfig2Capabilities(glp, dpy, cfg, false, capsRequested.isOnscreen(), capsRequested.isPBuffer()); - return new EGLGraphicsConfiguration(absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser(), cfg, cfgID); + EGLGLCapabilities caps = EGLConfig2Capabilities(glp, dpy, cfg, false, capsRequested.isOnscreen(), capsRequested.isPBuffer()); + return new EGLGraphicsConfiguration(absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser()); } public Object clone() { @@ -89,8 +87,6 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple if(null!=newConfig) { // FIXME: setScreen( ... ); setChosenCapabilities(newConfig.getChosenCapabilities()); - config = newConfig.getNativeConfig(); - configID = newConfig.getNativeConfigID(); if(DEBUG) { System.err.println("!!! updateGraphicsConfiguration: "+this); } @@ -116,27 +112,61 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple return configs.get(0); } - static boolean EGLConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) { - boolean res; + static int EGLConfigDrawableTypeBits(final long display, final long config) { + int val = 0; - if ( onscreen ) { - res = ( 0 != (val & EGL.EGL_WINDOW_BIT) ) ; - } else { - if ( usePBuffer ) { - res = ( 0 != (val & EGL.EGL_PBUFFER_BIT) ) ; - } else { - res = ( 0 != (val & EGL.EGL_PIXMAP_BIT) ) ; - } + int[] stype = new int[1]; + if(! EGL.eglGetConfigAttrib(display, config, EGL.EGL_SURFACE_TYPE, stype, 0)) { + throw new GLException("Could not determine EGL_SURFACE_TYPE !!!"); } - return res; + if ( 0 != ( stype[0] & EGL.EGL_WINDOW_BIT ) ) { + val |= GLGraphicsConfigurationUtil.WINDOW_BIT; + } + if ( 0 != ( stype[0] & EGL.EGL_PIXMAP_BIT ) ) { + val |= GLGraphicsConfigurationUtil.BITMAP_BIT; + } + if ( 0 != ( stype[0] & EGL.EGL_PBUFFER_BIT ) ) { + val |= GLGraphicsConfigurationUtil.PBUFFER_BIT; + } + + return val; } - public static GLCapabilitiesImmutable EGLConfig2Capabilities(GLProfile glp, long display, long config, + public static EGLGLCapabilities EGLConfig2Capabilities(GLProfile glp, long display, long config, boolean relaxed, boolean onscreen, boolean usePBuffer) { - GLCapabilities caps = new GLCapabilities(glp); + ArrayList bucket = new ArrayList(); + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + if( EGLConfig2Capabilities(bucket, glp, display, config, winattrmask) ) { + return (EGLGLCapabilities) bucket.get(0); + } else if ( relaxed && EGLConfig2Capabilities(bucket, glp, display, config, GLGraphicsConfigurationUtil.ALL_BITS) ) { + return (EGLGLCapabilities) bucket.get(0); + } + return null; + } + + public static boolean EGLConfig2Capabilities(ArrayList capsBucket, + GLProfile glp, long display, long config, + int winattrmask) { + final int allDrawableTypeBits = EGLConfigDrawableTypeBits(display, config); + final int drawableTypeBits = winattrmask & allDrawableTypeBits; + + if( 0 == drawableTypeBits ) { + return false; + } + int[] val = new int[1]; + // get the configID + if(!EGL.eglGetConfigAttrib(display, config, EGL.EGL_CONFIG_ID, val, 0)) { + if(DEBUG) { + // FIXME: this happens on a ATI PC Emulation .. + System.err.println("EGL couldn't retrieve ConfigID for config "+toHexString(config)+", error "+toHexString(EGL.eglGetError())); + } + return false; + } + GLCapabilities caps = new EGLGLCapabilities(config, val[0], glp); + // Read the actual configuration into the choosen caps if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_RED_SIZE, val, 0)) { caps.setRedBits(val[0]); @@ -178,26 +208,7 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple caps.setTransparentAlphaValue(val[0]==EGL.EGL_DONT_CARE?-1:val[0]); } */ } - if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_SURFACE_TYPE, val, 0)) { - if(EGLConfigDrawableTypeVerify(val[0], onscreen, usePBuffer)) { - caps.setDoubleBuffered(onscreen); - caps.setOnscreen(onscreen); - caps.setPBuffer(usePBuffer); - } else if(relaxed) { - caps.setDoubleBuffered( 0 != (val[0] & EGL.EGL_WINDOW_BIT) ); - caps.setOnscreen( 0 != (val[0] & EGL.EGL_WINDOW_BIT) ); - caps.setPBuffer ( 0 != (val[0] & EGL.EGL_PBUFFER_BIT) ); - } else { - if(DEBUG) { - 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 !!!"); - } - - return caps; + return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, caps, drawableTypeBits ); } public static int[] GLCapabilities2AttribList(GLCapabilitiesImmutable caps) { @@ -289,7 +300,7 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple } public String toString() { - return ReflectionUtil.getBaseName(getClass())+"["+getScreen()+", eglConfigID 0x"+Integer.toHexString(configID)+ + return ReflectionUtil.getBaseName(getClass())+"["+getScreen()+", eglConfigID "+toHexString(getNativeConfigID())+ ",\n\trequested " + getRequestedCapabilities()+ ",\n\tchosen " + getChosenCapabilities()+ "]"; @@ -297,7 +308,5 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple } private GLCapabilitiesChooser chooser; - private long config; - private int configID; } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java index ff6e025a8..3e3d4f964 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java @@ -33,7 +33,6 @@ package com.jogamp.opengl.impl.egl; -import java.io.PrintStream; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.AbstractGraphicsScreen; @@ -41,18 +40,22 @@ import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.DefaultGraphicsScreen; import javax.media.nativewindow.GraphicsConfigurationFactory; -import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.egl.EGLGraphicsDevice; -import javax.media.opengl.DefaultGLCapabilitiesChooser; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; +import javax.media.opengl.GLDrawableFactory; import com.jogamp.common.nio.PointerBuffer; -import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; +import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.io.PrintStream; /** Subclass of GraphicsConfigurationFactory used when non-AWT tookits @@ -60,8 +63,9 @@ import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; to this one to change the accepted and returned types of the GraphicsDevice and GraphicsConfiguration abstractions. */ -public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { +public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = GraphicsConfigurationFactory.DEBUG || com.jogamp.opengl.impl.Debug.debug("EGL"); + static EGLGLCapabilities.EglCfgIDComparator EglCfgIDComparator = new EGLGLCapabilities.EglCfgIDComparator(); EGLGraphicsConfigurationFactory() { // become the selector for KD/EGL .. @@ -94,6 +98,41 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact absScreen); } + protected static List/*<EGLGLCapabilities>*/ getAvailableCapabilities(EGLDrawableFactory factory, AbstractGraphicsDevice device) { + EGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device); + if(null == sharedResource) { + throw new GLException("Shared resource for device n/a: "+device); + } + EGLGraphicsDevice eglDevice = sharedResource.getDevice(); + long eglDisplay = eglDevice.getHandle(); + + List/*<EGLGLCapabilities>*/ availableCaps = null; + int[] maxConfigs = new int[1]; + + if(!EGL.eglGetConfigs(eglDisplay, null, 0, maxConfigs, 0)) { + throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError())); + } + if(0 == maxConfigs[0]) { + throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) no configs"); + } + + PointerBuffer configs = PointerBuffer.allocateDirect(maxConfigs[0]); + int[] numConfigs = new int[1]; + + if(!EGL.eglGetConfigs(eglDisplay, configs, configs.capacity(), numConfigs, 0)) { + throw new GLException("Graphics configuration get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError())); + } + if (numConfigs[0] > 0) { + GLProfile glp = GLProfile.getDefault(device); + availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], GLGraphicsConfigurationUtil.ALL_BITS); + if( null != availableCaps ) { + Collections.sort(availableCaps, EglCfgIDComparator); + } + } + + return availableCaps; + } + private static EGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsReq, GLCapabilitiesChooser chooser, @@ -101,7 +140,6 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact if (capsChosen == null) { capsChosen = new GLCapabilities(null); } - GLProfile glp = capsChosen.getGLProfile(); if(null==absScreen) { throw new GLException("Null AbstractGraphicsScreen"); @@ -117,12 +155,10 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact throw new GLException("Invalid EGL display: "+absDevice); } - if(!capsChosen.isOnscreen() && capsChosen.getDoubleBuffered()) { - // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN - GLCapabilities caps2 = (GLCapabilities) capsChosen.cloneMutable(); - caps2.setDoubleBuffered(false); - capsChosen = caps2; - } + EGLDrawableFactory factory = (EGLDrawableFactory) GLDrawableFactory.getEGLFactory(); + capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory.canCreateGLPbuffer(absDevice) ); + + GLProfile glp = capsChosen.getGLProfile(); EGLGraphicsConfiguration res = eglChooseConfig(eglDisplay, capsChosen, capsReq, chooser, absScreen); if(null!=res) { @@ -132,43 +168,6 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact System.err.println("eglChooseConfig failed with given capabilities "+capsChosen); } - if (chooser == null) { - chooser = new DefaultGLCapabilitiesChooser(); - } - - PointerBuffer configs = PointerBuffer.allocateDirect(10); - int[] numConfigs = new int[1]; - - if(!EGL.eglGetConfigs(eglDisplay, configs, configs.capacity(), numConfigs, 0)) { - throw new GLException("Graphics configuration fetch (eglGetConfigs) failed"); - } - if (numConfigs[0] == 0) { - throw new GLException("Graphics configuration fetch (eglGetConfigs) - no EGLConfig found"); - } - GLCapabilitiesImmutable[] caps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], - capsChosen.isOnscreen(), capsChosen.isPBuffer()); - if(DEBUG) { - System.err.println("EGL Get Configs: "+numConfigs[0]+", Caps "+caps.length); - printCaps("eglGetConfigs", caps, System.err); - } - int chosen = -1; - try { - chosen = chooser.chooseCapabilities(capsChosen, caps, -1); - } catch (NativeWindowException e) { throw new GLException(e); } - if(chosen<0) { - throw new GLException("Graphics configuration chooser failed"); - } - if(DEBUG) { - System.err.println("Chosen "+caps[chosen]); - } - res = eglChooseConfig(eglDisplay, caps[chosen], capsReq, chooser, absScreen); - if(null!=res) { - return res; - } - if(DEBUG) { - System.err.println("eglChooseConfig failed with eglGetConfig/choosen capabilities "+caps[chosen]); - } - // Last try .. add a fixed embedded profile [ATI, Nokia, Intel, ..] // // rgb888 - d16, s4 @@ -222,73 +221,100 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact } static EGLGraphicsConfiguration eglChooseConfig(long eglDisplay, - GLCapabilitiesImmutable capsChosen0, GLCapabilitiesImmutable capsRequested, + GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { - GLProfile glp = capsChosen0.getGLProfile(); - int[] attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen0); - PointerBuffer configs = PointerBuffer.allocateDirect(1); + GLProfile glp = capsChosen.getGLProfile(); + boolean onscreen = capsChosen.isOnscreen(); + boolean usePBuffer = capsChosen.isPBuffer(); + List/*<EGLGLCapabilities>*/ availableCaps = null; + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + int recommendedIndex = -1; + long recommendedEGLConfig = -1; + int[] maxConfigs = new int[1]; + + if(!EGL.eglGetConfigs(eglDisplay, null, 0, maxConfigs, 0)) { + throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError())); + } + if(0 == maxConfigs[0]) { + throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) no configs"); + } + if (DEBUG) { + System.err.println("!!! eglChooseConfig maxConfigs: "+maxConfigs[0]); + } + + int[] attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen); + PointerBuffer configs = PointerBuffer.allocateDirect(maxConfigs[0]); int[] numConfigs = new int[1]; + + // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice if (!EGL.eglChooseConfig(eglDisplay, attrs, 0, configs, configs.capacity(), numConfigs, 0)) { - throw new GLException("Graphics configuration selection (eglChooseConfig) failed for "+capsChosen0); + throw new GLException("Graphics configuration selection (eglChooseConfig) failed for "+capsChosen+", error "+toHexString(EGL.eglGetError())); } if (numConfigs[0] > 0) { - if(DEBUG) { - GLCapabilitiesImmutable[] caps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], - capsChosen0.isOnscreen(), capsChosen0.isPBuffer()); - System.err.println("EGL Choose Configs: "+numConfigs[0]+", Caps "+caps.length); - printCaps("eglChooseConfig", caps, System.err); - } - int[] val = new int[1]; - // get the configID - if(!EGL.eglGetConfigAttrib(eglDisplay, configs.get(0), EGL.EGL_CONFIG_ID, val, 0)) { - if(DEBUG) { - // FIXME: this happens on a ATI PC Emulation .. - System.err.println("EGL couldn't retrieve ConfigID for already chosen eglConfig "+capsChosen0+", error 0x"+Integer.toHexString(EGL.eglGetError())); + availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], winattrmask); + if(availableCaps.size() > 0) { + recommendedEGLConfig = configs.get(0); + recommendedIndex = 0; + if (DEBUG) { + System.err.println("!!! eglChooseConfig recommended fbcfg " + toHexString(recommendedEGLConfig) + ", idx " + recommendedIndex); + System.err.println("!!! user caps " + capsChosen); + System.err.println("!!! fbcfg caps " + availableCaps.get(recommendedIndex)); } - return null; + } else if (DEBUG) { + System.err.println("!!! eglChooseConfig no caps for recommended fbcfg " + toHexString(configs.get(0))); + System.err.println("!!! user caps " + capsChosen); } - GLCapabilitiesImmutable capsChosen1 = EGLGraphicsConfiguration.EGLConfig2Capabilities( - glp, eglDisplay, configs.get(0), - true, capsChosen0.isOnscreen(), capsChosen0.isPBuffer()); - if(null!=capsChosen1) { - if(DEBUG) { - System.err.println("eglChooseConfig found: eglDisplay 0x"+Long.toHexString(eglDisplay)+ - ", eglConfig ID 0x"+Integer.toHexString(val[0])+ - ", "+capsChosen0+" -> "+capsChosen1); - } - return new EGLGraphicsConfiguration(absScreen, capsChosen1, capsRequested, chooser, configs.get(0), val[0]); + } + + // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available + if( null == availableCaps || 0 == availableCaps.size() ) { + // reset .. + recommendedEGLConfig = -1; + recommendedIndex = -1; + + if(!EGL.eglGetConfigs(eglDisplay, configs, configs.capacity(), numConfigs, 0)) { + throw new GLException("Graphics configuration get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError())); } - if(DEBUG) { - System.err.println("eglChooseConfig couldn't verify: eglDisplay 0x"+Long.toHexString(eglDisplay)+ - ", eglConfig ID 0x"+Integer.toHexString(val[0])+ - ", for "+capsChosen0); + if (numConfigs[0] > 0) { + availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], winattrmask); } - } else { + } + + if( null == availableCaps || 0 == availableCaps.size() ) { if(DEBUG) { - System.err.println("EGL Choose Configs: None using eglDisplay 0x"+Long.toHexString(eglDisplay)+ - ", "+capsChosen0); + // FIXME: this happens on a ATI PC Emulation .. + System.err.println("Graphics configuration 1st choice and 2nd choice failed - no configs"); } + return null; } - return null; + + int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + if ( 0 > chosenIndex ) { + if (DEBUG) { + Thread.dumpStack(); + } + return null; + } + EGLGLCapabilities chosenCaps = (EGLGLCapabilities) availableCaps.get(chosenIndex); + + return new EGLGraphicsConfiguration(absScreen, chosenCaps, capsRequested, chooser); } - static GLCapabilitiesImmutable[] eglConfigs2GLCaps(GLProfile glp, long eglDisplay, PointerBuffer configs, int num, - boolean onscreen, boolean usePBuffer) { - GLCapabilitiesImmutable[] caps = new GLCapabilitiesImmutable[num]; + static List/*<GLCapabilitiesImmutable>*/ eglConfigs2GLCaps(GLProfile glp, long eglDisplay, PointerBuffer configs, int num, int winattrmask) { + ArrayList caps = new ArrayList(num); for(int i=0; i<num; i++) { - caps[i] = EGLGraphicsConfiguration.EGLConfig2Capabilities(glp, eglDisplay, configs.get(i), - true, onscreen, usePBuffer); + EGLGraphicsConfiguration.EGLConfig2Capabilities(caps, glp, eglDisplay, configs.get(i), winattrmask); } return caps; } - static void printCaps(String prefix, GLCapabilitiesImmutable[] caps, PrintStream out) { - for(int i=0; i<caps.length; i++) { - out.println(prefix+"["+i+"] "+caps[i]); + static void printCaps(String prefix, List/*GLCapabilitiesImmutable*/ caps, PrintStream out) { + for(int i=0; i<caps.size(); i++) { + out.println(prefix+"["+i+"] "+caps.get(i)); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Type_Widget.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Type_Widget.java index b329840ef..0aeca8f1c 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Type_Widget.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Type_Widget.java @@ -56,7 +56,9 @@ public class Type_Widget { /** Creates a new instance of Type_Widget */ public Type_Widget() { - buffer = ByteBuffer.allocateDirect( 4 ); + // can't make this direct, because JVM doesn't allocate small direct buffers efficiently + // see https://jogamp.org/bugzilla/show_bug.cgi?id=463 for details + buffer = ByteBuffer.allocate( 4 ); } public void setUB0( byte b ) { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java index 1895c8e67..421bae715 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java @@ -41,14 +41,17 @@ package com.jogamp.opengl.impl.macosx.cgl; import java.nio.*; +import java.util.HashMap; +import java.util.List; + import javax.media.nativewindow.*; +import javax.media.nativewindow.macosx.MacOSXGraphicsDevice; import javax.media.opengl.*; + import com.jogamp.common.JogampRuntimeException; import com.jogamp.common.util.*; import com.jogamp.opengl.impl.*; import com.jogamp.nativewindow.impl.ProxySurface; -import java.util.HashMap; -import javax.media.nativewindow.macosx.MacOSXGraphicsDevice; public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { private static final DesktopGLDynamicLookupHelper macOSXCGLDynamicLookupHelper; @@ -123,6 +126,10 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { protected final void shutdownInstance() {} + protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) { + throw new UnsupportedOperationException("not yet implemented"); + } + protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java index f12f5d31a..cc06a6775 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java @@ -33,7 +33,7 @@ package com.jogamp.opengl.impl.macosx.cgl; -import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.CapabilitiesChooser; @@ -48,7 +48,7 @@ import javax.media.opengl.GLCapabilitiesImmutable; to this one to change the accepted and returned types of the GraphicsDevice and GraphicsConfiguration abstractions. */ -public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { +public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); MacOSXCGLGraphicsConfigurationFactory() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java index e4249f9c8..95b6f473f 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java @@ -33,7 +33,7 @@ package com.jogamp.opengl.impl.macosx.cgl.awt; -import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; @@ -55,7 +55,7 @@ import javax.media.opengl.GLException; import com.jogamp.opengl.impl.macosx.cgl.MacOSXCGLGraphicsConfiguration; -public class MacOSXAWTCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { +public class MacOSXAWTCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); public MacOSXAWTCGLGraphicsConfigurationFactory() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WGLGLCapabilities.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WGLGLCapabilities.java new file mode 100644 index 000000000..b5be4bf8d --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WGLGLCapabilities.java @@ -0,0 +1,243 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions 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. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.impl.windows.wgl; + +import java.util.Comparator; + +import com.jogamp.nativewindow.impl.windows.GDI; +import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR; +import javax.media.opengl.GL; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; + +public class WGLGLCapabilities extends GLCapabilities { + PIXELFORMATDESCRIPTOR pfd; + int pfdID; + int arb_pixelformat; // -1 PFD, 0 NOP, 1 ARB + + /** Comparing pfd id only */ + public static class PfdIDComparator implements Comparator { + + public int compare(Object o1, Object o2) { + if ( ! ( o1 instanceof WGLGLCapabilities ) ) { + Class c = (null != o1) ? o1.getClass() : null ; + throw new ClassCastException("arg1 not a WGLGLCapabilities object: " + c); + } + if ( ! ( o2 instanceof WGLGLCapabilities ) ) { + Class c = (null != o2) ? o2.getClass() : null ; + throw new ClassCastException("arg2 not a WGLGLCapabilities object: " + c); + } + + final WGLGLCapabilities caps1 = (WGLGLCapabilities) o1; + final long id1 = caps1.getPFDID(); + + final WGLGLCapabilities caps2 = (WGLGLCapabilities) o2; + final long id2 = caps2.getPFDID(); + + if(id1 > id2) { + return 1; + } else if(id1 < id2) { + return -1; + } + return 0; + } + } + + public WGLGLCapabilities(PIXELFORMATDESCRIPTOR pfd, int pfdID, GLProfile glp) { + super(glp); + this.pfd = pfd; + this.pfdID = pfdID; + this.arb_pixelformat = 0; + } + + public boolean setValuesByGDI() { + arb_pixelformat = -1; + + setRedBits(pfd.getCRedBits()); + setGreenBits(pfd.getCGreenBits()); + setBlueBits(pfd.getCBlueBits()); + setAlphaBits(pfd.getCAlphaBits()); + setAccumRedBits(pfd.getCAccumRedBits()); + setAccumGreenBits(pfd.getCAccumGreenBits()); + setAccumBlueBits(pfd.getCAccumBlueBits()); + setAccumAlphaBits(pfd.getCAccumAlphaBits()); + setDepthBits(pfd.getCDepthBits()); + setStencilBits(pfd.getCStencilBits()); + setDoubleBuffered((pfd.getDwFlags() & GDI.PFD_DOUBLEBUFFER) != 0); + setStereo((pfd.getDwFlags() & GDI.PFD_STEREO) != 0); + setHardwareAccelerated((pfd.getDwFlags() & GDI.PFD_GENERIC_FORMAT) == 0 + || (pfd.getDwFlags() & GDI.PFD_GENERIC_ACCELERATED) != 0); + // n/a with non ARB/GDI method: + // multisample + // opaque + // pbuffer + + return true; + } + + public boolean setValuesByARB(final int[] iattribs, final int niattribs, final int[] iresults) { + arb_pixelformat = 1; + + for (int i = 0; i < niattribs; i++) { + int attr = iattribs[i]; + switch (attr) { + case WGLExt.WGL_DRAW_TO_WINDOW_ARB: + case WGLExt.WGL_DRAW_TO_BITMAP_ARB: + case WGLExt.WGL_DRAW_TO_PBUFFER_ARB: + break; + + case WGLExt.WGL_ACCELERATION_ARB: + setHardwareAccelerated(iresults[i] == WGLExt.WGL_FULL_ACCELERATION_ARB); + break; + + case WGLExt.WGL_SUPPORT_OPENGL_ARB: + if (iresults[i] != GL.GL_TRUE) { + return false; + } + break; + + case WGLExt.WGL_DEPTH_BITS_ARB: + setDepthBits(iresults[i]); + break; + + case WGLExt.WGL_STENCIL_BITS_ARB: + setStencilBits(iresults[i]); + break; + + case WGLExt.WGL_DOUBLE_BUFFER_ARB: + setDoubleBuffered(iresults[i] == GL.GL_TRUE); + break; + + case WGLExt.WGL_STEREO_ARB: + setStereo(iresults[i] == GL.GL_TRUE); + break; + + case WGLExt.WGL_PIXEL_TYPE_ARB: + // Fail softly with unknown results here + if (iresults[i] == WGLExt.WGL_TYPE_RGBA_ARB || + iresults[i] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) { + setPbufferFloatingPointBuffers(true); + } + break; + + case WGLExt.WGL_FLOAT_COMPONENTS_NV: + if (iresults[i] != 0) { + setPbufferFloatingPointBuffers(true); + } + break; + + case WGLExt.WGL_RED_BITS_ARB: + setRedBits(iresults[i]); + break; + + case WGLExt.WGL_GREEN_BITS_ARB: + setGreenBits(iresults[i]); + break; + + case WGLExt.WGL_BLUE_BITS_ARB: + setBlueBits(iresults[i]); + break; + + case WGLExt.WGL_ALPHA_BITS_ARB: + setAlphaBits(iresults[i]); + break; + + case WGLExt.WGL_ACCUM_RED_BITS_ARB: + setAccumRedBits(iresults[i]); + break; + + case WGLExt.WGL_ACCUM_GREEN_BITS_ARB: + setAccumGreenBits(iresults[i]); + break; + + case WGLExt.WGL_ACCUM_BLUE_BITS_ARB: + setAccumBlueBits(iresults[i]); + break; + + case WGLExt.WGL_ACCUM_ALPHA_BITS_ARB: + setAccumAlphaBits(iresults[i]); + break; + + case WGLExt.WGL_SAMPLE_BUFFERS_ARB: + setSampleBuffers(iresults[i] != 0); + break; + + case WGLExt.WGL_SAMPLES_ARB: + setNumSamples(iresults[i]); + break; + + default: + throw new GLException("Unknown pixel format attribute " + iattribs[i]); + } + } + return true; + } + + public Object cloneMutable() { + return clone(); + } + + public Object clone() { + try { + return super.clone(); + } catch (RuntimeException e) { + throw new GLException(e); + } + } + + final public PIXELFORMATDESCRIPTOR getPFD() { return pfd; } + final public int getPFDID() { return pfdID; } + + final public boolean isSetByARB() { return 0 < arb_pixelformat; } + final public boolean isSetByGDI() { return 0 > arb_pixelformat; } + final public boolean isSet() { return 0 != arb_pixelformat; } + + public StringBuffer toString(StringBuffer sink) { + if(null == sink) { + sink = new StringBuffer(); + } + sink.append(pfdID).append(" "); + switch (arb_pixelformat) { + case -1: + sink.append("gdi"); + break; + case 0: + sink.append("nop"); + break; + case 1: + sink.append("arb"); + break; + default: + throw new InternalError("invalid arb_pixelformat: " + arb_pixelformat); + } + sink.append(": "); + return super.toString(sink); + } +}
\ No newline at end of file diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java index f2f65622b..a307e295d 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java @@ -89,7 +89,6 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable { caps.setDepthBits(16); caps.setDoubleBuffered(true); caps.setOnscreen (true); - caps.setPBuffer (true); return new WindowsDummyWGLDrawable(factory, caps, absScreen); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java index 41889e703..720ac84ca 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java @@ -50,7 +50,6 @@ import javax.media.opengl.GLPbuffer; import javax.media.opengl.GLProfile; import com.jogamp.nativewindow.impl.windows.GDI; -import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR; import javax.media.opengl.GLCapabilitiesImmutable; public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { @@ -174,96 +173,57 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { throw new GLException("pbuffer creation error: Couldn't find a suitable pixel format"); } - boolean haveMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample"); - if (DEBUG) { System.err.println("" + nformats + " suitable pixel formats found"); - // query pixel format - iattributes[0] = WGLExt.WGL_RED_BITS_ARB; - iattributes[1] = WGLExt.WGL_GREEN_BITS_ARB; - iattributes[2] = WGLExt.WGL_BLUE_BITS_ARB; - iattributes[3] = WGLExt.WGL_ALPHA_BITS_ARB; - iattributes[4] = WGLExt.WGL_DEPTH_BITS_ARB; - iattributes[5] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE_ARB : WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS_ARB); - iattributes[6] = (haveMultisample ? WGLExt.WGL_SAMPLE_BUFFERS_ARB : WGLExt.WGL_RED_BITS_ARB); - iattributes[7] = (haveMultisample ? WGLExt.WGL_SAMPLES_ARB : WGLExt.WGL_RED_BITS_ARB); - iattributes[8] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB; - int[] ivalues = new int[9]; for (int i = 0; i < nformats; i++) { - if (!wglExt.wglGetPixelFormatAttribivARB(parentHdc, pformats[i], 0, 9, iattributes, 0, ivalues, 0)) { - throw new GLException("Error while querying pixel format " + pformats[i] + - "'s (index " + i + "'s) capabilities for debugging"); - } - System.err.print("pixel format " + pformats[i] + " (index " + i + "): "); - System.err.print( "r: " + ivalues[0]); - System.err.print(" g: " + ivalues[1]); - System.err.print(" b: " + ivalues[2]); - System.err.print(" a: " + ivalues[3]); - System.err.print(" depth: " + ivalues[4]); - if (haveMultisample) { - System.err.print(" multisample: " + ivalues[6]); - } - System.err.print(" samples: " + ivalues[7]); - if (useFloat) { - if (ati) { - if (ivalues[5] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) { - System.err.print(" [ati float]"); - } else if (ivalues[5] != WGLExt.WGL_TYPE_RGBA_ARB) { - System.err.print(" [unknown pixel type " + ivalues[5] + "]"); - } - } else { - if (ivalues[5] != 0) { - System.err.print(" [float]"); - } - } - } - - if (ivalues[8] != 0) { - System.err.print(" [pbuffer]"); - } - System.err.println(); + WGLGLCapabilities dbgCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedCtx, parentHdc, pformats[i], glProfile, false, true); + System.err.println("pixel format " + pformats[i] + " (index " + i + "): " + dbgCaps); } } + int pfdid = 0; long tmpBuffer = 0; - int whichFormat = -1; - // Loop is a workaround for bugs in NVidia's recent drivers - for (whichFormat = 0; whichFormat < nformats; whichFormat++) { - int format = pformats[whichFormat]; - - // Create the p-buffer. - niattribs = 0; - - if (rtt) { - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FORMAT_ARB; - if (useFloat) { - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FLOAT_RGB_NV; - } else { - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_RGBA_ARB; - } + { + int whichFormat; + // Loop is a workaround for bugs in NVidia's recent drivers + for (whichFormat = 0; whichFormat < nformats; whichFormat++) { + int format = pformats[whichFormat]; + + // Create the p-buffer. + niattribs = 0; + + if (rtt) { + iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FORMAT_ARB; + if (useFloat) { + iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FLOAT_RGB_NV; + } else { + iattributes[niattribs++] = WGLExt.WGL_TEXTURE_RGBA_ARB; + } - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_TARGET_ARB; - iattributes[niattribs++] = rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D_ARB; + iattributes[niattribs++] = WGLExt.WGL_TEXTURE_TARGET_ARB; + iattributes[niattribs++] = rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D_ARB; - iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE_ARB; - iattributes[niattribs++] = GL.GL_FALSE; + iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE_ARB; + iattributes[niattribs++] = GL.GL_FALSE; - iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB; - iattributes[niattribs++] = GL.GL_FALSE; - } + iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB; + iattributes[niattribs++] = GL.GL_FALSE; + } - iattributes[niattribs++] = 0; + iattributes[niattribs++] = 0; - tmpBuffer = wglExt.wglCreatePbufferARB(parentHdc, format, getWidth(), getHeight(), iattributes, 0); - if (tmpBuffer != 0) { - // Done - break; - } - } + tmpBuffer = wglExt.wglCreatePbufferARB(parentHdc, format, getWidth(), getHeight(), iattributes, 0); + if (tmpBuffer != 0) { + // Done + break; + } + } - if (tmpBuffer == 0) { - throw new GLException("pbuffer creation error: wglCreatePbuffer() failed: tried " + nformats + - " pixel formats, last error was: " + wglGetLastError()); + if (0 == tmpBuffer) { + throw new GLException("pbuffer creation error: wglCreatePbuffer() failed: tried " + nformats + + " pixel formats, last error was: " + wglGetLastError()); + } + pfdid = pformats[whichFormat]; } // Get the device context. @@ -280,48 +240,14 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { // Re-query chosen pixel format { - niattribs = 0; - iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB; - iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB; - iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB; - iattributes[niattribs++] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE_ARB : WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS_ARB); - iattributes[niattribs++] = (haveMultisample ? WGLExt.WGL_SAMPLE_BUFFERS_ARB : WGLExt.WGL_RED_BITS_ARB); - iattributes[niattribs++] = (haveMultisample ? WGLExt.WGL_SAMPLES_ARB : WGLExt.WGL_RED_BITS_ARB); - iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB; - int[] ivalues = new int[niattribs]; - if (wglExt.wglGetPixelFormatAttribivARB(parentHdc, pformats[whichFormat], 0, niattribs, iattributes, 0, ivalues, 0)) { - GLCapabilitiesImmutable newCaps = WindowsWGLGraphicsConfiguration.AttribList2GLCapabilities(glProfile, iattributes, niattribs, ivalues, false, true); - if(null == newCaps|| newCaps.isOnscreen() || !newCaps.isPBuffer()) { - throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps); - } - PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); - if (GDI.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) { - if (DEBUG) { - System.err.println("Unable to describe pixel format (Continue: true) " + whichFormat + "/" + nformats + " pfdID " + pformats[whichFormat]+":\n\t"+newCaps); - } - } - config.setCapsPFD(newCaps, pfd, pformats[whichFormat], true); - } else { - PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); - if (GDI.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) { - throw new GLException("Unable to describe pixel format " + pformats[whichFormat]); - } - GLCapabilitiesImmutable newCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, false, true); - if(newCaps.isOnscreen()) { - throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps+"\n\t"+newCaps); - } - config.setCapsPFD(newCaps, pfd, pformats[whichFormat], false); + WGLGLCapabilities newCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedCtx, parentHdc, pfdid, glProfile, false, true); + if(null == newCaps) { + throw new GLException("pbuffer creation error: unable to re-query chosen PFD ID: " + pfdid + ", hdc " + this.toHexString(tmpHdc)); + } + if(newCaps.isOnscreen() || !newCaps.isPBuffer()) { + throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps); } + config.setCapsPFD(newCaps); } // Determine the actual width and height we were able to create. diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java index 0b4933db8..7d38f8ee8 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java @@ -48,6 +48,7 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.opengl.GLContext; import javax.media.opengl.GLException; +import javax.media.opengl.GLCapabilitiesImmutable; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; @@ -55,8 +56,6 @@ import com.jogamp.nativewindow.impl.windows.GDI; import com.jogamp.opengl.impl.GLContextImpl; import com.jogamp.opengl.impl.GLContextShareSet; import com.jogamp.opengl.impl.GLDrawableImpl; -import javax.media.opengl.GLCapabilitiesImmutable; - public class WindowsWGLContext extends GLContextImpl { static final Map/*<String, String>*/ functionNameMap; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java index ac71d6e9c..674690e50 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java @@ -53,6 +53,8 @@ import javax.media.nativewindow.DefaultGraphicsScreen; import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.windows.WindowsGraphicsDevice; +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawable; @@ -71,8 +73,6 @@ import com.jogamp.opengl.impl.GLDrawableFactoryImpl; import com.jogamp.opengl.impl.GLDrawableImpl; import com.jogamp.opengl.impl.GLDynamicLookupHelper; import com.jogamp.opengl.impl.SharedResourceRunner; -import javax.media.nativewindow.AbstractGraphicsConfiguration; -import javax.media.opengl.GLCapabilitiesImmutable; public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { private static final DesktopGLDynamicLookupHelper windowsWGLDynamicLookupHelper; @@ -179,13 +179,13 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { canCreateGLPbuffer = canPbuffer; readDrawableAvailable = readBufferAvail; } - public AbstractGraphicsDevice getDevice() { return device; } - public AbstractGraphicsScreen getScreen() { return screen; } - public GLDrawableImpl getDrawable() { return drawable; } - public GLContextImpl getContext() { return context; } + final public AbstractGraphicsDevice getDevice() { return device; } + final public AbstractGraphicsScreen getScreen() { return screen; } + final public GLDrawableImpl getDrawable() { return drawable; } + final public GLContextImpl getContext() { return context; } - boolean canCreateGLPbuffer() { return canCreateGLPbuffer; } - boolean isReadDrawableAvailable() { return readDrawableAvailable; } + final boolean canCreateGLPbuffer() { return canCreateGLPbuffer; } + final boolean isReadDrawableAvailable() { return readDrawableAvailable; } } class SharedResourceImplementation implements SharedResourceRunner.Implementation { @@ -218,7 +218,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { if (null == absScreen) { throw new GLException("Couldn't create shared screen for device: "+sharedDevice+", idx 0"); } - GLProfile glp = GLProfile.getDefault(sharedDevice); + GLProfile glp = GLProfile.getMinDesktop(sharedDevice); if (null == glp) { throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice); } @@ -330,7 +330,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return null; } - protected WindowsWGLDrawable getSharedDrawable(AbstractGraphicsDevice device) { + protected WindowsWGLDrawable getOrCreateSharedDrawable(AbstractGraphicsDevice device) { SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); if(null!=sr) { return (WindowsWGLDrawable) sr.getDrawable(); @@ -338,11 +338,19 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return null; } + SharedResource getOrCreateSharedResource(AbstractGraphicsDevice device) { + return (SharedResource) sharedResourceRunner.getOrCreateShared(device); + } + protected final void shutdownInstance() { sharedResourceRunner.releaseAndWait(); RegisteredClassFactory.shutdownSharedClasses(); } + protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) { + return WindowsWGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device); + } + protected final GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); 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 0ff1832d1..36d78b38d 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 @@ -33,11 +33,15 @@ package com.jogamp.opengl.impl.windows.wgl; +import java.util.ArrayList; +import java.util.List; + import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.DefaultGraphicsConfiguration; import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.opengl.GL; -import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; @@ -47,8 +51,7 @@ import javax.media.opengl.GLProfile; import com.jogamp.nativewindow.impl.windows.GDI; import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR; import com.jogamp.opengl.impl.GLContextImpl; -import javax.media.nativewindow.AbstractGraphicsDevice; -import javax.media.opengl.GLCapabilitiesImmutable; +import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil; public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable { // Keep this under the same debug flag as the drawable factory for convenience @@ -60,28 +63,21 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio protected static final int MAX_PFORMATS = 256; protected static final int MAX_ATTRIBS = 256; - private PIXELFORMATDESCRIPTOR pixelfmt; - private int pixelfmtID; private GLCapabilitiesChooser chooser; private boolean isChosen = false; - private boolean choosenByARBPixelFormat=false; WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { super(screen, capsChosen, capsRequested); - this.pixelfmt = null; - this.pixelfmtID = -1; this.chooser=chooser; - isChosen = false; - choosenByARBPixelFormat=false; + this.isChosen = false; } WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen, - GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, - PIXELFORMATDESCRIPTOR pixelfmt, int pixelfmtID, boolean choosenByARBPixelFormat) { + WGLGLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested) { super(screen, capsChosen, capsRequested); - setCapsPFD(capsChosen, pixelfmt, pixelfmtID, choosenByARBPixelFormat); + setCapsPFD(capsChosen); this.chooser=null; } @@ -106,8 +102,7 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device); boolean hasARB = null != sharedContext && sharedContext.isExtensionAvailable(WGL_ARB_pixel_format) ; - GLCapabilitiesImmutable caps = null; - PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); // PFD storage + WGLGLCapabilities caps = null; if(hasARB) { sharedContext.makeCurrent(); @@ -116,18 +111,14 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio } finally { sharedContext.release(); } - } else { - caps = PFD2GLCapabilities(glp, hdc, pfdID, onscreen, usePBuffer, pfd); + } else if(!usePBuffer) { + caps = PFD2GLCapabilities(glp, hdc, pfdID, onscreen); } if(null==caps) { throw new GLException("Couldn't choose Capabilities by: HDC 0x"+Long.toHexString(hdc)+", pfdID "+pfdID+", hasARB "+hasARB); } - if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { - throw new GLException("Unable to describe pixel format " + pfdID); - } - - return new WindowsWGLGraphicsConfiguration(screen, caps, caps, pfd, pfdID, hasARB); + return new WindowsWGLGraphicsConfiguration(screen, caps, caps); } public Object clone() { @@ -164,24 +155,18 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio WindowsWGLGraphicsConfigurationFactory.preselectGraphicsConfiguration(chooser, factory, device, this, pfdIDs); } - final void setCapsPFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd, int pfdID, boolean choosenByARBPixelFormat) { - this.pixelfmt = pfd; - this.pixelfmtID = pfdID; + final void setCapsPFD(WGLGLCapabilities caps) { setChosenCapabilities(caps); this.isChosen=true; - this.choosenByARBPixelFormat=choosenByARBPixelFormat; if (DEBUG) { - System.err.println("*** setCapsPFD: ARB-Choosen "+choosenByARBPixelFormat+", pfdID "+pfdID+", "+caps); + System.err.println("*** setCapsPFD: "+caps); } } - public final boolean isDetermined() { - return isChosen; - } - - public final PIXELFORMATDESCRIPTOR getPixelFormat() { return pixelfmt; } - public final int getPixelFormatID() { return pixelfmtID; } - public final boolean isChoosenByWGL() { return choosenByARBPixelFormat; } + public final boolean isDetermined() { return isChosen; } + public final PIXELFORMATDESCRIPTOR getPixelFormat() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).getPFD() : null; } + public final int getPixelFormatID() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).getPFDID() : 0; } + public final boolean isChoosenByARB() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).isSetByARB() : false; } static int fillAttribsForGeneralWGLARBQuery(boolean haveWGLARBMultisample, int[] iattributes) { int niattribs = 0; @@ -207,6 +192,10 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB; iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB; } + // pbo float buffer + iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB; // ati + iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV; // nvidia + return niattribs; } @@ -251,8 +240,8 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return pfdIDs; } - static GLCapabilitiesImmutable wglARBPFID2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int pfdID, - GLProfile glp, boolean onscreen, boolean usePBuffer) { + static WGLGLCapabilities wglARBPFID2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int pfdID, + GLProfile glp, boolean onscreen, boolean usePBuffer) { boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format); if (!haveWGLChoosePixelFormatARB) { return null; @@ -265,10 +254,14 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio int niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes); if (!sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, 0, iresults, 0)) { - throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID + " of device context"); + throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID + " of device context"); } - return AttribList2GLCapabilities(glp, iattributes, niattribs, iresults, - onscreen, usePBuffer); + ArrayList bucket = new ArrayList(1); + final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + if(AttribList2GLCapabilities(bucket, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits)) { + return (WGLGLCapabilities) bucket.get(0); + } + return null; } static int[] wglChoosePixelFormatARB(long hdc, WindowsWGLContext sharedContext, @@ -300,8 +293,11 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return null; } int numFormats = numFormatsTmp[0]; - int[] pformats = new int[numFormats]; - System.arraycopy(pformatsTmp, 0, pformats, 0, numFormats); + int[] pformats = null; + if( 0 < numFormats ) { + pformats = new int[numFormats]; + System.arraycopy(pformatsTmp, 0, pformats, 0, numFormats); + } if (DEBUG) { System.err.println("wglChoosePixelFormatARB1: NumFormats (wglChoosePixelFormatARB) accelMode 0x" + Integer.toHexString(accelerationMode) + ": " + numFormats); @@ -309,97 +305,43 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return pformats; } - static GLCapabilitiesImmutable[] wglARBPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs, - GLProfile glp, boolean onscreen, boolean usePBuffer) { + static List /*<GLCapabilitiesImmutable>*/ wglARBPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs, + GLProfile glp, boolean onscreen, boolean usePBuffer) { + final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + return wglARBPFIDs2GLCapabilitiesImpl(sharedCtx, hdc, pfdIDs, glp, winattrbits); + } + + static List /*<GLCapabilitiesImmutable>*/ wglARBPFIDs2AllGLCapabilities(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs, + GLProfile glp) { + return wglARBPFIDs2GLCapabilitiesImpl(sharedCtx, hdc, pfdIDs, glp, GLGraphicsConfigurationUtil.ALL_BITS); + } + + private static List /*<GLCapabilitiesImmutable>*/ wglARBPFIDs2GLCapabilitiesImpl(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs, + GLProfile glp, int winattrbits) { boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format); if (!haveWGLChoosePixelFormatARB) { return null; } boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable(WGL_ARB_multisample); final int numFormats = pfdIDs.length; - GLCapabilitiesImmutable[] caps = new GLCapabilitiesImmutable[numFormats]; - int[] iattributes = new int [2*MAX_ATTRIBS]; - int[] iresults = new int [2*MAX_ATTRIBS]; + int[] iattributes = new int [2*MAX_ATTRIBS]; + int[] iresults = new int [2*MAX_ATTRIBS]; int niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes); + ArrayList bucket = new ArrayList(); + for(int i = 0; i<numFormats; i++) { if ( pfdIDs[i] >= 1 && sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) { - caps[i] = AttribList2GLCapabilities(glp, iattributes, niattribs, iresults, onscreen, usePBuffer); - } else { - if (DEBUG) { - System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " + - i + "/" + numFormats + ": " + pfdIDs[i]); - } - caps[i] = null; + AttribList2GLCapabilities(bucket, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits); + } else if (DEBUG) { + System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " + + i + "/" + numFormats + ": " + pfdIDs[i] + ", " + + GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString()); } } - return caps; - } - - /** - * - * @param sharedCtx - * @param hdc - * @param glp - * @param onscreen - * @param usePBuffer - * @param pfIDs stores the PIXELFORMAT ID for the GLCapabilitiesImmutable[] - * @return the resulting GLCapabilitiesImmutable[] - */ - static GLCapabilitiesImmutable[] wglARBAllPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, - GLProfile glp, boolean onscreen, boolean usePBuffer, int[] pfIDs) { - boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format); - if (!haveWGLChoosePixelFormatARB) { - return null; - } - boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable(WGL_ARB_multisample); - - // Produce a list of GLCapabilities to give to the - // GLCapabilitiesChooser. - // Use wglGetPixelFormatAttribivARB instead of - // DescribePixelFormat to get higher-precision information - // about the pixel format (should make the GLCapabilities - // more precise as well...i.e., remove the - // "HardwareAccelerated" bit, which is basically - // meaningless, and put in whether it can render to a - // window, to a pbuffer, or to a pixmap) - GLCapabilitiesImmutable[] availableCaps = null; - int numFormats = 0; - int niattribs = 0; - int[] iattributes = new int[2 * MAX_ATTRIBS]; - int[] iresults = new int[2 * MAX_ATTRIBS]; - - WGLExt wglExt = sharedCtx.getWGLExt(); - iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB; - if (wglExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) { - numFormats = iresults[0]; - if (DEBUG) { - System.err.println("wglARBAllPFIDs2GLCapabilities: wglGetPixelFormatAttribivARB reported WGL_NUMBER_PIXEL_FORMATS = " + numFormats + ", pfIDs sz "+pfIDs.length); - } - if (numFormats > pfIDs.length) { - numFormats = pfIDs.length; - } - - niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes); - - availableCaps = new GLCapabilitiesImmutable[numFormats]; - for (int i = 0; i < numFormats; i++) { - pfIDs[i] = i + 1; - if (!wglExt.wglGetPixelFormatAttribivARB(hdc, pfIDs[i], 0, niattribs, iattributes, 0, iresults, 0)) { - throw new GLException("wglARBAllPFIDs2GLCapabilities: Error getting pixel format attributes for pixel format " + pfIDs[i]); - } - availableCaps[i] = AttribList2GLCapabilities(glp, iattributes, niattribs, iresults, onscreen, usePBuffer); - } - } else { - long lastErr = GDI.GetLastError(); - // Some GPU's falsely fails with a zero error code (success) - if (lastErr != GDI.ERROR_SUCCESS) { - throw new GLException("wglARBAllPFIDs2GLCapabilities: Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + lastErr); - } - } - return availableCaps; + return bucket; } static boolean GLCapabilities2AttribList(GLCapabilitiesImmutable caps, @@ -573,161 +515,50 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return true; } - public static final int WINDOW_BIT = 1 << 0 ; - public static final int BITMAP_BIT = 1 << 1 ; - public static final int PBUFFER_BIT = 1 << 2 ; - - static int WGLConfig2DrawableTypeBits(int[] iattribs, - int niattribs, - int[] iresults) { + static int AttribList2DrawableTypeBits(final int[] iattribs, final int niattribs, final int[] iresults) { int val = 0; for (int i = 0; i < niattribs; i++) { int attr = iattribs[i]; switch (attr) { case WGLExt.WGL_DRAW_TO_WINDOW_ARB: - if(iresults[i] == GL.GL_TRUE) val |= WINDOW_BIT; + if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.WINDOW_BIT; break; case WGLExt.WGL_DRAW_TO_BITMAP_ARB: - if(iresults[i] == GL.GL_TRUE) val |= BITMAP_BIT; + if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.BITMAP_BIT; break; case WGLExt.WGL_DRAW_TO_PBUFFER_ARB: - if(iresults[i] == GL.GL_TRUE) val |= PBUFFER_BIT; + if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.PBUFFER_BIT; break; } } return val; } - static boolean WGLConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) { - boolean res; + static boolean AttribList2GLCapabilities( ArrayList capsBucket, + final GLProfile glp, final long hdc, final int pfdID, final int[] iattribs, + final int niattribs, + final int[] iresults, final int winattrmask) { + final int allDrawableTypeBits = AttribList2DrawableTypeBits(iattribs, niattribs, iresults); + int drawableTypeBits = winattrmask & allDrawableTypeBits; - if ( onscreen ) { - res = ( 0 != (val & WINDOW_BIT) ) ; - } else { - if ( usePBuffer ) { - res = ( 0 != (val & PBUFFER_BIT) ) ; - } else { - res = ( 0 != (val & BITMAP_BIT) ) ; - } + if( 0 == drawableTypeBits ) { + return false; } + PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); - return res; - } - - static GLCapabilitiesImmutable AttribList2GLCapabilities( - GLProfile glp, int[] iattribs, - int niattribs, - int[] iresults, - boolean onscreen, boolean usePBuffer) { - GLCapabilities res = new GLCapabilities(glp); - int drawableTypeBits = WGLConfig2DrawableTypeBits(iattribs, niattribs, iresults); - if(WGLConfigDrawableTypeVerify(drawableTypeBits, onscreen, usePBuffer)) { - res.setOnscreen(onscreen); - res.setPBuffer(usePBuffer); - } else { - 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) )+ - ", bitmap "+( 0 != (drawableTypeBits & BITMAP_BIT))+")"); + if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { + // remove displayable bits, since pfdID is non displayable + drawableTypeBits = drawableTypeBits & ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT); + if( 0 == drawableTypeBits ) { + return false; } - return null; + // non displayable requested (pbuffer) } + WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp); + res.setValuesByARB(iattribs, niattribs, iresults); - for (int i = 0; i < niattribs; i++) { - int attr = iattribs[i]; - switch (attr) { - case WGLExt.WGL_DRAW_TO_WINDOW_ARB: - case WGLExt.WGL_DRAW_TO_BITMAP_ARB: - case WGLExt.WGL_DRAW_TO_PBUFFER_ARB: - break; - - case WGLExt.WGL_ACCELERATION_ARB: - res.setHardwareAccelerated(iresults[i] == WGLExt.WGL_FULL_ACCELERATION_ARB); - break; - - case WGLExt.WGL_SUPPORT_OPENGL_ARB: - if (iresults[i] != GL.GL_TRUE) { - return null; - } - break; - - case WGLExt.WGL_DEPTH_BITS_ARB: - res.setDepthBits(iresults[i]); - break; - - case WGLExt.WGL_STENCIL_BITS_ARB: - res.setStencilBits(iresults[i]); - break; - - case WGLExt.WGL_DOUBLE_BUFFER_ARB: - res.setDoubleBuffered(iresults[i] == GL.GL_TRUE); - break; - - case WGLExt.WGL_STEREO_ARB: - res.setStereo(iresults[i] == GL.GL_TRUE); - break; - - case WGLExt.WGL_PIXEL_TYPE_ARB: - // Fail softly with unknown results here - if (iresults[i] == WGLExt.WGL_TYPE_RGBA_ARB|| - iresults[i] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) { - res.setPbufferFloatingPointBuffers(true); - } - break; - - case WGLExt.WGL_FLOAT_COMPONENTS_NV: - if (iresults[i] != 0) { - res.setPbufferFloatingPointBuffers(true); - } - break; - - case WGLExt.WGL_RED_BITS_ARB: - res.setRedBits(iresults[i]); - break; - - case WGLExt.WGL_GREEN_BITS_ARB: - res.setGreenBits(iresults[i]); - break; - - case WGLExt.WGL_BLUE_BITS_ARB: - res.setBlueBits(iresults[i]); - break; - - case WGLExt.WGL_ALPHA_BITS_ARB: - res.setAlphaBits(iresults[i]); - break; - - case WGLExt.WGL_ACCUM_RED_BITS_ARB: - res.setAccumRedBits(iresults[i]); - break; - - case WGLExt.WGL_ACCUM_GREEN_BITS_ARB: - res.setAccumGreenBits(iresults[i]); - break; - - case WGLExt.WGL_ACCUM_BLUE_BITS_ARB: - res.setAccumBlueBits(iresults[i]); - break; - - case WGLExt.WGL_ACCUM_ALPHA_BITS_ARB: - res.setAccumAlphaBits(iresults[i]); - break; - - case WGLExt.WGL_SAMPLE_BUFFERS_ARB: - res.setSampleBuffers(iresults[i] != 0); - break; - - case WGLExt.WGL_SAMPLES_ARB: - res.setNumSamples(iresults[i]); - break; - - default: - throw new GLException("Unknown pixel format attribute " + iattribs[i]); - } - } - return res; + return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits ); } // @@ -747,39 +578,48 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return pfdIDs; } - static GLCapabilitiesImmutable PFD2GLCapabilities(GLProfile glp, long hdc, int pfdID, boolean onscreen, boolean usePBuffer, PIXELFORMATDESCRIPTOR pfd) { - if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { - throw new GLException("Error describing pixel format " + pfdID + " of device context"); + static int PFD2DrawableTypeBits(PIXELFORMATDESCRIPTOR pfd) { + int val = 0; + + int dwFlags = pfd.getDwFlags(); + + if( 0 != (GDI.PFD_DRAW_TO_WINDOW & dwFlags ) ) { + val |= GLGraphicsConfigurationUtil.WINDOW_BIT; } - return PFD2GLCapabilities(glp, pfd, onscreen, usePBuffer); + if( 0 != (GDI.PFD_DRAW_TO_BITMAP & dwFlags ) ) { + val |= GLGraphicsConfigurationUtil.BITMAP_BIT; + } + return val; } - static GLCapabilitiesImmutable PFD2GLCapabilities(GLProfile glp, PIXELFORMATDESCRIPTOR pfd, boolean onscreen, boolean usePBuffer) { + static WGLGLCapabilities PFD2GLCapabilities(GLProfile glp, long hdc, int pfdID, boolean onscreen) { + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false); + ArrayList capsBucket = new ArrayList(1); + if( PFD2GLCapabilities(capsBucket, glp, hdc, pfdID, winattrmask) ) { + return (WGLGLCapabilities) capsBucket.get(0); + } + return null; + } + + static boolean PFD2GLCapabilities(ArrayList capsBucket, final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) { + PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID); + if(null == pfd) { + return false; + } if ((pfd.getDwFlags() & GDI.PFD_SUPPORT_OPENGL) == 0) { - return null; - } - GLCapabilities res = new GLCapabilities(glp); - res.setRedBits (pfd.getCRedBits()); - res.setGreenBits (pfd.getCGreenBits()); - res.setBlueBits (pfd.getCBlueBits()); - res.setAlphaBits (pfd.getCAlphaBits()); - res.setAccumRedBits (pfd.getCAccumRedBits()); - res.setAccumGreenBits(pfd.getCAccumGreenBits()); - res.setAccumBlueBits (pfd.getCAccumBlueBits()); - res.setAccumAlphaBits(pfd.getCAccumAlphaBits()); - res.setDepthBits (pfd.getCDepthBits()); - res.setStencilBits (pfd.getCStencilBits()); - res.setDoubleBuffered((pfd.getDwFlags() & GDI.PFD_DOUBLEBUFFER) != 0); - res.setStereo ((pfd.getDwFlags() & GDI.PFD_STEREO) != 0); - res.setHardwareAccelerated( (pfd.getDwFlags() & GDI.PFD_GENERIC_FORMAT) == 0 || - (pfd.getDwFlags() & GDI.PFD_GENERIC_ACCELERATED) != 0 ); - res.setOnscreen ( onscreen && ((pfd.getDwFlags() & GDI.PFD_DRAW_TO_WINDOW) != 0) ); - res.setPBuffer ( usePBuffer ); - // n/a with non ARB/GDI method: - // multisample - // opaque - // pbuffer - return res; + return false; + } + final int allDrawableTypeBits = PFD2DrawableTypeBits(pfd); + final int drawableTypeBits = winattrmask & allDrawableTypeBits; + + if( 0 == drawableTypeBits ) { + return false; + } + + WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp); + res.setValuesByGDI(); + + return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits ); } static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd) { @@ -828,15 +668,28 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return pfd; } - static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() { + static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor(long hdc, int pfdID) { PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create(); pfd.setNSize((short) pfd.size()); pfd.setNVersion((short) 1); + if(0 != hdc && 1 <= pfdID) { + if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { + // Accelerated pixel formats that are non displayable + if(DEBUG) { + System.err.println("Info: Non displayable pixel format " + pfdID + " of device context: error code " + GDI.GetLastError()); + } + return null; + } + } return pfd; } + static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() { + return createPixelFormatDescriptor(0, 0); + } + public String toString() { - return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + pixelfmtID + ", ARB-Choosen "+choosenByARBPixelFormat+ + return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + getPixelFormatID() + ", ARB-Choosen " + isChoosenByARB() + ",\n\trequested " + getRequestedCapabilities() + ",\n\tchosen " + getChosenCapabilities() + "]"; 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 0996438db..812829168 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 @@ -43,7 +43,6 @@ import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.NativeWindowFactory; import javax.media.opengl.GLCapabilitiesImmutable; -import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; @@ -51,15 +50,22 @@ import javax.media.opengl.GLProfile; import com.jogamp.nativewindow.impl.windows.GDI; import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR; -import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; +import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil; +import com.jogamp.opengl.impl.SharedResourceRunner; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; /** Subclass of GraphicsConfigurationFactory used when non-AWT tookits are used on Windows platforms. Toolkits will likely need to delegate to this one to change the accepted and returned types of the GraphicsDevice and GraphicsConfiguration abstractions. */ -public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { +public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); + static WGLGLCapabilities.PfdIDComparator PfdIDComparator = new WGLGLCapabilities.PfdIDComparator(); WindowsWGLGraphicsConfigurationFactory() { GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.windows.WindowsGraphicsDevice.class, this); @@ -91,17 +97,67 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat if(null==absScreen) { absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS); } + AbstractGraphicsDevice absDevice = absScreen.getDevice(); - if(!capsChosen.isOnscreen() && capsChosen.getDoubleBuffered()) { - // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN - GLCapabilities caps2 = (GLCapabilities) capsChosen.cloneMutable(); - caps2.setDoubleBuffered(false); - capsChosen = caps2; - } + capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( + capsChosen, GLDrawableFactory.getDesktopFactory().canCreateGLPbuffer(absDevice) ); return new WindowsWGLGraphicsConfiguration( absScreen, capsChosen, capsReq, (GLCapabilitiesChooser)chooser ); } + protected static List/*<WGLGLCapabilities>*/ getAvailableCapabilities(WindowsWGLDrawableFactory factory, AbstractGraphicsDevice device) { + SharedResourceRunner.Resource sharedResource = factory.getOrCreateSharedResource(device); + if(null == sharedResource) { + throw new GLException("Shared resource for device n/a: "+device); + } + WindowsWGLDrawable sharedDrawable = (WindowsWGLDrawable) sharedResource.getDrawable(); + GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities(); + WindowsWGLContext sharedContext = (WindowsWGLContext) sharedResource.getContext(); + List availableCaps = null; + + sharedDrawable.lockSurface(); + try { + long hdc = sharedDrawable.getHandle(); + if (0 == hdc) { + throw new GLException("Error: HDC is null"); + } + if (sharedContext.isExtensionAvailable(WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format)) { + availableCaps = getAvailableGLCapabilitiesARB(hdc, sharedContext, capsChosen.getGLProfile()); + } + if( null == availableCaps || 0 == availableCaps.size() ) { + availableCaps = getAvailableGLCapabilitiesGDI(hdc, capsChosen); + } + } finally { + sharedDrawable.unlockSurface(); + } + + if( null != availableCaps ) { + Collections.sort(availableCaps, PfdIDComparator); + } + return availableCaps; + } + + static List/*<WGLGLCapabilities>*/ getAvailableGLCapabilitiesARB(long hdc, WindowsWGLContext sharedContext, GLProfile glProfile) { + int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs(sharedContext, hdc); + return WindowsWGLGraphicsConfiguration.wglARBPFIDs2AllGLCapabilities(sharedContext, hdc, pformats, glProfile); + } + + static List/*<WGLGLCapabilities>*/ getAvailableGLCapabilitiesGDI(long hdc, GLCapabilitiesImmutable capsChosen) { + boolean onscreen = capsChosen.isOnscreen(); + if(capsChosen.isPBuffer()) { + return null; + } + GLProfile glProfile = capsChosen.getGLProfile(); + + int[] pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc); + int numFormats = pformats.length; + ArrayList bucket = new ArrayList(numFormats); + for (int i = 0; i < numFormats; i++) { + bucket.add( WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pformats[i], onscreen) ); + } + return bucket; + } + /** * * @param chooser @@ -161,7 +217,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat throw new IllegalArgumentException("WindowsWGLGraphicsConfiguration is null"); } WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) _factory; - WindowsWGLDrawable sharedDrawable = factory.getSharedDrawable(device); + WindowsWGLDrawable sharedDrawable = factory.getOrCreateSharedDrawable(device); if(null == sharedDrawable) { throw new IllegalArgumentException("Shared Drawable is null"); } @@ -202,35 +258,35 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } return false; } + if (!sharedContext.isExtensionAvailable(WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format)) { + if (DEBUG) { + System.err.println("updateGraphicsConfigurationARB: "+WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format+" not available"); + } + return false; + } + GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); boolean onscreen = capsChosen.isOnscreen(); boolean usePBuffer = capsChosen.isPBuffer(); GLProfile glProfile = capsChosen.getGLProfile(); - GLCapabilitiesImmutable[] availableCaps = null; // caps array matching PFD ID of pformats array - int pfdID; // chosen or preset PFD ID - GLCapabilitiesImmutable pixelFormatCaps = null; // chosen or preset PFD ID's caps + WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps boolean pixelFormatSet = false; // indicates a preset PFD ID [caps] - if (!sharedContext.isExtensionAvailable(WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format)) { - if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: "+WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format+" not available"); - } - return false; - } sharedContext.makeCurrent(); try { - if ( !extHDC && 1 <= ( pfdID = GDI.GetPixelFormat(hdc) ) ) { + final int presetPFDID = extHDC ? -1 : GDI.GetPixelFormat(hdc) ; + if ( 1 <= presetPFDID ) { // Pixelformat already set by either // - a previous preselectGraphicsConfiguration() call on the same HDC, // - the graphics driver, copying the HDC's pixelformat to the new one, // - or the Java2D/OpenGL pipeline's configuration if (DEBUG) { System.err.println("updateGraphicsConfigurationARB: Pixel format already chosen for HDC: " + toHexString(hdc) - + ", pixelformat " + pfdID); + + ", pixelformat " + presetPFDID); } pixelFormatSet = true; - pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedContext, hdc, pfdID, glProfile, onscreen, usePBuffer); + pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedContext, hdc, presetPFDID, glProfile, onscreen, usePBuffer); } else { int recommendedIndex = -1; // recommended index @@ -242,13 +298,13 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat float[] fattributes = new float[1]; pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedContext, capsChosen, iattributes, -1, fattributes); + if (null != pformats) { recommendedIndex = 0; - if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: NumFormats (wglChoosePixelFormatARB) " + pformats.length); - System.err.println("updateGraphicsConfigurationARB: Used wglChoosePixelFormatARB to recommend pixel format " + pformats[recommendedIndex] + ", idx " + recommendedIndex); - } } else { + if(DEBUG) { + System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB failed with: "+capsChosen); + } // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs(sharedContext, hdc); if (DEBUG) { @@ -262,9 +318,27 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat return false; } } - // translate chosen/all or given PFD IDs - availableCaps = WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedContext, hdc, pformats, - glProfile, onscreen, usePBuffer); + + List /*<WGLGLCapabilities>*/ availableCaps = + WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedContext, hdc, pformats, + glProfile, onscreen, usePBuffer); + if( null == availableCaps || 0 == availableCaps.size() ) { + if (DEBUG) { + System.err.println("updateGraphicsConfigurationARB: wglARBPFIDs2GLCapabilities failed with " + pformats.length + + " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer); + Thread.dumpStack(); + } + return false; + } + + if (DEBUG) { + System.err.println("updateGraphicsConfigurationARB: " + pformats.length + + " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer + ", " + availableCaps.size() + " glcaps"); + if(0 <= recommendedIndex) { + System.err.println("updateGraphicsConfigurationARB: Used wglChoosePixelFormatARB to recommend pixel format " + + pformats[recommendedIndex] + ", idx " + recommendedIndex +", "+availableCaps.get(recommendedIndex)); + } + } int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); if ( 0 > chosenIndex ) { @@ -273,56 +347,52 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } return false; } - pixelFormatCaps = availableCaps[chosenIndex]; - pfdID = pformats[chosenIndex]; + pixelFormatCaps = (WGLGLCapabilities) availableCaps.get(chosenIndex); if( null == pixelFormatCaps) { throw new GLException("Null Capabilities with "+ " chosen pfdID: native recommended "+ (recommendedIndex+1) + - " chosen "+pfdID); + " chosen "+pixelFormatCaps.getPFDID()); } if (DEBUG) { System.err.println("!!! chosen pfdID (ARB): native recommended "+ (recommendedIndex+1) + - " chosen "+pfdID+", caps " + pixelFormatCaps); + " chosen "+pixelFormatCaps); } } } finally { sharedContext.release(); } - PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); - - if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { - throw new GLException("updateGraphicsConfigurationARB: Error describing the chosen pixel format: " + pfdID + ", " + GDI.GetLastError()); - } - if ( !extHDC && !pixelFormatSet ) { - if (!GDI.SetPixelFormat(hdc, pfdID, pfd)) { - throw new GLException("Unable to set pixel format " + pfdID + + if (!GDI.SetPixelFormat(hdc, pixelFormatCaps.getPFDID(), pixelFormatCaps.getPFD())) { + throw new GLException("Unable to set pixel format " + pixelFormatCaps.getPFDID() + " for device context " + toHexString(hdc) + ": error code " + GDI.GetLastError()); } if (DEBUG) { - System.err.println("!!! setPixelFormat (ARB): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> "+pfdID); + System.err.println("!!! setPixelFormat (ARB): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> "+pixelFormatCaps.getPFDID()); } } - config.setCapsPFD(pixelFormatCaps, pfd, pfdID, true); + config.setCapsPFD(pixelFormatCaps); return true; } private static boolean updateGraphicsConfigurationGDI(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser, int[] pformats) { GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + if(capsChosen.isPBuffer()) { + if (DEBUG) { + System.err.println("updateGraphicsConfigurationGDI: no pbuffer supported on GDI: " + capsChosen); + } + return false; + } boolean onscreen = capsChosen.isOnscreen(); - boolean usePBuffer = capsChosen.isPBuffer(); GLProfile glProfile = capsChosen.getGLProfile(); - GLCapabilitiesImmutable[] availableCaps = null; // caps array matching PFD ID of pformats array + ArrayList/*<WGLGLCapabilities>*/ availableCaps = new ArrayList(); int pfdID; // chosen or preset PFD ID - GLCapabilitiesImmutable pixelFormatCaps = null; // chosen or preset PFD ID's caps + WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps boolean pixelFormatSet = false; // indicates a preset PFD ID [caps] - PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); // PFD storage - if ( !extHDC && 1 <= ( pfdID = GDI.GetPixelFormat(hdc) ) ) { // Pixelformat already set by either // - a previous preselectGraphicsConfiguration() call on the same HDC, @@ -333,26 +403,30 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat + ", pixelformat " + pfdID); } pixelFormatSet = true; - pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pfdID, onscreen, usePBuffer, pfd); + pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pfdID, onscreen); } else { if(null == pformats) { pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc); } - int numFormats = pformats.length; - availableCaps = new GLCapabilitiesImmutable[numFormats]; - for (int i = 0; i < numFormats; i++) { - availableCaps[i] = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pformats[i], onscreen, usePBuffer, pfd); + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false); + + for (int i = 0; i < pformats.length; i++) { + WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(availableCaps, glProfile, hdc, pformats[i], winattrmask); } + + // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice + PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capsChosen, pfd); pfdID = GDI.ChoosePixelFormat(hdc, pfd); int recommendedIndex = -1 ; if( 1 <= pfdID ) { // seek index .. - for (recommendedIndex = numFormats - 1 ; - 0 <= recommendedIndex && pfdID != pformats[recommendedIndex]; + for (recommendedIndex = availableCaps.size() - 1 ; + 0 <= recommendedIndex && pfdID != ((WGLGLCapabilities) availableCaps.get(recommendedIndex)).getPFDID(); recommendedIndex--) { /* nop */ } } + // 2nd choice: if no preferred recommendedIndex available if (DEBUG) { System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = " + pfdID + ", idx " + recommendedIndex + " (LastError: " + GDI.GetLastError() + ")"); } @@ -363,44 +437,25 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } return false; } - pixelFormatCaps = availableCaps[chosenIndex]; - pfdID = pformats[chosenIndex]; - if( null == pixelFormatCaps) { - throw new GLException("Null Capabilities with "+ - " chosen pfdID: native recommended "+ (recommendedIndex+1) + - " chosen "+pfdID); - } + pixelFormatCaps = (WGLGLCapabilities) availableCaps.get(chosenIndex); if (DEBUG) { System.err.println("!!! chosen pfdID (GDI): native recommended "+ (recommendedIndex+1) + - " chosen "+pfdID+", caps " + pixelFormatCaps); + ", caps " + pixelFormatCaps); } } - - if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { - throw new GLException("Error describing the chosen pixel format: " + pfdID + ", " + GDI.GetLastError()); - } if ( !extHDC && !pixelFormatSet ) { - if (!GDI.SetPixelFormat(hdc, pfdID, pfd)) { - throw new GLException("Unable to set pixel format " + pfdID + + if (!GDI.SetPixelFormat(hdc, pixelFormatCaps.getPFDID(), pixelFormatCaps.getPFD())) { + throw new GLException("Unable to set pixel format " + pixelFormatCaps.getPFDID() + " for device context " + toHexString(hdc) + ": error code " + GDI.GetLastError()); } if (DEBUG) { - System.err.println("!!! setPixelFormat (GDI): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> "+pfdID); + System.err.println("!!! setPixelFormat (GDI): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> " + pixelFormatCaps.getPFDID()); } } - config.setCapsPFD(pixelFormatCaps, pfd, pfdID, false); + config.setCapsPFD(pixelFormatCaps); return true; - - } - - static String getThreadName() { - return Thread.currentThread().getName(); - } - - static String toHexString(long hex) { - return "0x" + Long.toHexString(hex); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java index 4fbdab9c2..f753c08c5 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java @@ -36,7 +36,7 @@ package com.jogamp.opengl.impl.windows.wgl.awt; import com.jogamp.common.util.ArrayHashSet; import com.jogamp.nativewindow.impl.jawt.windows.Win32SunJDKReflection; -import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; @@ -59,7 +59,7 @@ import javax.media.opengl.GLException; import com.jogamp.opengl.impl.windows.wgl.WindowsWGLGraphicsConfiguration; import javax.media.opengl.GLDrawableFactory; -public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { +public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); public WindowsAWTWGLGraphicsConfigurationFactory() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLCapabilities.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLCapabilities.java new file mode 100644 index 000000000..e3a1e7d72 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLCapabilities.java @@ -0,0 +1,116 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions 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. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.impl.x11.glx; + +import com.jogamp.nativewindow.impl.x11.XVisualInfo; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; +import java.util.Comparator; + +public class X11GLCapabilities extends GLCapabilities { + XVisualInfo xVisualInfo; + long fbcfg; + int fbcfgid; + + /** Comparing xvisual id only */ + public static class XVisualIDComparator implements Comparator { + + public int compare(Object o1, Object o2) { + if ( ! ( o1 instanceof X11GLCapabilities ) ) { + Class c = (null != o1) ? o1.getClass() : null ; + throw new ClassCastException("arg1 not a X11GLCapabilities object: " + c); + } + if ( ! ( o2 instanceof X11GLCapabilities ) ) { + Class c = (null != o2) ? o2.getClass() : null ; + throw new ClassCastException("arg2 not a X11GLCapabilities object: " + c); + } + + final X11GLCapabilities caps1 = (X11GLCapabilities) o1; + final long id1 = caps1.getXVisualID(); + + final X11GLCapabilities caps2 = (X11GLCapabilities) o2; + final long id2 = caps2.getXVisualID(); + + if(id1 > id2) { + return 1; + } else if(id1 < id2) { + return -1; + } + return 0; + } + } + + public X11GLCapabilities(XVisualInfo xVisualInfo, long fbcfg, int fbcfgid, GLProfile glp) { + super(glp); + this.xVisualInfo = xVisualInfo; + this.fbcfg = fbcfg; + this.fbcfgid = fbcfgid; + } + + public X11GLCapabilities(XVisualInfo xVisualInfo, GLProfile glp) { + super(glp); + this.xVisualInfo = xVisualInfo; + this.fbcfg = 0; + this.fbcfgid = -1; + } + + public Object cloneMutable() { + return clone(); + } + + public Object clone() { + try { + return super.clone(); + } catch (RuntimeException e) { + throw new GLException(e); + } + } + + final public XVisualInfo getXVisualInfo() { return xVisualInfo; } + final public long getXVisualID() { return xVisualInfo.getVisualid(); } + + final public long getFBConfig() { return fbcfg; } + final public int getFBConfigID() { return fbcfgid; } + final public boolean isFBConfig() { return 0!=fbcfg && fbcfgid>0; } + + public StringBuffer toString(StringBuffer sink) { + if(null == sink) { + sink = new StringBuffer(); + } + sink.append("0x").append(Long.toHexString(xVisualInfo.getVisualid())).append(" "); + if(isFBConfig()) { + sink.append("0x").append(Integer.toHexString(fbcfgid)); + } else { + sink.append("----"); + } + sink.append(": "); + return super.toString(sink); + } +}
\ No newline at end of file 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 32d70ad6b..dd25f241e 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 @@ -40,11 +40,14 @@ package com.jogamp.opengl.impl.x11.glx; -import com.jogamp.common.util.VersionNumber; import java.nio.*; import java.util.*; + import javax.media.opengl.*; import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.X11GraphicsDevice; + +import com.jogamp.common.util.VersionNumber; import com.jogamp.opengl.impl.*; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; @@ -119,21 +122,23 @@ public abstract class X11GLXContext extends GLContextImpl { protected Map/*<String, String>*/ getExtensionNameMap() { return extensionNameMap; } - public final boolean isGLReadDrawableAvailable() { + public final boolean isGLXVersionGreaterEqualOneThree() { if(null == glXVersion) { X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl(); X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); - AbstractGraphicsDevice device = config.getScreen().getDevice(); + X11GraphicsDevice device = (X11GraphicsDevice) config.getScreen().getDevice(); glXVersion = factory.getGLXVersion(device); - if( null != glXVersion ) { - glXVersionOneThreeCapable = glXVersion.compareTo(factory.versionOneThree)>=0; - } + glXVersionOneThreeCapable = ( null != glXVersion ) ? glXVersion.compareTo(X11GLXDrawableFactory.versionOneThree) >= 0 : false ; } return glXVersionOneThreeCapable; } + public final boolean isGLReadDrawableAvailable() { + return isGLXVersionGreaterEqualOneThree(); + } + private final boolean glXMakeContextCurrent(long dpy, long writeDrawable, long readDrawable, long ctx) { boolean res = false; 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 186bd5ec5..709e2ddab 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 @@ -37,7 +37,11 @@ package com.jogamp.opengl.impl.x11.glx; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; import java.nio.*; + import javax.media.nativewindow.*; import javax.media.nativewindow.x11.*; import javax.media.opengl.*; @@ -47,8 +51,6 @@ import com.jogamp.common.JogampRuntimeException; import com.jogamp.common.util.*; import com.jogamp.nativewindow.impl.ProxySurface; import com.jogamp.nativewindow.impl.x11.*; -import java.util.Collection; -import java.util.HashMap; public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { @@ -70,6 +72,13 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } } + public static VersionNumber getGLXVersion(X11GraphicsDevice device) { + int[] major = new int[1]; + int[] minor = new int[1]; + GLXUtil.getGLXVersion(device.getHandle(), major, minor); + return new VersionNumber(major[0], minor[0], 0); + } + public GLDynamicLookupHelper getGLDynamicLookupHelper(int profile) { return x11GLXDynamicLookupHelper; } @@ -125,15 +134,18 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { isGLXVendorATI = GLXUtil.isVendorATI(glXVendorName); isGLXVendorNVIDIA = GLXUtil.isVendorNVIDIA(glXVendorName); } - public AbstractGraphicsDevice getDevice() { return device; } - public AbstractGraphicsScreen getScreen() { return screen; } - public GLDrawableImpl getDrawable() { return drawable; } - public GLContextImpl getContext() { return context; } - - String getGLXVendorName() { return glXVendorName; } - boolean isGLXVendorATI() { return isGLXVendorATI; } - boolean isGLXVendorNVIDIA() { return isGLXVendorNVIDIA; } - VersionNumber getGLXVersion() { return glXVersion; } + final public AbstractGraphicsDevice getDevice() { return device; } + final public AbstractGraphicsScreen getScreen() { return screen; } + final public GLDrawableImpl getDrawable() { return drawable; } + final public GLContextImpl getContext() { return context; } + + final String getGLXVendorName() { return glXVendorName; } + final boolean isGLXVendorATI() { return isGLXVendorATI; } + final boolean isGLXVendorNVIDIA() { return isGLXVendorNVIDIA; } + final VersionNumber getGLXVersion() { return glXVersion; } + final boolean isGLXVersionGreaterEqualOneThree() { + return ( null != glXVersion ) ? glXVersion.compareTo(versionOneThree) >= 0 : false ; + } } class SharedResourceImplementation implements SharedResourceRunner.Implementation { @@ -168,7 +180,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { if (null == sharedScreen) { throw new GLException("Couldn't create shared screen for device: "+sharedDevice+", idx 0"); } - GLProfile glp = GLProfile.getDefault(sharedDevice); + GLProfile glp = GLProfile.getMinDesktop(sharedDevice); if (null == glp) { throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice); } @@ -181,20 +193,18 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable); } sharedContext.setSynchronized(true); - VersionNumber glXVersion; + VersionNumber glXVersion = getGLXVersion(sharedDevice); + boolean madeCurrent = false; sharedContext.makeCurrent(); try { - int[] major = new int[1]; - int[] minor = new int[1]; - GLXUtil.getGLXVersion(sharedDevice.getHandle(), major, minor); - glXVersion = new VersionNumber(major[0], minor[0], 0); + madeCurrent = sharedContext.isCurrent(); } finally { sharedContext.release(); } if (DEBUG) { System.err.println("!!! SharedDevice: " + sharedDevice); System.err.println("!!! SharedScreen: " + sharedScreen); - System.err.println("!!! SharedContext: " + sharedContext); + System.err.println("!!! SharedContext: " + sharedContext + ", madeCurrent " + madeCurrent); System.err.println("!!! GLX Vendor: " + glXVendorName); System.err.println("!!! GLX Version: " + glXVersion + " >= 1.3: " + (glXVersion.compareTo(versionOneThree) >= 0)); @@ -273,15 +283,11 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return 0; } - protected final VersionNumber getGLXVersion(AbstractGraphicsDevice device) { - SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); - if(null!=sr) { - return ((SharedResource)sr).getGLXVersion(); - } - return null; + SharedResource getOrCreateSharedResource(AbstractGraphicsDevice device) { + return (SharedResource) sharedResourceRunner.getOrCreateShared(device); } - protected final String getGLXVendorName(AbstractGraphicsDevice device) { + public final String getGLXVendorName(AbstractGraphicsDevice device) { SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); if(null!=sr) { return ((SharedResource)sr).getGLXVendorName(); @@ -289,7 +295,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return GLXUtil.getVendorName(device.getHandle()); } - protected final boolean isGLXVendorATI(AbstractGraphicsDevice device) { + public final boolean isGLXVendorATI(AbstractGraphicsDevice device) { SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); if(null!=sr) { return ((SharedResource)sr).isGLXVendorATI(); @@ -297,7 +303,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return GLXUtil.isVendorATI(device.getHandle()); } - protected final boolean isGLXVendorNVIDIA(AbstractGraphicsDevice device) { + public final boolean isGLXVendorNVIDIA(AbstractGraphicsDevice device) { SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); if(null!=sr) { return ((SharedResource)sr).isGLXVendorNVIDIA(); @@ -313,6 +319,10 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { X11Util.shutdown( false, DEBUG ); } + protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) { + return X11GLXGraphicsConfigurationFactory.getAvailableCapabilities(this, device); + } + protected final GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); @@ -354,9 +364,16 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return pbufferDrawable; } - public final boolean glXVersionGreaterEqualOneThree(AbstractGraphicsDevice device) { - VersionNumber glXVersion = getGLXVersion(device); - return ( null != glXVersion ) ? glXVersion.compareTo(versionOneThree) >= 0 : false ; + public final boolean isGLXVersionGreaterEqualOneThree(AbstractGraphicsDevice device) { + SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device); + if(null!=sr) { + return sr.isGLXVersionGreaterEqualOneThree(); + } + if( device instanceof X11GraphicsDevice ) { + VersionNumber v = getGLXVersion( (X11GraphicsDevice) device); + return ( null != v ) ? v.compareTo(versionOneThree) >= 0 : false ; + } + return false; } public final boolean canCreateGLPbuffer(AbstractGraphicsDevice device) { @@ -366,7 +383,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { device = sr.getDevice(); } } - return glXVersionGreaterEqualOneThree(device); + return isGLXVersionGreaterEqualOneThree(device); } protected final NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device, 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 3dbaab21b..f7779ab28 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 @@ -33,10 +33,13 @@ package com.jogamp.opengl.impl.x11.glx; -import com.jogamp.common.nio.PointerBuffer; +import java.util.ArrayList; + import javax.media.nativewindow.*; import javax.media.nativewindow.x11.*; import javax.media.opengl.*; + +import com.jogamp.common.nio.PointerBuffer; import com.jogamp.opengl.impl.*; import com.jogamp.nativewindow.impl.x11.*; @@ -44,17 +47,12 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); public static final int MAX_ATTRIBS = 128; - private long fbConfig; - private int fbConfigID; private GLCapabilitiesChooser chooser; X11GLXGraphicsConfiguration(X11GraphicsScreen screen, - GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, - XVisualInfo info, long fbcfg, int fbcfgID) { - super(screen, capsChosen, capsRequested, info); + X11GLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { + super(screen, capsChosen, capsRequested, capsChosen.getXVisualInfo()); this.chooser=chooser; - fbConfig = fbcfg; - fbConfigID = fbcfgID; } static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) { @@ -70,23 +68,23 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem if(null==glp) { glp = GLProfile.getDefault(x11Screen.getDevice()); } - GLCapabilitiesImmutable caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display)); + X11GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display)); if(null==caps) { throw new GLException("GLCapabilities null of "+toHexString(fbcfg)); } - XVisualInfo xvi = GLX.glXGetVisualFromFBConfig(display, fbcfg); - if(null==xvi) { - throw new GLException("XVisualInfo null of "+toHexString(fbcfg)); - } - return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser(), xvi, fbcfg, fbcfgID); + return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser()); } public Object clone() { return super.clone(); } - public long getFBConfig() { return fbConfig; } - public int getFBConfigID() { return fbConfigID; } + public final long getFBConfig() { + return ((X11GLCapabilities)capabilitiesChosen).getFBConfig(); + } + public final int getFBConfigID() { + return ((X11GLCapabilities)capabilitiesChosen).getFBConfigID(); + } void updateGraphicsConfiguration() { X11GLXGraphicsConfiguration newConfig = (X11GLXGraphicsConfiguration) @@ -96,8 +94,6 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem // FIXME: setScreen( ... ); setXVisualInfo(newConfig.getXVisualInfo()); setChosenCapabilities(newConfig.getChosenCapabilities()); - fbConfig = newConfig.getFBConfig(); - fbConfigID = newConfig.getFBConfigID(); if(DEBUG) { System.err.println("!!! updateGraphicsConfiguration: "+this); } @@ -220,49 +216,63 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem return true; } - static boolean GLXFBConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) { - boolean res; + static int FBCfgDrawableTypeBits(final long display, final long fbcfg) { + int val = 0; - if ( onscreen ) { - res = ( 0 != (val & GLX.GLX_WINDOW_BIT) ) ; - } else { - if ( usePBuffer ) { - res = ( 0 != (val & GLX.GLX_PBUFFER_BIT) ) ; - } else { - res = ( 0 != (val & GLX.GLX_PIXMAP_BIT) ) ; - } - } + int[] tmp = new int[1]; + int fbtype = glXGetFBConfig(display, fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0); - return res; + if ( 0 != ( fbtype & GLX.GLX_WINDOW_BIT ) ) { + val |= GLGraphicsConfigurationUtil.WINDOW_BIT; + } + if ( 0 != ( fbtype & GLX.GLX_PIXMAP_BIT ) ) { + val |= GLGraphicsConfigurationUtil.BITMAP_BIT; + } + if ( 0 != ( fbtype & GLX.GLX_PBUFFER_BIT ) ) { + val |= GLGraphicsConfigurationUtil.PBUFFER_BIT; + } + return val; } - static GLCapabilitiesImmutable GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg, + static X11GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg, boolean relaxed, boolean onscreen, boolean usePBuffer, boolean isMultisampleAvailable) { - int[] tmp = new int[1]; - int val; - val = glXGetFBConfig(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0); - if (val != GLX.GLX_RGBA_BIT) { - if(DEBUG) { - System.err.println("FBConfig ("+toHexString(fbcfg)+") does not support RGBA: "+toHexString(val)); - } - return null; + ArrayList bucket = new ArrayList(); + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + if( GLXFBConfig2GLCapabilities(bucket, glp, display, fbcfg, winattrmask, isMultisampleAvailable) ) { + return (X11GLCapabilities) bucket.get(0); + } else if ( relaxed && GLXFBConfig2GLCapabilities(bucket, glp, display, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) { + return (X11GLCapabilities) bucket.get(0); } - GLCapabilities res = new GLCapabilities(glp); - - val = glXGetFBConfig(display, fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0); - if(GLXFBConfigDrawableTypeVerify(val, onscreen, usePBuffer)) { - res.setOnscreen(onscreen); - res.setPBuffer(usePBuffer); - } else if(relaxed) { - res.setOnscreen( 0 != (val & GLX.GLX_WINDOW_BIT) ); - res.setPBuffer ( 0 != (val & GLX.GLX_PBUFFER_BIT) ); - } else { + return null; + } + + static boolean GLXFBConfig2GLCapabilities(ArrayList capsBucket, + GLProfile glp, long display, long fbcfg, + int winattrmask, boolean isMultisampleAvailable) { + final int allDrawableTypeBits = FBCfgDrawableTypeBits(display, fbcfg); + int drawableTypeBits = winattrmask & allDrawableTypeBits; + + int fbcfgid = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfg); + XVisualInfo visualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfg); + if(null == visualInfo) { 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) )+")"); + System.err.println("X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities: Null XVisualInfo for FBConfigID 0x" + Integer.toHexString(fbcfgid)); } - return null; + // onscreen must have an XVisualInfo + drawableTypeBits = drawableTypeBits & ~GLGraphicsConfigurationUtil.WINDOW_BIT; } + + if( 0 == drawableTypeBits ) { + return false; + } + + int[] tmp = new int[1]; + if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0)) { + return false; + } + + GLCapabilities res = new X11GLCapabilities(visualInfo, fbcfg, fbcfgid, glp); res.setDoubleBuffered(glXGetFBConfig(display, fbcfg, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0); res.setStereo (glXGetFBConfig(display, fbcfg, GLX.GLX_STEREO, tmp, 0) != 0); res.setHardwareAccelerated(glXGetFBConfig(display, fbcfg, GLX.GLX_CONFIG_CAVEAT, tmp, 0) != GLX.GLX_SLOW_CONFIG); @@ -297,7 +307,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem try { res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE); } catch (Exception e) {} - return res; + + return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits ); } private static String glXGetFBConfigErrorCode(int err) { @@ -352,26 +363,34 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem return res; } - static GLCapabilitiesImmutable XVisualInfo2GLCapabilities(GLProfile glp, long display, XVisualInfo info, - boolean onscreen, boolean usePBuffer, boolean isMultisampleEnabled) { + static boolean XVisualInfo2GLCapabilities(ArrayList capsBucket, + GLProfile glp, long display, XVisualInfo info, + final int winattrmask, boolean isMultisampleEnabled) { + final int allDrawableTypeBits = GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT ; + final int drawableTypeBits = winattrmask & allDrawableTypeBits; + + if( 0 == drawableTypeBits ) { + return false; + } + int[] tmp = new int[1]; int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0); if (val == 0) { if(DEBUG) { System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support OpenGL"); } - return null; + return false; } val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp, 0); if (val == 0) { if(DEBUG) { System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support RGBA"); } - return null; + return false; } - GLCapabilities res = new GLCapabilities(glp); - res.setOnscreen (onscreen); - res.setPBuffer (usePBuffer); + + GLCapabilities res = new X11GLCapabilities(info, glp); + res.setDoubleBuffered(glXGetConfig(display, info, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0); res.setStereo (glXGetConfig(display, info, GLX.GLX_STEREO, tmp, 0) != 0); // Note: use of hardware acceleration is determined by @@ -393,7 +412,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0); res.setNumSamples (glXGetConfig(display, info, GLX.GLX_SAMPLES, tmp, 0)); } - return res; + + return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits); } private static String glXGetConfigErrorCode(int err) { @@ -417,16 +437,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem return tmp[tmp_offset]; } - static String toHexString(int val) { - return "0x"+Integer.toHexString(val); - } - - static String toHexString(long val) { - return "0x"+Long.toHexString(val); - } - public String toString() { - return "X11GLXGraphicsConfiguration["+getScreen()+", visualID " + toHexString(getVisualID()) + ", fbConfigID " + toHexString(fbConfigID) + + return "X11GLXGraphicsConfiguration["+getScreen()+", visualID " + toHexString(getVisualID()) + ", fbConfigID " + toHexString(getFBConfigID()) + ",\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 88ed852d5..b391dc948 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 @@ -39,12 +39,13 @@ import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.GraphicsConfigurationFactory; -import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.x11.X11GraphicsScreen; +import javax.media.nativewindow.x11.X11GraphicsDevice; import javax.media.opengl.DefaultGLCapabilitiesChooser; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; @@ -53,7 +54,12 @@ import com.jogamp.nativewindow.impl.x11.X11Lib; import com.jogamp.nativewindow.impl.x11.X11Util; import com.jogamp.nativewindow.impl.x11.XVisualInfo; import com.jogamp.opengl.impl.Debug; -import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; +import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; /** Subclass of GraphicsConfigurationFactory used when non-AWT toolkits @@ -61,8 +67,9 @@ import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; to this one to change the accepted and returned types of the GraphicsDevice and GraphicsConfiguration abstractions. */ -public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { +public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); + static X11GLCapabilities.XVisualIDComparator XVisualIDComparator = new X11GLCapabilities.XVisualIDComparator(); X11GLXGraphicsConfigurationFactory() { GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, this); @@ -89,6 +96,86 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF (GLCapabilitiesChooser)chooser, (X11GraphicsScreen)absScreen); } + protected static List/*<X11GLCapabilities>*/ getAvailableCapabilities(X11GLXDrawableFactory factory, AbstractGraphicsDevice device) { + X11GLXDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device); + if(null == sharedResource) { + throw new GLException("Shared resource for device n/a: "+device); + } + X11GraphicsScreen sharedScreen = (X11GraphicsScreen) sharedResource.getScreen(); + X11GLXDrawable sharedDrawable = (X11GLXDrawable) sharedResource.getDrawable(); + GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities(); + GLProfile glp = capsChosen.getGLProfile(); + + List/*GLCapabilitiesImmutable*/ availableCaps = null; + + if( sharedResource.isGLXVersionGreaterEqualOneThree() ) { + availableCaps = getAvailableGLCapabilitiesFBConfig(sharedScreen, glp); + } + if( null == availableCaps || 0 == availableCaps.size() ) { + availableCaps = getAvailableGLCapabilitiesXVisual(sharedScreen, glp); + } + if( null != availableCaps ) { + Collections.sort(availableCaps, XVisualIDComparator); + } + return availableCaps; + } + + static List/*<X11GLCapabilities>*/ getAvailableGLCapabilitiesFBConfig(X11GraphicsScreen x11Screen, GLProfile glProfile) { + PointerBuffer fbcfgsL = null; + + // Utilizing FBConfig + // + AbstractGraphicsDevice absDevice = x11Screen.getDevice(); + long display = absDevice.getHandle(); + + int screen = x11Screen.getIndex(); + boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); + int[] count = { -1 }; + ArrayList availableCaps = new ArrayList(); + + fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0); + if (fbcfgsL == null || fbcfgsL.limit()<=0) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: Failed glXChooseFBConfig ("+x11Screen+"): "+fbcfgsL+", "+count[0]); + } + return null; + } + for (int i = 0; i < fbcfgsL.limit(); i++) { + if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i))); + } + } + } + return availableCaps; + } + + static List/*<X11GLCapabilities>*/ getAvailableGLCapabilitiesXVisual(X11GraphicsScreen x11Screen, GLProfile glProfile) { + AbstractGraphicsDevice absDevice = x11Screen.getDevice(); + long display = absDevice.getHandle(); + + int screen = x11Screen.getIndex(); + boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); + + int[] count = new int[1]; + XVisualInfo template = XVisualInfo.create(); + template.setScreen(screen); + XVisualInfo[] infos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); + if (infos == null || infos.length<1) { + throw new GLException("Error while enumerating available XVisualInfos"); + } + ArrayList availableCaps = new ArrayList(); + for (int i = 0; i < infos.length; i++) { + if( !X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(availableCaps, glProfile, display, infos[i], GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid())); + } + } + } + return availableCaps; + } + + static X11GLXGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsReq, GLCapabilitiesChooser chooser, @@ -100,18 +187,16 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF if (capsChosen == null) { capsChosen = new GLCapabilities(null); } + X11GraphicsDevice x11Device = (X11GraphicsDevice) x11Screen.getDevice(); + X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory(); - if(!capsChosen.isOnscreen() && capsChosen.getDoubleBuffered()) { - // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN - GLCapabilities caps2 = (GLCapabilities) capsChosen.cloneMutable(); - caps2.setDoubleBuffered(false); - capsChosen = caps2; - } - + capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory.canCreateGLPbuffer(x11Device) ); boolean usePBuffer = capsChosen.isPBuffer(); - X11GLXGraphicsConfiguration res; - res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen); + X11GLXGraphicsConfiguration res = null; + if( factory.isGLXVersionGreaterEqualOneThree(x11Device) ) { + res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen); + } if(null==res) { if(usePBuffer) { throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for "+capsChosen); @@ -139,14 +224,8 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF } return null; } - XVisualInfo visualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfg); - if (visualInfo==null) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetVisualFromFBConfig ("+x11Screen+", "+toHexString(fbcfg)+")"); - return null; - } - GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display)); - return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser(), visualInfo, fbcfg, fbID); - + X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display)); + return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser()); } private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig(GLCapabilitiesImmutable capsChosen, @@ -155,10 +234,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF X11GraphicsScreen x11Screen) { long recommendedFBConfig = -1; int recommendedIndex = -1; - int retFBID=-1; - GLCapabilitiesImmutable[] availableCaps = null; PointerBuffer fbcfgsL = null; - XVisualInfo retXVisualInfo = null; GLProfile glProfile = capsChosen.getGLProfile(); boolean onscreen = capsChosen.isOnscreen(); boolean usePBuffer = capsChosen.isPBuffer(); @@ -172,39 +248,39 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, true, isMultisampleAvailable, display, screen); int[] count = { -1 }; + ArrayList/*<X11GLCapabilities>*/ availableCaps = new ArrayList(); + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0); if (fbcfgsL != null && fbcfgsL.limit()>0) { - availableCaps = new GLCapabilitiesImmutable[fbcfgsL.limit()]; for (int i = 0; i < fbcfgsL.limit(); i++) { - if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) { + if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) { if(DEBUG) { System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (1): ("+x11Screen+","+capsChosen+"): fbcfg: "+toHexString(fbcfgsL.get(i))); } - } else { - availableCaps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i), - false, onscreen, usePBuffer, isMultisampleAvailable); } } - if(availableCaps[0]!=null) { + if(availableCaps.size() > 0) { recommendedFBConfig = fbcfgsL.get(0); recommendedIndex=0; if (DEBUG) { System.err.println("!!! glXChooseFBConfig recommended fbcfg " + toHexString(recommendedFBConfig) + ", idx " + recommendedIndex); System.err.println("!!! user caps " + capsChosen); - System.err.println("!!! fbcfg caps " + availableCaps[recommendedIndex]); - } - } else { - if (DEBUG) { - System.err.println("!!! glXChooseFBConfig no caps for recommended fbcfg " + toHexString(recommendedFBConfig)); - System.err.println("!!! user caps " + capsChosen); + System.err.println("!!! fbcfg caps " + availableCaps.get(recommendedIndex)); } + } else if (DEBUG) { + System.err.println("!!! glXChooseFBConfig no caps for recommended fbcfg " + toHexString(fbcfgsL.get(0))); + System.err.println("!!! user caps " + capsChosen); } } // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available - if(null == availableCaps) { + if( 0 == availableCaps.size() ) { + // reset .. + recommendedFBConfig = -1; + recommendedIndex = -1; + fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0); if (fbcfgsL == null || fbcfgsL.limit()<=0) { if(DEBUG) { @@ -213,19 +289,14 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF return null; } - availableCaps = new GLCapabilitiesImmutable[fbcfgsL.limit()]; for (int i = 0; i < fbcfgsL.limit(); i++) { - if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) { + if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) { if(DEBUG) { System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i))); } - } else { - availableCaps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i), - false, onscreen, usePBuffer, isMultisampleAvailable); } } } - int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); if ( 0 > chosenIndex ) { if (DEBUG) { @@ -233,20 +304,9 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF } return null; } - retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosenIndex)); + X11GLCapabilities chosenCaps = (X11GLCapabilities) availableCaps.get(chosenIndex); - retXVisualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfgsL.get(chosenIndex)); - if (retXVisualInfo==null) { - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetVisualFromFBConfig ("+x11Screen+", "+fbcfgsL.get(chosenIndex) +" (Continue: "+(false==availableCaps[chosenIndex].isOnscreen())+"):\n\t"+availableCaps[chosenIndex]); - } - if(availableCaps[chosenIndex].isOnscreen()) { - // Onscreen drawables shall have a XVisual .. - return null; - } - } - - return new X11GLXGraphicsConfiguration(x11Screen, availableCaps[chosenIndex], capsReq, chooser, retXVisualInfo, fbcfgsL.get(chosenIndex), retFBID); + return new X11GLXGraphicsConfiguration(x11Screen, chosenCaps, capsReq, chooser); } private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual(GLCapabilitiesImmutable capsChosen, @@ -257,15 +317,10 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF chooser = new DefaultGLCapabilitiesChooser(); } - // Until we have a rock-solid visual selection algorithm written - // in pure Java, we're going to provide the underlying window - // system's selection to the chooser as a hint - GLProfile glProfile = capsChosen.getGLProfile(); - boolean onscreen = capsChosen.isOnscreen(); - GLCapabilitiesImmutable[] availableCaps = null; + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(capsChosen.isOnscreen(), false /* pbuffer */); + ArrayList availableCaps = new ArrayList(); int recommendedIndex = -1; - XVisualInfo retXVisualInfo = null; AbstractGraphicsDevice absDevice = x11Screen.getDevice(); long display = absDevice.getHandle(); @@ -273,8 +328,8 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF int screen = x11Screen.getIndex(); boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, false, isMultisampleAvailable, display, screen); - XVisualInfo[] infos = null; + // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice XVisualInfo recommendedVis = GLX.glXChooseVisual(display, screen, attribs, 0); if (DEBUG) { System.err.print("!!! glXChooseVisual recommended "); @@ -284,21 +339,29 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF System.err.println("visual id " + toHexString(recommendedVis.getVisualid())); } } + + // 2nd choice: get all GLCapabilities available, preferred recommendedIndex might be available if 1st choice was successful int[] count = new int[1]; XVisualInfo template = XVisualInfo.create(); template.setScreen(screen); - infos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); + XVisualInfo[] infos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); if (infos == null || infos.length<1) { throw new GLException("Error while enumerating available XVisualInfos"); } - availableCaps = new GLCapabilitiesImmutable[infos.length]; + for (int i = 0; i < infos.length; i++) { - availableCaps[i] = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, infos[i], onscreen, false, isMultisampleAvailable); - // Attempt to find the visual chosenIndex by glXChooseVisual - if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) { - recommendedIndex = i; + if( !X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(availableCaps, glProfile, display, infos[i], winattrmask, isMultisampleAvailable) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid())); + } + } else { + // Attempt to find the visual chosenIndex by glXChooseVisual + if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) { + recommendedIndex = availableCaps.size() - 1; + } } } + int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); if ( 0 > chosenIndex ) { if (DEBUG) { @@ -306,17 +369,9 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF } return null; } + X11GLCapabilities chosenCaps = (X11GLCapabilities) availableCaps.get(chosenIndex); - retXVisualInfo = XVisualInfo.create(infos[chosenIndex]); - return new X11GLXGraphicsConfiguration(x11Screen, availableCaps[chosenIndex], capsReq, chooser, retXVisualInfo, 0, -1); - } - - static String toHexString(int val) { - return "0x"+Integer.toHexString(val); - } - - static String toHexString(long val) { - return "0x"+Long.toHexString(val); + return new X11GLXGraphicsConfiguration(x11Screen, chosenCaps, capsReq, chooser); } } 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 51f9f53cc..898a8a658 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 @@ -44,7 +44,7 @@ import com.jogamp.opengl.impl.*; import com.jogamp.nativewindow.impl.jawt.x11.*; import com.jogamp.nativewindow.impl.x11.*; -public class X11AWTGLXGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { +public class X11AWTGLXGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); public X11AWTGLXGraphicsConfigurationFactory() { diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java index f22e11cb7..6073a75f8 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -43,11 +44,9 @@ import com.jogamp.opengl.impl.Debug; import com.jogamp.opengl.util.*; import com.jogamp.opengl.util.packrect.*; import com.jogamp.opengl.util.texture.*; -import com.jogamp.opengl.util.texture.awt.*; import java.awt.AlphaComposite; import java.awt.Color; -import java.awt.Composite; // For debugging purposes import java.awt.EventQueue; @@ -71,7 +70,6 @@ import java.security.*; import javax.media.opengl.*; import javax.media.opengl.glu.*; -import javax.media.opengl.glu.gl2.*; import javax.media.opengl.awt.*; @@ -720,7 +718,7 @@ public class TextRenderer { // The OpenGL spec is unclear about whether this changes the // buffer bindings, so preemptively zero out the GL_ARRAY_BUFFER // binding - if (is15Available(gl)) { + if (getUseVertexArrays() && is15Available(gl)) { try { gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0); } catch (Exception e) { @@ -1236,7 +1234,7 @@ public class TextRenderer { // The OpenGL spec is unclear about whether this changes the // buffer bindings, so preemptively zero out the GL_ARRAY_BUFFER // binding - if (is15Available(gl)) { + if (getUseVertexArrays() && is15Available(gl)) { try { gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0); } catch (Exception e) { @@ -1558,6 +1556,8 @@ public class TextRenderer { final int undefined = -2; FontRenderContext fontRenderContext; List/*<Glyph>*/ glyphsOutput = new ArrayList/*<Glyph>*/(); + HashMap/*<String, GlyphVector>*/fullGlyphVectorCache = new HashMap/*<String, GlyphVector>*/(); + HashMap/*<Character, GlyphMetrics>*/glyphMetricsCache = new HashMap/*<Character, GlyphMetrics>*/(); // The mapping from unicode character to font-specific glyph ID int[] unicodes2Glyphs; // The mapping from glyph ID to Glyph @@ -1573,8 +1573,13 @@ public class TextRenderer { public List/*<Glyph>*/ getGlyphs(CharSequence inString) { glyphsOutput.clear(); - iter.initFromCharSequence(inString); - GlyphVector fullRunGlyphVector = font.createGlyphVector(getFontRenderContext(), iter); + GlyphVector fullRunGlyphVector; + fullRunGlyphVector = (GlyphVector) fullGlyphVectorCache.get(inString.toString()); + if (fullRunGlyphVector == null) { + iter.initFromCharSequence(inString); + fullRunGlyphVector = font.createGlyphVector(getFontRenderContext(), iter); + fullGlyphVectorCache.put(inString.toString(), fullRunGlyphVector); + } boolean complex = (fullRunGlyphVector.getLayoutFlags() != 0); if (complex || DISABLE_GLYPH_CACHE) { // Punt to the robust version of the renderer @@ -1585,7 +1590,13 @@ public class TextRenderer { int lengthInGlyphs = fullRunGlyphVector.getNumGlyphs(); int i = 0; while (i < lengthInGlyphs) { - Glyph glyph = getGlyph(inString, fullRunGlyphVector, i); + Character letter = CharacterCache.valueOf(inString.charAt(i)); + GlyphMetrics metrics = (GlyphMetrics) glyphMetricsCache.get(letter); + if (metrics == null) { + metrics = fullRunGlyphVector.getGlyphMetrics(i); + glyphMetricsCache.put(letter, metrics); + } + Glyph glyph = getGlyph(inString, metrics, i); if (glyph != null) { glyphsOutput.add(glyph); i++; @@ -1594,7 +1605,7 @@ public class TextRenderer { // the cache StringBuffer buf = new StringBuffer(); while (i < lengthInGlyphs && - getGlyph(inString, fullRunGlyphVector, i) == null) { + getGlyph(inString, fullRunGlyphVector.getGlyphMetrics(i), i) == null) { buf.append(inString.charAt(i++)); } glyphsOutput.add(new Glyph(buf.toString(), @@ -1645,7 +1656,7 @@ public class TextRenderer { // if the unicode or glyph ID would be out of bounds of the // glyph cache. private Glyph getGlyph(CharSequence inString, - GlyphVector fullRunGlyphVector, + GlyphMetrics glyphMetrics, int index) { char unicodeID = inString.charAt(index); @@ -1661,7 +1672,7 @@ public class TextRenderer { // Must fabricate the glyph singleUnicode[0] = unicodeID; GlyphVector gv = font.createGlyphVector(getFontRenderContext(), singleUnicode); - return getGlyph(unicodeID, gv, fullRunGlyphVector.getGlyphMetrics(index)); + return getGlyph(unicodeID, gv, glyphMetrics); } // It's unclear whether this variant might produce less @@ -1698,6 +1709,26 @@ public class TextRenderer { return glyph; } } + + private static class CharacterCache { + private CharacterCache() { + } + + static final Character cache[] = new Character[127 + 1]; + + static { + for (int i = 0; i < cache.length; i++) { + cache[i] = new Character((char) i); + } + } + + public static Character valueOf(char c) { + if (c <= 127) { // must cache + return CharacterCache.cache[c]; + } + return new Character(c); + } + } class Pipelined_QuadRenderer { int mOutstandingGlyphsVerticesPipeline = 0; @@ -1712,7 +1743,7 @@ public class TextRenderer { mVertCoords = Buffers.newDirectFloatBuffer(kTotalBufferSizeCoordsVerts); mTexCoords = Buffers.newDirectFloatBuffer(kTotalBufferSizeCoordsTex); - usingVBOs = is15Available(gl); + usingVBOs = getUseVertexArrays() && is15Available(gl); if (usingVBOs) { try { @@ -1918,7 +1949,7 @@ public class TextRenderer { * rendering, or whether text is rendered using the OpenGL * immediate mode commands. Defaults to true. */ - public boolean getUseVertexArrays() { + public final boolean getUseVertexArrays() { return useVertexArrays; } @@ -1943,7 +1974,7 @@ public class TextRenderer { return smoothing; } - private boolean is15Available(GL gl) { + private final boolean is15Available(GL gl) { if (!checkFor_isExtensionAvailable_GL_VERSION_1_5) { isExtensionAvailable_GL_VERSION_1_5 = gl.isExtensionAvailable("GL_VERSION_1_5"); checkFor_isExtensionAvailable_GL_VERSION_1_5 = true; diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java index bc5aa517e..86dca59f4 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -47,10 +48,8 @@ import java.awt.Rectangle; import java.awt.image.*; import javax.media.opengl.*; -import javax.media.opengl.glu.*; import javax.media.opengl.glu.gl2.*; import com.jogamp.opengl.util.texture.*; -import com.jogamp.opengl.util.texture.spi.*; import com.jogamp.opengl.util.texture.awt.*; /** Provides the ability to render into an OpenGL {@link diff --git a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java index 695fad5a9..ecba18147 100644 --- a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java +++ b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java @@ -42,6 +42,7 @@ package javax.media.opengl; import javax.media.nativewindow.NativeWindowException; import com.jogamp.opengl.impl.Debug; +import java.util.List; import javax.media.nativewindow.CapabilitiesImmutable; /** <P> The default implementation of the {@link @@ -85,38 +86,40 @@ import javax.media.nativewindow.CapabilitiesImmutable; public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { private static final boolean DEBUG = Debug.debug("CapabilitiesChooser"); - public int chooseCapabilities(CapabilitiesImmutable desired, - CapabilitiesImmutable[] available, - int windowSystemRecommendedChoice) { - GLCapabilitiesImmutable _desired = (GLCapabilitiesImmutable) desired; - GLCapabilitiesImmutable[] _available = (GLCapabilitiesImmutable[]) available; - int availnum = 0; - - for (int i = 0; i < _available.length; i++) { - if(null != _available[i]) { availnum++; } + public int chooseCapabilities(final CapabilitiesImmutable desired, + final List /*<CapabilitiesImmutable>*/ available, + final int windowSystemRecommendedChoice) { + if ( null == desired ) { + throw new NativeWindowException("Null desired capabilities"); + } + if ( 0 == available.size() ) { + throw new NativeWindowException("Empty available capabilities"); } + final GLCapabilitiesImmutable gldes = (GLCapabilitiesImmutable) desired; + final int availnum = available.size(); + 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(i + ": " + _available[i]); + System.err.println("Desired: " + gldes); + System.err.println("Available: " + availnum); + for (int i = 0; i < available.size(); i++) { + System.err.println(i + ": " + available.get(i)); } System.err.println("Window system's recommended choice: " + windowSystemRecommendedChoice); } if (windowSystemRecommendedChoice >= 0 && - windowSystemRecommendedChoice < _available.length && - _available[windowSystemRecommendedChoice] != null) { + windowSystemRecommendedChoice < availnum && + null != available.get(windowSystemRecommendedChoice)) { if (DEBUG) { System.err.println("Choosing window system's recommended choice of " + windowSystemRecommendedChoice); - System.err.println(_available[windowSystemRecommendedChoice]); + System.err.println(available.get(windowSystemRecommendedChoice)); } return windowSystemRecommendedChoice; } // Create score array - int[] scores = new int[_available.length]; + int[] scores = new int[availnum]; int NO_SCORE = -9999999; int DOUBLE_BUFFER_MISMATCH_PENALTY = 1000; int STENCIL_MISMATCH_PENALTY = 500; @@ -131,18 +134,18 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { scores[i] = NO_SCORE; } // Compute score for each - for (int i = 0; i < scores.length; i++) { - GLCapabilitiesImmutable cur = _available[i]; + for (int i = 0; i < availnum; i++) { + GLCapabilitiesImmutable cur = (GLCapabilitiesImmutable) available.get(i); if (cur == null) { continue; } - if (_desired.isOnscreen() != cur.isOnscreen()) { + if (gldes.isOnscreen() != cur.isOnscreen()) { continue; } - if (!_desired.isOnscreen() && _desired.isPBuffer() && !cur.isPBuffer()) { + if (!gldes.isOnscreen() && gldes.isPBuffer() && !cur.isPBuffer()) { continue; // only skip if requested Offscreen && PBuffer, but no PBuffer available } - if (_desired.getStereo() != cur.getStereo()) { + if (gldes.getStereo() != cur.getStereo()) { continue; } int score = 0; @@ -150,20 +153,20 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { // (Note that this decides the direction of all other penalties) score += (COLOR_MISMATCH_PENALTY_SCALE * ((cur.getRedBits() + cur.getGreenBits() + cur.getBlueBits() + cur.getAlphaBits()) - - (_desired.getRedBits() + _desired.getGreenBits() + _desired.getBlueBits() + _desired.getAlphaBits()))); + (gldes.getRedBits() + gldes.getGreenBits() + gldes.getBlueBits() + gldes.getAlphaBits()))); // Compute difference in depth buffer depth score += (DEPTH_MISMATCH_PENALTY_SCALE * sign(score) * - Math.abs(cur.getDepthBits() - _desired.getDepthBits())); + Math.abs(cur.getDepthBits() - gldes.getDepthBits())); // Compute difference in accumulation buffer depth score += (ACCUM_MISMATCH_PENALTY_SCALE * sign(score) * Math.abs((cur.getAccumRedBits() + cur.getAccumGreenBits() + cur.getAccumBlueBits() + cur.getAccumAlphaBits()) - - (_desired.getAccumRedBits() + _desired.getAccumGreenBits() + _desired.getAccumBlueBits() + _desired.getAccumAlphaBits()))); + (gldes.getAccumRedBits() + gldes.getAccumGreenBits() + gldes.getAccumBlueBits() + gldes.getAccumAlphaBits()))); // Compute difference in stencil bits - score += STENCIL_MISMATCH_PENALTY_SCALE * sign(score) * (cur.getStencilBits() - _desired.getStencilBits()); - if (cur.getDoubleBuffered() != _desired.getDoubleBuffered()) { + score += STENCIL_MISMATCH_PENALTY_SCALE * sign(score) * (cur.getStencilBits() - gldes.getStencilBits()); + if (cur.getDoubleBuffered() != gldes.getDoubleBuffered()) { score += sign(score) * DOUBLE_BUFFER_MISMATCH_PENALTY; } - if ((_desired.getStencilBits() > 0) && (cur.getStencilBits() == 0)) { + if ((gldes.getStencilBits() > 0) && (cur.getStencilBits() == 0)) { score += sign(score) * STENCIL_MISMATCH_PENALTY; } scores[i] = score; @@ -172,12 +175,12 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { // non-hardware-accelerated visuals out boolean gotHW = false; int maxAbsoluteHWScore = 0; - for (int i = 0; i < scores.length; i++) { + for (int i = 0; i < availnum; i++) { int score = scores[i]; if (score == NO_SCORE) { continue; } - GLCapabilitiesImmutable cur = _available[i]; + GLCapabilitiesImmutable cur = (GLCapabilitiesImmutable) available.get(i); if (cur.getHardwareAccelerated()) { int absScore = Math.abs(score); if (!gotHW || @@ -188,12 +191,12 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { } } if (gotHW) { - for (int i = 0; i < scores.length; i++) { + for (int i = 0; i < availnum; i++) { int score = scores[i]; if (score == NO_SCORE) { continue; } - GLCapabilitiesImmutable cur = _available[i]; + GLCapabilitiesImmutable cur = (GLCapabilitiesImmutable) available.get(i); if (!cur.getHardwareAccelerated()) { if (score <= 0) { score -= maxAbsoluteHWScore; @@ -207,7 +210,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { if (DEBUG) { System.err.print("Scores: ["); - for (int i = 0; i < _available.length; i++) { + for (int i = 0; i < availnum; i++) { if (i > 0) { System.err.print(","); } @@ -219,7 +222,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { // Ready to select. Choose score closest to 0. int scoreClosestToZero = NO_SCORE; int chosenIndex = -1; - for (int i = 0; i < scores.length; i++) { + for (int i = 0; i < availnum; i++) { int score = scores[i]; if (score == NO_SCORE) { continue; @@ -238,7 +241,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { if (DEBUG) { System.err.println("Chosen index: " + chosenIndex); System.err.println("Chosen capabilities:"); - System.err.println(_available[chosenIndex]); + System.err.println(available.get(chosenIndex)); } return chosenIndex; @@ -250,4 +253,5 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { } return 1; } + } diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilities.java b/src/jogl/classes/javax/media/opengl/GLCapabilities.java index 82f83dc82..1ae9e40aa 100644 --- a/src/jogl/classes/javax/media/opengl/GLCapabilities.java +++ b/src/jogl/classes/javax/media/opengl/GLCapabilities.java @@ -143,6 +143,56 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil return res; } + /** comparing hw/sw, stereo, multisample, stencil, RGBA and depth only */ + public int compareTo(Object o) { + if ( ! ( o instanceof GLCapabilities ) ) { + Class c = (null != o) ? o.getClass() : null ; + throw new ClassCastException("Not a GLCapabilities object: " + c); + } + + final GLCapabilities caps = (GLCapabilities) o; + + if(hardwareAccelerated && !caps.hardwareAccelerated) { + return 1; + } else if(!hardwareAccelerated && caps.hardwareAccelerated) { + return -1; + } + + if(stereo && !caps.stereo) { + return 1; + } else if(!stereo && caps.stereo) { + return -1; + } + + final int ms = sampleBuffers ? numSamples : 0; + final int xms = caps.sampleBuffers ? caps.numSamples : 0; + + if(ms > xms) { + return 1; + } else if( ms < xms ) { + return -1; + } + + if(stencilBits > caps.stencilBits) { + return 1; + } else if(stencilBits < caps.stencilBits) { + return -1; + } + + final int sc = super.compareTo(caps); // RGBA + if(0 != sc) { + return sc; + } + + if(depthBits > caps.depthBits) { + return 1; + } else if(depthBits < caps.depthBits) { + return -1; + } + + return 0; // they are equal: hw/sw, stereo, multisample, stencil, RGBA and depth + } + /** Returns the GL profile you desire or used by the drawable. */ public GLProfile getGLProfile() { return glProfile; @@ -158,11 +208,30 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil return pbuffer; } - /** Enables or disables pbuffer usage. */ + /** + * Enables or disables pbuffer usage.<br> + * If enabled, onscreen := false. + * Defaults to false. + */ public void setPBuffer(boolean onOrOff) { + if(onOrOff) { + setOnscreen(false); + } pbuffer = onOrOff; } + /** + * Sets whether the drawable surface supports onscreen.<br> + * If enabled, pbuffer := false.<br> + * Defaults to true. + */ + public void setOnscreen(boolean onscreen) { + if(onscreen) { + setPBuffer(false); + } + super.setOnscreen(onscreen); + } + /** Indicates whether double-buffering is enabled. */ public boolean getDoubleBuffered() { return doubleBuffered; @@ -340,28 +409,54 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil return pbufferRenderToTextureRectangle; } + public StringBuffer toString(StringBuffer sink) { + if(null == sink) { + sink = new StringBuffer(); + } + + int samples = sampleBuffers ? numSamples : 0 ; + + super.toString(sink); + + sink.append(", accum-rgba ").append(accumRedBits).append("/").append(accumGreenBits).append("/").append(accumBlueBits).append("/").append(accumAlphaBits); + sink.append(", dp/st/ms: ").append(depthBits).append("/").append(stencilBits).append("/").append(samples); + if(doubleBuffered) { + sink.append(", dbl"); + } else { + sink.append(", one"); + } + if(stereo) { + sink.append(", stereo"); + } else { + sink.append(", mono "); + } + if(hardwareAccelerated) { + sink.append(", hw, "); + } else { + sink.append(", sw, "); + } + sink.append(glProfile); + if(!isOnscreen()) { + if(pbuffer) { + sink.append(", pbuffer [r2t ").append(pbufferRenderToTexture?1:0) + .append(", r2tr ").append(pbufferRenderToTextureRectangle?1:0) + .append(", float ").append(pbufferFloatingPointBuffers?1:0) + .append("]"); + } else { + sink.append(", pixmap"); + } + } + + return sink; + } + /** Returns a textual representation of this GLCapabilities object. */ public String toString() { StringBuffer msg = new StringBuffer(); - msg.append("GLCapabilities["); - msg.append(super.toString()); - msg.append(", GL profile: " + glProfile + - ", PBuffer: " + pbuffer + - ", DoubleBuffered: " + doubleBuffered + - ", Stereo: " + stereo + - ", HardwareAccelerated: " + hardwareAccelerated + - ", DepthBits: " + depthBits + - ", StencilBits: " + stencilBits + - ", Red Accum: " + accumRedBits + - ", Green Accum: " + accumGreenBits + - ", Blue Accum: " + accumBlueBits + - ", Alpha Accum: " + accumAlphaBits + - ", Multisample: " + sampleBuffers + - ", Num samples: "+(sampleBuffers ? numSamples : 0)); - msg.append(", PBuffer-FloatingPointBuffers: "+pbufferFloatingPointBuffers+ - ", PBuffer-RenderToTexture: "+pbufferRenderToTexture+ - ", PBuffer-RenderToTextureRectangle: "+pbufferRenderToTextureRectangle+ "]"); + msg.append("GLCaps["); + toString(msg); + msg.append("]"); return msg.toString(); } } diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java index 8c06acfd6..4c9b737d5 100644 --- a/src/jogl/classes/javax/media/opengl/GLContext.java +++ b/src/jogl/classes/javax/media/opengl/GLContext.java @@ -40,10 +40,10 @@ package javax.media.opengl; -import com.jogamp.opengl.impl.Debug; import java.util.HashMap; import java.util.HashSet; import javax.media.nativewindow.AbstractGraphicsDevice; +import com.jogamp.opengl.impl.Debug; /** Abstraction for an OpenGL rendering context. In order to perform OpenGL rendering, a context must be "made current" on the current diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java index fe591c9fc..500173cf2 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java @@ -40,13 +40,14 @@ package javax.media.opengl; -import com.jogamp.common.JogampRuntimeException; -import com.jogamp.common.impl.Debug; -import com.jogamp.common.util.ReflectionUtil; - import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; +import java.util.List; + +import com.jogamp.common.JogampRuntimeException; +import com.jogamp.common.impl.Debug; +import com.jogamp.common.util.ReflectionUtil; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; @@ -239,6 +240,24 @@ public abstract class GLDrawableFactory { */ public abstract boolean getIsDeviceCompatible(AbstractGraphicsDevice device); + protected final AbstractGraphicsDevice validateDevice(AbstractGraphicsDevice device) { + if(null==device) { + device = getDefaultDevice(); + if(null==device) { + throw new InternalError("no default device"); + } + if (GLProfile.DEBUG) { + System.err.println("Info: GLDrawableFactory.validateDevice: using default device : "+device); + } + } else if( !getIsDeviceCompatible(device) ) { + if (GLProfile.DEBUG) { + System.err.println("Info: GLDrawableFactory.validateDevice: device not compatible : "+device); + } + return null; + } + return device; + } + /** * Returns true if a shared context is already mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()}, * or if a new shared context could be created and mapped. Otherwise return false.<br> @@ -258,24 +277,28 @@ public abstract class GLDrawableFactory { * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device. */ protected final GLContext getOrCreateSharedContext(AbstractGraphicsDevice device) { - if(null==device) { - device = getDefaultDevice(); - if(null==device) { - throw new InternalError("no default device"); - } - if (GLProfile.DEBUG) { - System.err.println("Info: GLDrawableFactory.getOrCreateSharedContext: using default device : "+device); - } - } else if( !getIsDeviceCompatible(device) ) { - if (GLProfile.DEBUG) { - System.err.println("Info: GLDrawableFactory.getOrCreateSharedContext: device not compatible : "+device); - } - return null; + device = validateDevice(device); + if(null!=device) { + return getOrCreateSharedContextImpl(device); } - return getOrCreateSharedContextImpl(device); + return null; } protected abstract GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device); + /** + * Returns the sole GLDrawableFactory instance for the desktop (X11, WGL, ..) if exist or null + */ + public static GLDrawableFactory getDesktopFactory() { + return nativeOSFactory; + } + + /** + * Returns the sole GLDrawableFactory instance for EGL if exist or null + */ + public static GLDrawableFactory getEGLFactory() { + return eglFactory; + } + /** * Returns the sole GLDrawableFactory instance. * @@ -300,16 +323,6 @@ public abstract class GLDrawableFactory { throw new GLException("No native platform GLDrawableFactory, nor EGLDrawableFactory available: "+glProfileImplName); } - /** - * Returns the sole GLDrawableFactory instance. - * - * @param device AbstractGraphicsDevice to determine the factory type, ie EGLDrawableFactory, - * or one of the native GLDrawableFactory's, ie X11/GLX, Windows/WGL or MacOSX/CGL. - */ - public static GLDrawableFactory getFactory(AbstractGraphicsDevice device) throws GLException { - return getFactoryImpl(device); - } - protected static GLDrawableFactory getFactoryImpl(AbstractGraphicsDevice device) throws GLException { if(null != nativeOSFactory && nativeOSFactory.getIsDeviceCompatible(device)) { return nativeOSFactory; @@ -320,6 +333,24 @@ public abstract class GLDrawableFactory { throw new GLException("No native platform GLDrawableFactory, nor EGLDrawableFactory available: "+device); } + /** + * Returns an array of available GLCapabilities for the device.<br> + * The list is sorted by the native ID, ascending.<br> + * The chosen GLProfile statement in the result may not refer to the maximum available profile + * due to implementation constraints, ie using the shared resource. + * + * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device. + * @return A list of {@link javax.media.opengl.GLCapabilitiesImmutable}'s, maybe empty if none is available. + */ + public final List/*GLCapabilitiesImmutable*/ getAvailableCapabilities(AbstractGraphicsDevice device) { + device = validateDevice(device); + if(null!=device) { + return getAvailableCapabilitiesImpl(device); + } + return null; + } + protected abstract List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device); + //---------------------------------------------------------------------- // Methods to create high-level objects diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java index 3e1727f50..10d92b050 100644 --- a/src/jogl/classes/javax/media/opengl/GLProfile.java +++ b/src/jogl/classes/javax/media/opengl/GLProfile.java @@ -47,12 +47,13 @@ import com.jogamp.opengl.impl.GLDrawableFactoryImpl; import com.jogamp.opengl.impl.GLDynamicLookupHelper; import com.jogamp.opengl.impl.DesktopGLDynamicLookupHelper; import com.jogamp.opengl.JoglVersion; -import java.util.HashMap; -import java.util.Iterator; -import java.security.*; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.opengl.fixedfunc.GLPointerFunc; import javax.media.nativewindow.NativeWindowFactory; +import java.util.HashMap; +import java.util.Iterator; +import java.security.*; +import java.util.List; /** * Specifies the the OpenGL profile. @@ -346,17 +347,35 @@ public class GLProfile { /** * All GL Profiles in the order of default detection. - * Desktop compatibility profiles (the one with fixed function pipeline) comes first. - * - * FIXME GL3GL4: Due to GL3 and GL4 implementation bugs, we still choose GL2 first, if available! + * Desktop compatibility profiles (the one with fixed function pipeline) comes first + * from highest to lowest version. * * <ul> - * <li> GL2 - * <li> GL3bc * <li> GL4bc + * <li> GL3bc + * <li> GL2 * <li> GL2GL3 + * <li> GL4 * <li> GL3 + * <li> GL2ES2 + * <li> GLES2 + * <li> GL2ES1 + * <li> GLES1 + * </ul> + * + */ + public static final String[] GL_PROFILE_LIST_ALL = new String[] { GL4bc, GL3bc, GL2, GL2GL3, GL4, GL3, GL2ES2, GLES2, GL2ES1, GLES1 }; + + /** + * Order of maximum profiles. + * + * <ul> + * <li> GL4bc * <li> GL4 + * <li> GL3bc + * <li> GL3 + * <li> GL2 + * <li> GL2GL3 * <li> GL2ES2 * <li> GLES2 * <li> GL2ES1 @@ -364,7 +383,21 @@ public class GLProfile { * </ul> * */ - public static final String[] GL_PROFILE_LIST_ALL = new String[] { GL2, GL3bc, GL4bc, GL2GL3, GL3, GL4, GL2ES2, GLES2, GL2ES1, GLES1 }; + public static final String[] GL_PROFILE_LIST_MAX = new String[] { GL4bc, GL4, GL3bc, GL3, GL2, GL2GL3, GL2ES2, GLES2, GL2ES1, GLES1 }; + + /** + * Order of minimum original desktop profiles. + * + * <ul> + * <li> GL2 + * <li> GL3bc + * <li> GL4bc + * <li> GL3 + * <li> GL4 + * </ul> + * + */ + public static final String[] GL_PROFILE_LIST_MIN_DESKTOP = new String[] { GL2, GL3bc, GL4bc, GL3, GL4 }; /** * Order of maximum fixed function profiles @@ -394,13 +427,11 @@ public class GLProfile { * </ul> * */ - public static final String[] GL_PROFILE_LIST_MAX_PROGSHADER = new String[] { GL4, GL4bc, GL3, GL3bc, GL2, GL2ES2, GLES2 }; + public static final String[] GL_PROFILE_LIST_MAX_PROGSHADER = new String[] { GL4bc, GL4, GL3bc, GL3, GL2, GL2ES2, GLES2 }; /** * All GL2ES2 Profiles in the order of default detection. * - * FIXME GL3GL4: Due to GL3 and GL4 implementation bugs, we still choose GL2 first, if available! - * * <ul> * <li> GL2ES2 * <li> GL2 @@ -410,13 +441,11 @@ public class GLProfile { * </ul> * */ - public static final String[] GL_PROFILE_LIST_GL2ES2 = new String[] { GL2ES2, GL2, GL3, GL4, GLES2 }; + public static final String[] GL_PROFILE_LIST_GL2ES2 = new String[] { GL2ES2, GL4, GL3, GL2, GLES2 }; /** * All GL2ES1 Profiles in the order of default detection. * - * FIXME GL3GL4: Due to GL3 and GL4 implementation bugs, we still choose GL2 first, if available! - * * <ul> * <li> GL2ES1 * <li> GL2 @@ -426,7 +455,7 @@ public class GLProfile { * </ul> * */ - public static final String[] GL_PROFILE_LIST_GL2ES1 = new String[] { GL2ES1, GL2, GL3bc, GL4bc, GLES1 }; + public static final String[] GL_PROFILE_LIST_GL2ES1 = new String[] { GL2ES1, GL4bc, GL3bc, GL2, GLES1 }; /** * All GLES Profiles in the order of default detection. @@ -454,7 +483,48 @@ public class GLProfile { } /** - * Returns the highest profile, implementing the fixed function pipeline + * Returns the highest profile. + * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MAX} + * + * @throws GLException if no implementation for the given profile is found. + * @see #GL_PROFILE_LIST_MAX + */ + public static GLProfile getMaximum(AbstractGraphicsDevice device) + throws GLException + { + return get(device, GL_PROFILE_LIST_MAX); + } + + /** Uses the default device */ + public static GLProfile getMaximum() + throws GLException + { + return get(GL_PROFILE_LIST_MAX); + } + + /** + * Returns the lowest desktop profile. + * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MIN_DESKTOP} + * + * @throws GLException if no implementation for the given profile is found. + * @see #GL_PROFILE_LIST_MIN_DESKTOP + */ + public static GLProfile getMinDesktop(AbstractGraphicsDevice device) + throws GLException + { + return get(device, GL_PROFILE_LIST_MIN_DESKTOP); + } + + /** Uses the default device */ + public static GLProfile getMinDesktop() + throws GLException + { + return get(GL_PROFILE_LIST_MIN_DESKTOP); + } + + + /** + * Returns the highest profile, implementing the fixed function pipeline. * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MAX_FIXEDFUNC} * * @throws GLException if no implementation for the given profile is found. @@ -1301,8 +1371,16 @@ public class GLProfile { System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": "+glAvailabilityToString(device)); if(addedDesktopProfile) { dumpGLInfo(desktopFactory, device); + List/*<GLCapabilitiesImmutable>*/ availCaps = desktopFactory.getAvailableCapabilities(device); + for(int i=0; i<availCaps.size(); i++) { + System.err.println(availCaps.get(i)); + } } else if(addedEGLProfile) { dumpGLInfo(eglFactory, device); + List/*<GLCapabilitiesImmutable>*/ availCaps = eglFactory.getAvailableCapabilities(device); + for(int i=0; i<availCaps.size(); i++) { + System.err.println(availCaps.get(i)); + } } } @@ -1314,13 +1392,10 @@ public class GLProfile { System.err.println("GLProfile.dumpGLInfo: "+ctx); ctx.makeCurrent(); try { - System.err.println("GLProfile.dumpGLInfo: p2"); System.err.println(JoglVersion.getGLInfo(ctx.getGL(), null)); - System.err.println("GLProfile.dumpGLInfo: p3"); } finally { ctx.release(); } - System.err.println("GLProfile.dumpGLInfo: p4"); } public static AbstractGraphicsDevice getDefaultDevice() { diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index d47501795..acabe58a5 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -54,9 +54,10 @@ import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.geom.Rectangle2D; -import com.jogamp.common.GlueGenVersion; -import com.jogamp.common.util.VersionUtil; -import com.jogamp.common.util.locks.RecursiveLock; +import java.awt.EventQueue; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; import javax.media.nativewindow.WindowClosingProtocol; import javax.media.nativewindow.AbstractGraphicsConfiguration; @@ -69,7 +70,6 @@ import javax.media.nativewindow.awt.AWTGraphicsConfiguration; import javax.media.nativewindow.awt.AWTGraphicsDevice; import javax.media.nativewindow.awt.AWTGraphicsScreen; import javax.media.nativewindow.awt.AWTWindowClosingProtocol; -import com.jogamp.nativewindow.NativeWindowVersion; import javax.media.opengl.GL; import javax.media.opengl.GLAnimatorControl; @@ -85,14 +85,17 @@ import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; import javax.media.opengl.GLRunnable; import javax.media.opengl.Threading; + +import com.jogamp.nativewindow.NativeWindowVersion; +import com.jogamp.common.GlueGenVersion; +import com.jogamp.common.util.VersionUtil; import com.jogamp.opengl.JoglVersion; + +import com.jogamp.common.util.locks.RecursiveLock; import com.jogamp.opengl.impl.Debug; import com.jogamp.opengl.impl.GLContextImpl; import com.jogamp.opengl.impl.GLDrawableHelper; import com.jogamp.opengl.impl.ThreadingImpl; -import java.awt.EventQueue; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; // FIXME: Subclasses need to call resetGLFunctionAvailability() on their // context whenever the displayChanged() function is called on our @@ -996,6 +999,12 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing System.err.println(NativeWindowVersion.getInstance()); System.err.println(JoglVersion.getInstance()); + GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory(); + List/*<GLCapabilitiesImmutable>*/ availCaps = factory.getAvailableCapabilities(null); + for(int i=0; i<availCaps.size(); i++) { + System.err.println(availCaps.get(i)); + } + GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDesktopDevice()) ); Frame frame = new Frame("JOGL AWT Test"); |