diff options
Diffstat (limited to 'src/jogl')
54 files changed, 2387 insertions, 1602 deletions
diff --git a/src/jogl/classes/com/sun/opengl/impl/GLContextShareSet.java b/src/jogl/classes/com/sun/opengl/impl/GLContextShareSet.java index d02b8c8a6..5f8fc1c84 100644 --- a/src/jogl/classes/com/sun/opengl/impl/GLContextShareSet.java +++ b/src/jogl/classes/com/sun/opengl/impl/GLContextShareSet.java @@ -241,11 +241,10 @@ public class GLContextShareSet { // // FIXME: probably need to do something different here // // Need to be able to figure out the GraphicsDevice for the // // older context if it's on-screen - // GraphicsConfiguration gc = GraphicsEnvironment. + // GraphicsDevice device = GraphicsEnvironment. // getLocalGraphicsEnvironment(). - // getDefaultScreenDevice(). - // getDefaultConfiguration(); - // GLContext j2dShareContext = Java2D.getShareContext(gc); + // getDefaultScreenDevice(); + // GLContext j2dShareContext = Java2D.getShareContext(device); // if (impl1 != null && impl1 == j2dShareContext) { // impl1 = null; // } diff --git a/src/jogl/classes/com/sun/opengl/impl/GLDrawableImpl.java b/src/jogl/classes/com/sun/opengl/impl/GLDrawableImpl.java index 9df572af1..7a0f072a4 100644 --- a/src/jogl/classes/com/sun/opengl/impl/GLDrawableImpl.java +++ b/src/jogl/classes/com/sun/opengl/impl/GLDrawableImpl.java @@ -43,16 +43,12 @@ import javax.media.nativewindow.*; import javax.media.opengl.*; public abstract class GLDrawableImpl implements GLDrawable { - private GLCapabilities requestedCapabilities; protected GLDrawableImpl(GLDrawableFactory factory, NativeWindow comp, - GLCapabilities requestedCapabilities, boolean realized) { this.factory = factory; this.component = comp; - this.requestedCapabilities = - (requestedCapabilities == null) ? null : (GLCapabilities) requestedCapabilities.clone(); this.realized = realized; } @@ -73,20 +69,13 @@ public abstract class GLDrawableImpl implements GLDrawable { return GLContextImpl.toHexString(hex); } - protected GLCapabilities getRequestedGLCapabilities() { - return requestedCapabilities; - } - public GLCapabilities getChosenGLCapabilities() { - if (chosenCapabilities == null) + GLCapabilities caps = (GLCapabilities)component.getGraphicsConfiguration().getCapabilities(); + if (caps == null) return null; // Must return a new copy to avoid mutation by end user - return (GLCapabilities) chosenCapabilities.clone(); - } - - protected void setChosenGLCapabilities(GLCapabilities caps) { - chosenCapabilities = (caps==null) ? null : (GLCapabilities) caps.clone(); + return (GLCapabilities)caps.clone(); } public NativeWindow getNativeWindow() { @@ -100,7 +89,6 @@ public abstract class GLDrawableImpl implements GLDrawable { public void setRealized(boolean realized) { this.realized = realized; if(!realized) { - setChosenGLCapabilities(null); component.invalidate(); } } @@ -141,7 +129,6 @@ public abstract class GLDrawableImpl implements GLDrawable { protected GLDrawableFactory factory; protected NativeWindow component; - private GLCapabilities chosenCapabilities; // Indicates whether the component (if an onscreen context) has been // realized. Plausibly, before the component is realized the JAWT diff --git a/src/jogl/classes/com/sun/opengl/impl/InternalBufferUtil.java.javame_cdc_fp b/src/jogl/classes/com/sun/opengl/impl/InternalBufferUtil.java.javame_cdc_fp index 1b989dc37..2614e52d4 100644 --- a/src/jogl/classes/com/sun/opengl/impl/InternalBufferUtil.java.javame_cdc_fp +++ b/src/jogl/classes/com/sun/opengl/impl/InternalBufferUtil.java.javame_cdc_fp @@ -66,6 +66,24 @@ public class InternalBufferUtil { } //---------------------------------------------------------------------- + // Copy routines (type-to-type) + // + + /** Copies the <i>remaining</i> elements (as defined by + <code>limit() - position()</code>) in the passed ByteBuffer into + a newly-allocated direct ByteBuffer. The returned buffer will + have its byte order set to the host platform's native byte + order. The position of the newly-allocated buffer will be zero, + and the position of the passed buffer is unchanged (though its + mark is changed). */ + public static ByteBuffer copyByteBuffer(ByteBuffer orig) { + ByteBuffer dest = newByteBuffer(orig.remaining()); + dest.put(orig); + dest.rewind(); + return dest; + } + + //---------------------------------------------------------------------- // Conversion routines // diff --git a/src/jogl/classes/com/sun/opengl/impl/NativeLibLoader.java b/src/jogl/classes/com/sun/opengl/impl/NativeLibLoader.java index 054b1e83b..eaed6ad81 100644 --- a/src/jogl/classes/com/sun/opengl/impl/NativeLibLoader.java +++ b/src/jogl/classes/com/sun/opengl/impl/NativeLibLoader.java @@ -59,7 +59,7 @@ public class NativeLibLoader extends NativeLibLoaderBase { }); } - public static void loadGL2() { + public static void loadGLDesktop() { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { loadLibrary("jogl_gl2", nativewindowX11Preload, true); @@ -109,6 +109,8 @@ public class NativeLibLoader extends NativeLibLoaderBase { // Support for the new JNLPAppletLauncher // + private static boolean DEBUG = true; + private static class JOGLAction implements NativeLibLoaderBase.LoaderAction { public void loadLibrary(String libname, String[] preload, boolean preloadIgnoreError) { @@ -118,6 +120,7 @@ public class NativeLibLoader extends NativeLibLoaderBase { loadLibraryInternal(preload[i]); } catch (UnsatisfiedLinkError e) { + if(DEBUG) e.printStackTrace(); if (!preloadIgnoreError && e.getMessage().indexOf("already loaded") < 0) { throw e; } @@ -156,6 +159,7 @@ public class NativeLibLoader extends NativeLibLoaderBase { jnlpLoadLibraryMethod.invoke(null, new Object[] { libraryName }); } catch (Exception e) { Throwable t = e; + if(DEBUG) t.printStackTrace(); if (t instanceof InvocationTargetException) { t = ((InvocationTargetException) t).getTargetException(); } diff --git a/src/jogl/classes/com/sun/opengl/impl/awt/Java2D.java b/src/jogl/classes/com/sun/opengl/impl/awt/Java2D.java index 7da32f707..5bac0097c 100755 --- a/src/jogl/classes/com/sun/opengl/impl/awt/Java2D.java +++ b/src/jogl/classes/com/sun/opengl/impl/awt/Java2D.java @@ -47,6 +47,8 @@ import java.lang.reflect.*; import java.security.*; import javax.media.opengl.*; +import javax.media.nativewindow.*; +import javax.media.nativewindow.awt.*; /** Defines integration with the Java2D OpenGL pipeline. This integration is only supported in 1.6 and is highly experimental. */ @@ -285,8 +287,7 @@ public class Java2D { // Queue Flusher Thread, which isn't allowed initFBOShareContext(GraphicsEnvironment. getLocalGraphicsEnvironment(). - getDefaultScreenDevice(). - getDefaultConfiguration()); + getDefaultScreenDevice()); AWTUtil.lockToolkit(); try { @@ -437,8 +438,7 @@ public class Java2D { // FIXME: this may need adjustment initFBOShareContext(GraphicsEnvironment. getLocalGraphicsEnvironment(). - getDefaultScreenDevice(). - getDefaultConfiguration()); + getDefaultScreenDevice()); if (j2dFBOShareContext != null) { return j2dFBOShareContext; } @@ -449,8 +449,8 @@ public class Java2D { context", with which all contexts created by JOGL must share textures and display lists when the FBO option is enabled for the Java2D/OpenGL pipeline. */ - public static GLContext getShareContext(GraphicsConfiguration gc) { - initFBOShareContext(gc); + public static GLContext getShareContext(GraphicsDevice device) { + initFBOShareContext(device); // FIXME: for full generality probably need to have multiple of // these, one per GraphicsConfiguration seen? return j2dFBOShareContext; @@ -536,7 +536,7 @@ public class Java2D { return i.intValue(); } - private static void initFBOShareContext(final GraphicsConfiguration gc) { + private static void initFBOShareContext(final GraphicsDevice device) { // Note 1: this must not be done in the static initalizer due to // deadlock problems. @@ -556,9 +556,10 @@ public class Java2D { if (DEBUG) { System.err.println("Starting initialization of J2D FBO share context"); } - invokeWithOGLSharedContextCurrent(gc, new Runnable() { + invokeWithOGLSharedContextCurrent(device.getDefaultConfiguration(), new Runnable() { public void run() { - j2dFBOShareContext = GLDrawableFactory.getFactory().createExternalGLContext(); + // AbstractGraphicsScreen awtscreen = AWTGraphicsScreen.createScreenDevice(device); + j2dFBOShareContext = GLDrawableFactory.getFactory().createExternalGLContext(/*awtscreen*/); } }); if (DEBUG) { diff --git a/src/jogl/classes/com/sun/opengl/impl/egl/EGLContext.java b/src/jogl/classes/com/sun/opengl/impl/egl/EGLContext.java index 4e2347fcc..d6d80bc1f 100755 --- a/src/jogl/classes/com/sun/opengl/impl/egl/EGLContext.java +++ b/src/jogl/classes/com/sun/opengl/impl/egl/EGLContext.java @@ -44,7 +44,7 @@ import java.util.*; public class EGLContext extends GLContextImpl { private EGLDrawable drawable; - private long context; + private long eglContext; private boolean eglQueryStringInitialized; private boolean eglQueryStringAvailable; private EGLExt eglExt; @@ -89,26 +89,26 @@ public class EGLContext extends GLContextImpl { } public long getContext() { - return context; + return eglContext; } private int makeCurrentImplInner() throws GLException { boolean created = false; - if (context == 0) { + if (eglContext == 0) { create(); if (DEBUG) { System.err.println(getThreadName() + ": !!! Created GL context 0x" + - Long.toHexString(context) + " for " + getClass().getName()); + Long.toHexString(eglContext) + " for " + getClass().getName()); } created = true; } - if (EGL.eglGetCurrentContext() != context) { + if (EGL.eglGetCurrentContext() != eglContext) { if (!EGL.eglMakeCurrent(drawable.getDisplay(), drawable.getSurface(), drawable.getSurface(), - context)) { + eglContext)) { throw new GLException("Error making context 0x" + - Long.toHexString(context) + " current: error code " + EGL.eglGetError()); + Long.toHexString(eglContext) + " current: error code " + EGL.eglGetError()); } } @@ -156,7 +156,7 @@ public class EGLContext extends GLContextImpl { EGL.EGL_NO_SURFACE, EGL.EGL_NO_CONTEXT)) { throw new GLException("Error freeing OpenGL context 0x" + - Long.toHexString(context) + ": error code " + EGL.eglGetError()); + Long.toHexString(eglContext) + ": error code " + EGL.eglGetError()); } } finally { getDrawableImpl().getFactoryImpl().unlockToolkit(); @@ -167,12 +167,12 @@ public class EGLContext extends GLContextImpl { protected void destroyImpl() throws GLException { getDrawableImpl().getFactoryImpl().lockToolkit(); try { - if (context != 0) { - if (!EGL.eglDestroyContext(drawable.getDisplay(), context)) { + if (eglContext != 0) { + if (!EGL.eglDestroyContext(drawable.getDisplay(), eglContext)) { throw new GLException("Error destroying OpenGL context 0x" + - Long.toHexString(context) + ": error code " + EGL.eglGetError()); + Long.toHexString(eglContext) + ": error code " + EGL.eglGetError()); } - context = 0; + eglContext = 0; GLContextShareSet.contextDestroyed(this); } } finally { @@ -181,14 +181,15 @@ public class EGLContext extends GLContextImpl { } protected void create() throws GLException { - long display = drawable.getDisplay(); - _EGLConfig config = drawable.getEGLConfig().getNativeConfig(); + long eglDisplay = drawable.getDisplay(); + EGLGraphicsConfiguration config = drawable.getGraphicsConfiguration(); + _EGLConfig eglConfig = config.getNativeConfig(); long shareWith = EGL.EGL_NO_CONTEXT; - if (display == 0) { + if (eglDisplay == 0) { throw new GLException("Error: attempted to create an OpenGL context without a display connection"); } - if (config == null) { + if (eglConfig == null) { throw new GLException("Error: attempted to create an OpenGL context without a graphics configuration"); } EGLContext other = (EGLContext) GLContextShareSet.getShareContext(this); @@ -203,28 +204,28 @@ public class EGLContext extends GLContextImpl { EGL.EGL_CONTEXT_CLIENT_VERSION, -1, EGL.EGL_NONE }; - if (GLProfile.isGLES2()) { + if (GLProfile.usesNativeGLES2()) { contextAttrs[1] = 2; - } else if (GLProfile.isGLES1()) { + } else if (GLProfile.usesNativeGLES1()) { contextAttrs[1] = 1; } else { throw new GLException("Error creating OpenGL context - invalid GLProfile"); } - context = EGL.eglCreateContext(display, config, shareWith, contextAttrs, 0); - if (context == 0) { + eglContext = EGL.eglCreateContext(eglDisplay, eglConfig, shareWith, contextAttrs, 0); + if (eglContext == 0) { throw new GLException("Error creating OpenGL context"); } GLContextShareSet.contextCreated(this); if (DEBUG) { System.err.println(getThreadName() + ": !!! Created OpenGL context 0x" + - Long.toHexString(context) + " for " + this + + Long.toHexString(eglContext) + " for " + this + ", surface 0x" + Long.toHexString(drawable.getSurface()) + ", sharing with 0x" + Long.toHexString(shareWith)); } } public boolean isCreated() { - return (context != 0); + return (eglContext != 0); } protected void resetGLFunctionAvailability() { @@ -250,7 +251,7 @@ public class EGLContext extends GLContextImpl { GLDrawableFactoryImpl factory = getDrawableImpl().getFactoryImpl(); factory.lockToolkit(); try { - String ret = EGL.eglQueryString(drawable.getNativeWindow().getDisplayHandle(), + String ret = EGL.eglQueryString(drawable.getDisplay(), EGL.EGL_EXTENSIONS); if (DEBUG) { System.err.println("!!! EGL extensions: " + ret); diff --git a/src/jogl/classes/com/sun/opengl/impl/egl/EGLDrawable.java b/src/jogl/classes/com/sun/opengl/impl/egl/EGLDrawable.java index 105ccc6d9..fe9544666 100755 --- a/src/jogl/classes/com/sun/opengl/impl/egl/EGLDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/egl/EGLDrawable.java @@ -39,45 +39,42 @@ import com.sun.opengl.impl.GLDrawableImpl; import com.sun.nativewindow.impl.NWReflection; import javax.media.nativewindow.*; +import javax.media.nativewindow.egl.*; import javax.media.opengl.*; public class EGLDrawable extends GLDrawableImpl { - private GLCapabilitiesChooser chooser; - private long display; - private EGLConfig config; - private long surface; + private long eglDisplay; + private EGLGraphicsConfiguration eglConfig; + private boolean ownEGLDisplay = false; + private long eglSurface; private int[] tmp = new int[1]; public EGLDrawable(EGLDrawableFactory factory, - NativeWindow component, - GLCapabilities requestedCapabilities, - GLCapabilitiesChooser chooser) throws GLException { - super(factory, component, requestedCapabilities, false); - this.chooser = chooser; - surface=EGL.EGL_NO_SURFACE; - display=0; - config=null; + NativeWindow component) throws GLException { + super(factory, component, false); + eglSurface=EGL.EGL_NO_SURFACE; + eglDisplay=0; } public long getDisplay() { - return display; + return eglDisplay; } - public EGLConfig getEGLConfig() { - return config; + public long getSurface() { + return eglSurface; } - public long getSurface() { - return surface; + public EGLGraphicsConfiguration getGraphicsConfiguration() { + return eglConfig; } protected void setSurface() { - if (EGL.EGL_NO_SURFACE==surface) { + if (EGL.EGL_NO_SURFACE==eglSurface) { + lockSurface(); try { - lockSurface(); // Create the window surface - surface = EGL.eglCreateWindowSurface(display, config.getNativeConfig(), component.getWindowHandle(), null); - if (EGL.EGL_NO_SURFACE==surface) { + eglSurface = EGL.eglCreateWindowSurface(eglDisplay, eglConfig.getNativeConfig(), component.getWindowHandle(), null); + if (EGL.EGL_NO_SURFACE==eglSurface) { throw new GLException("Creation of window surface (eglCreateWindowSurface) failed, component: "+component); } } finally { @@ -92,41 +89,51 @@ public class EGLDrawable extends GLDrawableImpl { public void setRealized(boolean realized) { if (realized) { - if (NWReflection.instanceOf(component, "com.sun.javafx.newt.opengl.kd.KDWindow")) { - // KDWindows holds already determined EGL values - display = component.getDisplayHandle(); - if (display==0) { - throw new GLException("KDWindow has null display"); + AbstractGraphicsConfiguration aConfig = component.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice(); + if(aDevice instanceof EGLGraphicsDevice) { + // just fetch the data .. trust but verify .. + eglDisplay = aDevice.getHandle(); + if (eglDisplay == EGL.EGL_NO_DISPLAY) { + throw new GLException("Invalid EGL display in EGLGraphicsDevice from "+aDevice); } - if (display == EGL.EGL_NO_DISPLAY) { - throw new GLException("KDWindow has EGL_NO_DISPLAY"); - } - EGLConfig config = (EGLConfig) component.getGraphicsConfiguration(); - int configID = 0; - if (config != null) { - configID = config.getNativeConfigID(); + if(aConfig instanceof EGLGraphicsConfiguration) { + eglConfig = (EGLGraphicsConfiguration) aConfig; // done .. + if (null == eglConfig) { + throw new GLException("Null EGLGraphicsConfiguration from "+aConfig); + } + } else { + throw new GLException("EGLGraphicsConfiguration doesn't carry a EGLGraphicsDevice: "+aConfig); } } else { - display = EGL.eglGetDisplay((0!=component.getDisplayHandle())?component.getDisplayHandle():EGL.EGL_DEFAULT_DISPLAY); - if (display == EGL.EGL_NO_DISPLAY) { - throw new GLException("eglGetDisplay failed"); + // create a new EGL config .. + ownEGLDisplay=true; + eglDisplay = EGL.eglGetDisplay((0!=aDevice.getHandle())?aDevice.getHandle():EGL.EGL_DEFAULT_DISPLAY); + if (eglDisplay == EGL.EGL_NO_DISPLAY) { + throw new GLException("Failed to created EGL display from "+aDevice); } - if (!EGL.eglInitialize(display, null, null)) { + if (!EGL.eglInitialize(eglDisplay, null, null)) { throw new GLException("eglInitialize failed"); } - config = new EGLConfig(display, getRequestedGLCapabilities()); + EGLGraphicsDevice e = new EGLGraphicsDevice(eglDisplay); + DefaultGraphicsScreen s = new DefaultGraphicsScreen(e, aConfig.getScreen().getIndex()); + GLCapabilities caps = (GLCapabilities) aConfig.getCapabilities(); + eglConfig = (EGLGraphicsConfiguration) GraphicsConfigurationFactory.getFactory(e).chooseGraphicsConfiguration(caps, null, s); + if (null == eglConfig) { + throw new GLException("Couldn't create EGLGraphicsConfiguration from "+s); + } } - setChosenGLCapabilities(config.getCapabilities()); - } else if (surface != EGL.EGL_NO_SURFACE) { + } else if (eglSurface != EGL.EGL_NO_SURFACE) { // Destroy the window surface - if (!EGL.eglDestroySurface(display, surface)) { + if (!EGL.eglDestroySurface(eglDisplay, eglSurface)) { throw new GLException("Error destroying window surface (eglDestroySurface)"); } - surface = EGL.EGL_NO_SURFACE; - if (EGL.EGL_NO_DISPLAY!=display) { - EGL.eglTerminate(display); - display=EGL.EGL_NO_DISPLAY; + eglSurface = EGL.EGL_NO_SURFACE; + if (ownEGLDisplay && EGL.EGL_NO_DISPLAY!=eglDisplay) { + EGL.eglTerminate(eglDisplay); } + eglDisplay=EGL.EGL_NO_DISPLAY; + eglConfig=null; } super.setRealized(realized); } @@ -136,14 +143,14 @@ public class EGLDrawable extends GLDrawableImpl { } public int getWidth() { - if (!EGL.eglQuerySurface(display, surface, EGL.EGL_WIDTH, tmp, 0)) { + if (!EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_WIDTH, tmp, 0)) { throw new GLException("Error querying surface width"); } return tmp[0]; } public int getHeight() { - if (!EGL.eglQuerySurface(display, surface, EGL.EGL_HEIGHT, tmp, 0)) { + if (!EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_HEIGHT, tmp, 0)) { throw new GLException("Error querying surface height"); } return tmp[0]; @@ -158,7 +165,7 @@ public class EGLDrawable extends GLDrawableImpl { } } - EGL.eglSwapBuffers(display, surface); + EGL.eglSwapBuffers(eglDisplay, eglSurface); } finally { unlockSurface(); @@ -169,9 +176,8 @@ public class EGLDrawable extends GLDrawableImpl { public String toString() { return "EGLDrawable[ realized "+getRealized()+ ", window "+getNativeWindow()+ - ", egl display " + display + - ", " + config + - ", egl surface " + surface + + ", egl surface " + eglSurface + + ", "+eglConfig+ ", factory "+getFactory()+"]"; } } diff --git a/src/jogl/classes/com/sun/opengl/impl/egl/EGLDrawableFactory.java b/src/jogl/classes/com/sun/opengl/impl/egl/EGLDrawableFactory.java index a5f1d2ca3..d9f17689c 100755 --- a/src/jogl/classes/com/sun/opengl/impl/egl/EGLDrawableFactory.java +++ b/src/jogl/classes/com/sun/opengl/impl/egl/EGLDrawableFactory.java @@ -39,6 +39,7 @@ import java.util.*; import javax.media.nativewindow.*; import javax.media.opengl.*; import com.sun.opengl.impl.*; +import com.sun.nativewindow.impl.*; import com.sun.gluegen.runtime.NativeLibrary; public class EGLDrawableFactory extends GLDrawableFactoryImpl { @@ -51,6 +52,17 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { loadGLESLibrary(); EGL.resetProcAddressTable(this); + + // Register our GraphicsConfigurationFactory implementations + // The act of constructing them causes them to be registered + new EGLGraphicsConfigurationFactory(); + + // Check for other underlying stuff .. + if(NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType())) { + try { + NWReflection.createInstance("com.sun.opengl.impl.x11.glx.X11GLXGraphicsConfigurationFactory"); + } catch (Throwable t) {} + } } private NativeLibrary loadFirstAvailable(List/*<String>*/ libNames, ClassLoader loader) { @@ -70,7 +82,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { List/*<String>*/ glesLibNames = new ArrayList(); List/*<String>*/ eglLibNames = new ArrayList(); - if (GLProfile.isGLES2()) { + if (GLProfile.usesNativeGLES2()) { // Unix glesLibNames.add("libGLES20"); glesLibNames.add("libGLESv2"); @@ -79,7 +91,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { glesLibNames.add("GLES20"); glesLibNames.add("GLESv2"); glesLibNames.add("GLESv2_CM"); - } else if (GLProfile.isGLES1()) { + } else if (GLProfile.usesNativeGLES1()) { // Unix glesLibNames.add("libGLES_CM"); glesLibNames.add("libGLES_CL"); @@ -110,26 +122,16 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { } glesLibraries.add(lib); - if (GLProfile.isGLES2()) { + if (GLProfile.usesNativeGLES2()) { NativeLibLoader.loadES2(); - } else if (GLProfile.isGLES1()) { + } else if (GLProfile.usesNativeGLES1()) { NativeLibLoader.loadES1(); } } - public AbstractGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities, - GLCapabilitiesChooser chooser, - AbstractGraphicsDevice device) { - return null; - } - - public GLDrawable createGLDrawable(NativeWindow target, - GLCapabilities capabilities, - GLCapabilitiesChooser chooser) { - target = NativeWindowFactory.getNativeWindow(target); - return new EGLDrawable(this, target, - capabilities, - chooser); + public GLDrawable createGLDrawable(NativeWindow target) { + target = NativeWindowFactory.getNativeWindow(target, null); + return new EGLDrawable(this, target); } public GLDrawableImpl createOffscreenDrawable(GLCapabilities capabilities, @@ -152,7 +154,8 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { } public GLContext createExternalGLContext() { - return new EGLExternalContext(); + AbstractGraphicsScreen absScreen = DefaultGraphicsScreen.createScreenDevice(0); + return new EGLExternalContext(absScreen); } public boolean canCreateExternalGLDrawable() { diff --git a/src/jogl/classes/com/sun/opengl/impl/egl/EGLExternalContext.java b/src/jogl/classes/com/sun/opengl/impl/egl/EGLExternalContext.java index 6466c767d..49c6afaef 100755 --- a/src/jogl/classes/com/sun/opengl/impl/egl/EGLExternalContext.java +++ b/src/jogl/classes/com/sun/opengl/impl/egl/EGLExternalContext.java @@ -37,13 +37,14 @@ package com.sun.opengl.impl.egl; import javax.media.opengl.*; import com.sun.opengl.impl.*; +import javax.media.nativewindow.*; public class EGLExternalContext extends EGLContext { private boolean firstMakeCurrent = true; private boolean created = true; private GLContext lastContext; - public EGLExternalContext() { + public EGLExternalContext(AbstractGraphicsScreen screen) { super(null, null); GLContextShareSet.contextCreated(this); resetGLFunctionAvailability(); diff --git a/src/jogl/classes/com/sun/opengl/impl/egl/EGLConfig.java b/src/jogl/classes/com/sun/opengl/impl/egl/EGLGraphicsConfiguration.java index 0f60dd6b4..2b50b68a3 100644 --- a/src/jogl/classes/com/sun/opengl/impl/egl/EGLConfig.java +++ b/src/jogl/classes/com/sun/opengl/impl/egl/EGLGraphicsConfiguration.java @@ -41,7 +41,7 @@ import javax.media.opengl.*; import com.sun.opengl.impl.*; import com.sun.gluegen.runtime.NativeLibrary; -public class EGLConfig implements AbstractGraphicsConfiguration { +public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable { public _EGLConfig getNativeConfig() { return _config; @@ -51,23 +51,25 @@ public class EGLConfig implements AbstractGraphicsConfiguration { return configID; } - public GLCapabilities getCapabilities() { - return capabilities; + public EGLGraphicsConfiguration(AbstractGraphicsScreen screen, GLCapabilities caps, _EGLConfig cfg, int cfgID) { + super(screen, caps); + _config = cfg; + configID = cfgID; } - public int[] getAttributeList() { - return glCapabilities2AttribList(capabilities); + public Object clone() { + return super.clone(); } - public EGLConfig(long display, int configID) { + public static _EGLConfig EGLConfigId2EGLConfig(long display, int configID) { int[] attrs = new int[] { EGL.EGL_RENDERABLE_TYPE, -1, EGL.EGL_CONFIG_ID, configID, EGL.EGL_NONE }; - if (GLProfile.isGLES2()) { + if (GLProfile.usesNativeGLES2()) { attrs[1] = EGL.EGL_OPENGL_ES2_BIT; - } else if (GLProfile.isGLES1()) { + } else if (GLProfile.usesNativeGLES1()) { attrs[1] = EGL.EGL_OPENGL_ES_BIT; } else { throw new GLException("Error creating EGL drawable - invalid GLProfile"); @@ -78,66 +80,41 @@ public class EGLConfig implements AbstractGraphicsConfiguration { attrs, 0, configs, 1, numConfigs, 0)) { - throw new GLException("Graphics configuration selection (eglChooseConfig) failed"); + return null; } if (numConfigs[0] == 0) { - throw new GLException("No valid graphics configuration selected from eglChooseConfig"); + return null; } - capabilities = new GLCapabilities(); - setup(display, configID, configs[0]); + return configs[0]; } - public EGLConfig(long display, GLCapabilities caps) { - int[] attrs = glCapabilities2AttribList(caps); - _EGLConfig[] configs = new _EGLConfig[1]; - int[] numConfigs = new int[1]; - if (!EGL.eglChooseConfig(display, - attrs, 0, - configs, 1, - numConfigs, 0)) { - throw new GLException("Graphics configuration selection (eglChooseConfig) failed"); - } - if (numConfigs[0] == 0) { - throw new GLException("No valid graphics configuration selected from eglChooseConfig"); - } - capabilities = (GLCapabilities)caps.clone(); - setup(display, -1, configs[0]); - } - - private void setup(long display, int setConfigID, _EGLConfig _config) { - this._config = _config; + public static GLCapabilities EGLConfig2Capabilities(long display, _EGLConfig _config) { + GLCapabilities caps = new GLCapabilities(); int[] val = new int[1]; - // get the configID - if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_CONFIG_ID, val, 0)) { - configID = val[0]; - if( setConfigID>=0 && setConfigID!=this.configID ) { - throw new GLException("EGL ConfigID mismatch, ask "+setConfigID+", got "+configID); - } - } else { - throw new GLException("EGL couldn't retrieve ConfigID"); - } + // Read the actual configuration into the choosen caps if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_RED_SIZE, val, 0)) { - capabilities.setRedBits(val[0]); + caps.setRedBits(val[0]); } if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_GREEN_SIZE, val, 0)) { - capabilities.setGreenBits(val[0]); + caps.setGreenBits(val[0]); } if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_BLUE_SIZE, val, 0)) { - capabilities.setBlueBits(val[0]); + caps.setBlueBits(val[0]); } if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_ALPHA_SIZE, val, 0)) { - capabilities.setAlphaBits(val[0]); + caps.setAlphaBits(val[0]); } if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_STENCIL_SIZE, val, 0)) { - capabilities.setStencilBits(val[0]); + caps.setStencilBits(val[0]); } if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_DEPTH_SIZE, val, 0)) { - capabilities.setDepthBits(val[0]); + caps.setDepthBits(val[0]); } + return caps; } - public static int[] glCapabilities2AttribList(GLCapabilities caps) { + public static int[] GLCapabilities2AttribList(GLCapabilities caps) { int[] attrs = new int[] { EGL.EGL_RENDERABLE_TYPE, -1, // FIXME: does this need to be configurable? @@ -150,23 +127,23 @@ public class EGLConfig implements AbstractGraphicsConfiguration { EGL.EGL_DEPTH_SIZE, caps.getDepthBits(), EGL.EGL_NONE }; - if (GLProfile.isGLES2()) { - attrs[1] = EGL.EGL_OPENGL_ES2_BIT; - } else if (GLProfile.isGLES1()) { + + if(GLProfile.usesNativeGLES1()) { attrs[1] = EGL.EGL_OPENGL_ES_BIT; + } + else if(GLProfile.usesNativeGLES2()) { + attrs[1] = EGL.EGL_OPENGL_ES2_BIT; } else { - throw new GLException("Error creating EGL drawable - invalid GLProfile"); + attrs[1] = EGL.EGL_OPENGL_BIT; } return attrs; } public String toString() { - return "EGLConfig[ id "+configID+ - ", "+capabilities+"]"; + return getClass().toString()+"["+getScreen()+", eglConfigID "+configID+ ", "+getCapabilities()+"]"; } private _EGLConfig _config; private int configID; - private GLCapabilities capabilities; } diff --git a/src/jogl/classes/com/sun/opengl/impl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/sun/opengl/impl/egl/EGLGraphicsConfigurationFactory.java new file mode 100644 index 000000000..da12cead6 --- /dev/null +++ b/src/jogl/classes/com/sun/opengl/impl/egl/EGLGraphicsConfigurationFactory.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution 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. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package com.sun.opengl.impl.egl; + +import javax.media.nativewindow.*; +import javax.media.nativewindow.egl.*; +import com.sun.nativewindow.impl.*; + +import javax.media.opengl.*; +import com.sun.opengl.impl.*; + +/** Subclass of GraphicsConfigurationFactory used when non-AWT tookits + are used on X11 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 EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory { + // Keep this under the same debug flag as the drawable factory for convenience + protected static final boolean DEBUG = com.sun.opengl.impl.Debug.debug("EGLDrawableFactory"); + + public EGLGraphicsConfigurationFactory() { + // become the selector for KD/EGL .. + GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.egl.EGLGraphicsDevice.class, this); + } + + public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, + CapabilitiesChooser chooser, + AbstractGraphicsScreen absScreen) { + if (absScreen == null) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only AbstractGraphicsDevice objects"); + } + + if (capabilities != null && + !(capabilities instanceof GLCapabilities)) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects"); + } + + if (chooser != null && + !(chooser instanceof GLCapabilitiesChooser)) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); + } + + return chooseGraphicsConfigurationStatic((GLCapabilities) capabilities, + (GLCapabilitiesChooser) chooser, + absScreen); + } + + public static EGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + AbstractGraphicsScreen absScreen) { + if (capabilities == null) { + capabilities = new GLCapabilities(); + } + + if(null==absScreen) { + throw new GLException("Null AbstractGraphicsScreen"); + } + AbstractGraphicsDevice absDevice = absScreen.getDevice(); + + if(null==absDevice || !(absDevice instanceof EGLGraphicsDevice)) { + throw new GLException("GraphicsDevice must be a valid EGLGraphicsDevice"); + } + long eglDisplay = absDevice.getHandle(); + + if (eglDisplay == EGL.EGL_NO_DISPLAY) { + throw new GLException("Invalid EGL display: "+absDevice); + } + + int[] attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities); + _EGLConfig[] configs = new _EGLConfig[1]; + int[] numConfigs = new int[1]; + if (!EGL.eglChooseConfig(eglDisplay, + attrs, 0, + configs, 1, + numConfigs, 0)) { + throw new GLException("Graphics configuration selection (eglChooseConfig) failed"); + } + if (numConfigs[0] == 0) { + throw new GLException("No valid graphics configuration selected from eglChooseConfig"); + } + + int[] val = new int[1]; + // get the configID + if(!EGL.eglGetConfigAttrib(eglDisplay, configs[0], EGL.EGL_CONFIG_ID, val, 0)) { + throw new GLException("EGL couldn't retrieve ConfigID"); + } + + return new EGLGraphicsConfiguration(absScreen, + EGLGraphicsConfiguration.EGLConfig2Capabilities(eglDisplay, configs[0]), configs[0], val[0]); + } +} + diff --git a/src/jogl/classes/com/sun/opengl/impl/glu/GLUquadricImpl.java b/src/jogl/classes/com/sun/opengl/impl/glu/GLUquadricImpl.java index bb1decf42..129b24529 100644 --- a/src/jogl/classes/com/sun/opengl/impl/glu/GLUquadricImpl.java +++ b/src/jogl/classes/com/sun/opengl/impl/glu/GLUquadricImpl.java @@ -169,7 +169,7 @@ public class GLUquadricImpl implements GLUquadric { } public void enableImmModeSink(boolean val) { - if(!GLProfile.isGLES()) { + if(GLProfile.isGL2()) { immModeSinkEnabled=val; } else { immModeSinkEnabled=true; diff --git a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLContext.java index c14e0c83e..c23ac38af 100644 --- a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLContext.java @@ -42,6 +42,7 @@ package com.sun.opengl.impl.macosx.cgl; import java.nio.*; import java.util.*; import javax.media.opengl.*; +import javax.media.nativewindow.*; import com.sun.opengl.impl.*; import com.sun.gluegen.runtime.ProcAddressTable; @@ -109,8 +110,10 @@ public abstract class MacOSXCGLContext extends GLContextImpl throw new GLException("GLContextShareSet returned an invalid OpenGL context"); } } + MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilities capabilities = (GLCapabilities)config.getCapabilities(); + // FIXME: Shall being moved to MacOSXCGLGraphicsConfiguration ! int[] viewNotReady = new int[1]; - GLCapabilities capabilities = drawable.getRequestedGLCapabilities(); int[] iattribs = new int[128]; int[] ivalues = new int[128]; int idx = 0; @@ -166,9 +169,10 @@ public abstract class MacOSXCGLContext extends GLContextImpl // On this platform the pixel format is associated with the // context and not the drawable. However it's a reasonable // approximation to just store the chosen pixel format up in the - // drawable since the public API doesn't provide for a different - // GLCapabilities per context. - if (drawable.getChosenGLCapabilities() == null) { + // NativeWindow's AbstractGraphicsConfiguration, + // since the public API doesn't provide for a different GLCapabilities per context. + // Note: These restrictions of the platform's API might be considered as a bug anyways. + if (!config.getIsUpdated()) { // Figure out what attributes we really got GLCapabilities caps = new GLCapabilities(); CGL.queryPixelFormat(pixelFormat, iattribs, 0, idx, ivalues, 0); @@ -234,7 +238,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl } } - drawable.setChosenGLCapabilities(caps); + config.update(caps); } diff --git a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java index 7dc94b74d..472c5f2bc 100644 --- a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java @@ -46,8 +46,6 @@ import com.sun.opengl.impl.*; public abstract class MacOSXCGLDrawable extends GLDrawableImpl { protected static final boolean DEBUG = Debug.debug("MacOSXCGLDrawable"); - protected GLCapabilitiesChooser chooser; - // The Java2D/OpenGL pipeline on OS X uses low-level CGLContextObjs // to represent the contexts for e.g. the Java2D back buffer. When // the Java2D/JOGL bridge is active, this means that if we want to @@ -81,21 +79,10 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl { public static final int NSOPENGL_MODE = 1; public static final int CGL_MODE = 2; - public MacOSXCGLDrawable(GLDrawableFactory factory, NativeWindow comp, boolean realized, - GLCapabilities requestedCapabilities, GLCapabilitiesChooser chooser) { - super(factory, comp, requestedCapabilities, realized); - this.chooser = chooser; + public MacOSXCGLDrawable(GLDrawableFactory factory, NativeWindow comp, boolean realized) { + super(factory, comp, realized); } - // These are public to allow access from a couple of context implementations - public void setChosenGLCapabilities(GLCapabilities caps) { - super.setChosenGLCapabilities(caps); - } - - public GLCapabilities getRequestedGLCapabilities() { - return super.getRequestedGLCapabilities(); - } - protected static String getThreadName() { return Thread.currentThread().getName(); } diff --git a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java index 2868a0899..36d9280e4 100644 --- a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java +++ b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java @@ -49,29 +49,26 @@ import com.sun.opengl.impl.*; public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { public MacOSXCGLDrawableFactory() { super(); + + // Register our GraphicsConfigurationFactory implementations + // The act of constructing them causes them to be registered + new MacOSXCGLGraphicsConfigurationFactory(); } - public GLDrawable createGLDrawable(NativeWindow target, - GLCapabilities capabilities, - GLCapabilitiesChooser chooser) { + public GLDrawable createGLDrawable(NativeWindow target) { if (target == null) { throw new IllegalArgumentException("Null target"); } - target = NativeWindowFactory.getNativeWindow(target); - if (capabilities == null) { - capabilities = new GLCapabilities(); - } - if (chooser == null) { - chooser = new DefaultGLCapabilitiesChooser(); - } - return new MacOSXOnscreenCGLDrawable(this, target, capabilities, chooser); + target = NativeWindowFactory.getNativeWindow(target, null); + return new MacOSXOnscreenCGLDrawable(this, target); } public GLDrawableImpl createOffscreenDrawable(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) { - return new MacOSXOffscreenCGLDrawable(this, capabilities, width, height); + AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(); + return new MacOSXOffscreenCGLDrawable(this, aScreen, capabilities, chooser, width, height); } public boolean canCreateGLPbuffer() { @@ -87,7 +84,8 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { final GLDrawableFactory factory = this; Runnable r = new Runnable() { public void run() { - MacOSXPbufferCGLDrawable pbufferDrawable = new MacOSXPbufferCGLDrawable(factory, capabilities, + AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(); + MacOSXPbufferCGLDrawable pbufferDrawable = new MacOSXPbufferCGLDrawable(factory, aScreen, capabilities, chooser, initialWidth, initialHeight); GLPbufferImpl pbuffer = new GLPbufferImpl(pbufferDrawable, shareWith); @@ -99,7 +97,8 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { } public GLContext createExternalGLContext() { - return new MacOSXExternalCGLContext(); + AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(); + return new MacOSXExternalCGLContext(aScreen); } public boolean canCreateExternalGLDrawable() { diff --git a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java new file mode 100644 index 000000000..0ada5668f --- /dev/null +++ b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution 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. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.sun.opengl.impl.macosx.cgl; + +import java.util.*; +import javax.media.nativewindow.*; +import javax.media.opengl.*; +import com.sun.opengl.impl.*; +import com.sun.gluegen.runtime.NativeLibrary; + +public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable { + private boolean isUpdated = false; + + public MacOSXCGLGraphicsConfiguration(AbstractGraphicsScreen screen, GLCapabilities caps) { + super(screen, caps); + } + + public Object clone() { + return super.clone(); + } + + protected void update(GLCapabilities caps) { + setCapabilities(caps); + isUpdated=true; + } + + public boolean getIsUpdated() { + return isUpdated; + } +} + diff --git a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java new file mode 100644 index 000000000..71b9bd38e --- /dev/null +++ b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution 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. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package com.sun.opengl.impl.macosx.cgl; + +import javax.media.nativewindow.*; +import com.sun.nativewindow.impl.*; + +import javax.media.opengl.*; +import com.sun.opengl.impl.*; + +/** Subclass of GraphicsConfigurationFactory used when non-AWT tookits + are used on OSX 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 MacOSXCGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory { + + public MacOSXCGLGraphicsConfigurationFactory() { + Class awtDeviceClass = NWReflection.getClass("javax.media.nativewindow.awt.AWTGraphicsDevice"); + if(null!=awtDeviceClass) { + GraphicsConfigurationFactory.registerFactory(awtDeviceClass, this); + } + GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.AbstractGraphicsDevice.class, this); + } + + public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, + CapabilitiesChooser chooser, + AbstractGraphicsScreen absScreen) { + return chooseGraphicsConfigurationStatic(capabilities, chooser, absScreen, false); + } + + protected static MacOSXCGLGraphicsConfiguration createDefaultGraphicsConfiguration(AbstractGraphicsScreen absScreen, boolean usePBuffer) { + if (absScreen == null) { + throw new IllegalArgumentException("AbstractGraphicsScreen is null"); + } + + return new MacOSXCGLGraphicsConfiguration(absScreen, new GLCapabilities()); + } + + protected static MacOSXCGLGraphicsConfiguration chooseGraphicsConfigurationStatic(Capabilities capabilities, + CapabilitiesChooser chooser, + AbstractGraphicsScreen absScreen, boolean usePBuffer) { + if (absScreen == null) { + throw new IllegalArgumentException("AbstractGraphicsScreen is null"); + } + + if (capabilities != null && + !(capabilities instanceof GLCapabilities)) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects"); + } + + if (chooser != null && + !(chooser instanceof GLCapabilitiesChooser)) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); + } + + if (capabilities == null) { + capabilities = new GLCapabilities(); + } + + return new MacOSXCGLGraphicsConfiguration(absScreen, (GLCapabilities)capabilities); + } +} + diff --git a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java index b19e221f0..4bef8f74b 100644 --- a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java +++ b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java @@ -40,6 +40,7 @@ package com.sun.opengl.impl.macosx.cgl; import javax.media.opengl.*; +import javax.media.nativewindow.*; import com.sun.opengl.impl.*; public class MacOSXExternalCGLContext extends MacOSXCGLContext { @@ -47,7 +48,7 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext { private boolean created = true; private GLContext lastContext; - public MacOSXExternalCGLContext() { + public MacOSXExternalCGLContext(AbstractGraphicsScreen absScreen) { super(null, null); // FIXME: we don't have a "current context" primitive implemented diff --git a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOffscreenCGLDrawable.java b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOffscreenCGLDrawable.java index a825e1c1e..3ff1c0a91 100644 --- a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOffscreenCGLDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOffscreenCGLDrawable.java @@ -40,15 +40,18 @@ package com.sun.opengl.impl.macosx.cgl; import javax.media.opengl.*; +import javax.media.nativewindow.*; import com.sun.opengl.impl.*; public class MacOSXOffscreenCGLDrawable extends MacOSXPbufferCGLDrawable { public MacOSXOffscreenCGLDrawable(GLDrawableFactory factory, + AbstractGraphicsScreen absScreen, GLCapabilities capabilities, + GLCapabilitiesChooser chooser, int width, int height) { - super(factory, capabilities, width, height); + super(factory, absScreen, capabilities, chooser, width, height); } public GLContext createContext(GLContext shareWith) { diff --git a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOnscreenCGLDrawable.java b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOnscreenCGLDrawable.java index 12fc7c3ad..98687b5ef 100644 --- a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOnscreenCGLDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOnscreenCGLDrawable.java @@ -51,10 +51,8 @@ public class MacOSXOnscreenCGLDrawable extends MacOSXCGLDrawable { private List/*<WeakReference<GLContext>>*/ createdContexts = new ArrayList(); - protected MacOSXOnscreenCGLDrawable(GLDrawableFactory factory, NativeWindow component, - GLCapabilities capabilities, - GLCapabilitiesChooser chooser) { - super(factory, component, false, capabilities, chooser); + protected MacOSXOnscreenCGLDrawable(GLDrawableFactory factory, NativeWindow component) { + super(factory, component, false); } public GLContext createContext(GLContext shareWith) { diff --git a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java index cdcd66d10..13ea2c102 100644 --- a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java +++ b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java @@ -4,6 +4,7 @@ import java.security.*; import java.util.*; import javax.media.opengl.*; +import javax.media.nativewindow.*; import com.sun.opengl.impl.*; public class MacOSXPbufferCGLContext extends MacOSXCGLContext { @@ -79,8 +80,10 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext { resetGLFunctionAvailability(); // Initialize render-to-texture support if requested + DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilities capabilities = (GLCapabilities)config.getCapabilities(); GL gl = getGL(); - boolean rect = gl.isGL2() && drawable.getRequestedGLCapabilities().getPbufferRenderToTextureRectangle(); + boolean rect = gl.isGL2() && capabilities.getPbufferRenderToTextureRectangle(); if (rect) { if (!gl.isExtensionAvailable("GL_EXT_texture_rectangle")) { System.err.println("MacOSXPbufferCGLContext: WARNING: GL_EXT_texture_rectangle extension not " + @@ -135,7 +138,8 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext { } protected boolean create() { - GLCapabilities capabilities = drawable.getRequestedGLCapabilities(); + DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilities capabilities = (GLCapabilities)config.getCapabilities(); if (capabilities.getPbufferFloatingPointBuffers() && !isTigerOrLater) { throw new GLException("Floating-point pbuffers supported only on OS X 10.4 or later"); @@ -210,7 +214,8 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext { // NSOpenGLContext-based implementation class NSOpenGLImpl implements Impl { public long create() { - GLCapabilities capabilities = drawable.getRequestedGLCapabilities(); + DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilities capabilities = (GLCapabilities)config.getCapabilities(); if (capabilities.getPbufferFloatingPointBuffers() && !isTigerOrLater) { throw new GLException("Floating-point pbuffers supported only on OS X 10.4 or later"); @@ -262,10 +267,12 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext { } // Set up pixel format attributes + // FIXME: shall go into MacOSXCGLGraphicsConfiguration int[] attrs = new int[256]; int i = 0; attrs[i++] = CGL.kCGLPFAPBuffer; - GLCapabilities capabilities = drawable.getRequestedGLCapabilities(); + DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilities capabilities = (GLCapabilities)config.getCapabilities(); if (capabilities.getPbufferFloatingPointBuffers()) attrs[i++] = CGL.kCGLPFAColorFloat; if (capabilities.getDoubleBuffered()) diff --git a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java index 5c41ddbd4..7176aaaf1 100644 --- a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java @@ -40,6 +40,7 @@ package com.sun.opengl.impl.macosx.cgl; import javax.media.opengl.*; +import javax.media.nativewindow.*; import com.sun.opengl.impl.*; import com.sun.nativewindow.impl.NullWindow; @@ -56,8 +57,12 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { // semantic is that contains an NSView protected long pBuffer; - public MacOSXPbufferCGLDrawable(GLDrawableFactory factory, GLCapabilities capabilities, int width, int height) { - super(factory, new NullWindow(), true, capabilities, null); + public MacOSXPbufferCGLDrawable(GLDrawableFactory factory, + AbstractGraphicsScreen absScreen, + GLCapabilities caps, + GLCapabilitiesChooser chooser, + int width, int height) { + super(factory, new NullWindow(MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(caps, chooser, absScreen, true)), true); NullWindow nw = (NullWindow) getNativeWindow(); nw.setSize(width, height); initOpenGLImpl(); @@ -88,8 +93,9 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { private void createPbuffer() { NullWindow nw = (NullWindow) getNativeWindow(); + DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) nw.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilities capabilities = (GLCapabilities)config.getCapabilities(); int renderTarget; - GLCapabilities capabilities = getRequestedGLCapabilities(); if (GLProfile.isGL2() && capabilities.getPbufferRenderToTextureRectangle()) { renderTarget = GL2.GL_TEXTURE_RECTANGLE_EXT; } else { diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java index 07966f0f2..a22a8bfec 100644 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java @@ -47,7 +47,7 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable { private long hwnd, hdc; public WindowsDummyWGLDrawable(GLDrawableFactory factory) { - super(factory, new NullWindow(), true, new GLCapabilities(), null); + super(factory, new NullWindow(WindowsWGLGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(null, false)), true); // All entries to CreateDummyWindow must synchronize on one object // to avoid accidentally registering the dummy window class twice synchronized (WindowsDummyWGLDrawable.class) { @@ -59,7 +59,7 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable { // Choose a (hopefully hardware-accelerated) OpenGL pixel format for this device context GLCapabilities caps = new GLCapabilities(); caps.setDepthBits(16); - PIXELFORMATDESCRIPTOR pfd = glCapabilities2PFD(caps, true); + PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps, true); int pixelFormat = WGL.ChoosePixelFormat(hdc, pfd); if ((pixelFormat == 0) || (!WGL.SetPixelFormat(hdc, pixelFormat, pfd))) { diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLContext.java index 493b38061..ca14842ae 100755 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLContext.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLContext.java @@ -42,6 +42,7 @@ package com.sun.opengl.impl.windows.wgl; import java.nio.*; import java.util.*; import javax.media.opengl.*; +import javax.media.nativewindow.*; import com.sun.opengl.impl.*; public class WindowsExternalWGLContext extends WindowsWGLContext { @@ -49,7 +50,7 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { private boolean created = true; private GLContext lastContext; - public WindowsExternalWGLContext() { + public WindowsExternalWGLContext(AbstractGraphicsScreen absScreen) { // FIXME: figure out how to hook back in the Java 2D / JOGL bridge super(null, null); hglrc = WGL.wglGetCurrentContext(); diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java index 78b06307a..164216c2d 100755 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java @@ -47,12 +47,12 @@ import com.sun.nativewindow.impl.NullWindow; public class WindowsExternalWGLDrawable extends WindowsWGLDrawable { public WindowsExternalWGLDrawable(GLDrawableFactory factory, NativeWindow component) { - super(factory, component, true, new GLCapabilities(), null); + super(factory, component, true); } - public static WindowsExternalWGLDrawable create(GLDrawableFactory factory) { + public static WindowsExternalWGLDrawable create(GLDrawableFactory factory, AbstractGraphicsScreen absScreen) { long hdc = WGL.wglGetCurrentDC(); - NullWindow nw = new NullWindow(); + NullWindow nw = new NullWindow(WindowsWGLGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(absScreen, false)); nw.setSurfaceHandle(hdc); if (nw.getSurfaceHandle() == 0) { throw new GLException("Error: attempted to make an external GLDrawable without a drawable/context current"); diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java index 90327ee08..901d26e8b 100644 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java @@ -40,6 +40,7 @@ package com.sun.opengl.impl.windows.wgl; import javax.media.opengl.*; +import javax.media.nativewindow.*; import com.sun.opengl.impl.*; import com.sun.nativewindow.impl.NullWindow; @@ -48,11 +49,12 @@ public class WindowsOffscreenWGLDrawable extends WindowsWGLDrawable { private long hbitmap; public WindowsOffscreenWGLDrawable(GLDrawableFactory factory, + AbstractGraphicsScreen absScreen, GLCapabilities requestedCapabilities, GLCapabilitiesChooser chooser, int width, int height) { - super(factory, new NullWindow(), true, requestedCapabilities, chooser); + super(factory, new NullWindow(WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(requestedCapabilities, chooser, absScreen, true)), true); ((NullWindow) getNativeWindow()).setSize(width, height); create(); } @@ -63,7 +65,8 @@ public class WindowsOffscreenWGLDrawable extends WindowsWGLDrawable { private void create() { NullWindow nw = (NullWindow) getNativeWindow(); - GLCapabilities capabilities = getRequestedGLCapabilities(); + WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)nw.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilities capabilities = (GLCapabilities)config.getCapabilities(); int width = getWidth(); int height = getHeight(); BITMAPINFO info = BITMAPINFO.create(); @@ -108,7 +111,7 @@ public class WindowsOffscreenWGLDrawable extends WindowsWGLDrawable { throw new GLException("Error selecting bitmap into new device context"); } - choosePixelFormat(false); + config.update(getFactory(), nw, true); } public void destroy() { @@ -121,7 +124,6 @@ public class WindowsOffscreenWGLDrawable extends WindowsWGLDrawable { origbitmap = 0; hbitmap = 0; nw.setSurfaceHandle(0); - setChosenGLCapabilities(null); } } } diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java index 368462d6b..32e786a2b 100644 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java @@ -53,10 +53,8 @@ public class WindowsOnscreenWGLDrawable extends WindowsWGLDrawable { private int profilingSwapBuffersTicks; private long profilingSwapBuffersTime; - protected WindowsOnscreenWGLDrawable(GLDrawableFactory factory, NativeWindow component, - GLCapabilities capabilities, - GLCapabilitiesChooser chooser) { - super(factory, component, false, capabilities, chooser); + protected WindowsOnscreenWGLDrawable(GLDrawableFactory factory, NativeWindow component) { + super(factory, component, false); } public GLContext createContext(GLContext shareWith) { diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java index 5c7e7dc64..e98b570ed 100644 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java @@ -96,7 +96,8 @@ public class WindowsPbufferWGLContext extends WindowsWGLContext { System.err.println("WindowsPbufferWGLContext: super.makeCurrentImpl() = " + res); } if (res == CONTEXT_CURRENT_NEW) { - GLCapabilities capabilities = drawable.getRequestedGLCapabilities(); + WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilities capabilities = (GLCapabilities)config.getCapabilities(); // Initialize render-to-texture support if requested GL gl = getGL(); diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java index eccc21a15..247a00fa3 100644 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java @@ -40,6 +40,7 @@ package com.sun.opengl.impl.windows.wgl; import javax.media.opengl.*; +import javax.media.nativewindow.*; import com.sun.opengl.impl.*; import com.sun.nativewindow.impl.NullWindow; @@ -52,12 +53,15 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { private int floatMode; public WindowsPbufferWGLDrawable(GLDrawableFactory factory, + AbstractGraphicsScreen absScreen, GLCapabilities requestedCapabilities, + final GLCapabilitiesChooser chooser, int width, int height, WindowsWGLDrawable dummyDrawable, WGLExt wglExt) { - super(factory, new NullWindow(), true, requestedCapabilities, null); + super(factory, new NullWindow(WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic( + requestedCapabilities, chooser, absScreen, true) ), true); if (width <= 0 || height <= 0) { throw new GLException("Width and height of pbuffer must be positive (were (" + width + ", " + height + "))"); @@ -66,10 +70,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { nw.setSize(width, height); if (DEBUG) { - System.out.println("Pbuffer caps on init: " + requestedCapabilities + - (requestedCapabilities.getPbufferRenderToTexture() ? " [rtt]" : "") + - (requestedCapabilities.getPbufferRenderToTextureRectangle() ? " [rect]" : "") + - (requestedCapabilities.getPbufferFloatingPointBuffers() ? " [float]" : "")); + System.out.println("Pbuffer caps: " + requestedCapabilities); } createPbuffer(dummyDrawable.getNativeWindow().getSurfaceHandle(), wglExt); @@ -95,7 +96,6 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { throw new GLException("Error destroying pbuffer: error code " + WGL.GetLastError()); } buffer = 0; - setChosenGLCapabilities(null); } } @@ -124,33 +124,26 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { */ } - // This is public to allow access from PbufferContext - public GLCapabilities getRequestedGLCapabilities() { - return super.getRequestedGLCapabilities(); - } - private void createPbuffer(long parentHdc, WGLExt wglExt) { - int[] iattributes = new int [2*MAX_ATTRIBS]; + int[] iattributes = new int [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS]; float[] fattributes = new float[1]; int[] floatModeTmp = new int[1]; int niattribs = 0; int width, height; - GLCapabilities capabilities = getRequestedGLCapabilities(); + WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilities capabilities = (GLCapabilities)config.getCapabilities(); if (DEBUG) { System.out.println("Pbuffer parentHdc = " + toHexString(parentHdc)); - System.out.println("Pbuffer caps: " + capabilities + - (capabilities.getPbufferRenderToTexture() ? " [rtt]" : "") + - (capabilities.getPbufferRenderToTextureRectangle() ? " [rect]" : "") + - (capabilities.getPbufferFloatingPointBuffers() ? " [float]" : "")); + System.out.println("Pbuffer caps: " + capabilities); } - if (!glCapabilities2iattributes(capabilities, + if(!WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities, iattributes, wglExt, true, - floatModeTmp)) { + floatModeTmp)){ throw new GLException("Pbuffer-related extensions not supported"); } @@ -164,15 +157,15 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { ati = (floatMode == GLPbuffer.ATI_FLOAT); } - int[] pformats = new int[MAX_PFORMATS]; + int[] pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS]; int nformats; int[] nformatsTmp = new int[1]; if (!wglExt.wglChoosePixelFormatARB(parentHdc, - iattributes, 0, - fattributes, 0, - MAX_PFORMATS, - pformats, 0, - nformatsTmp, 0)) { + iattributes, 0, + fattributes, 0, + WindowsWGLGraphicsConfiguration.MAX_PFORMATS, + pformats, 0, + nformatsTmp, 0)) { throw new GLException("pbuffer creation error: wglChoosePixelFormat() failed"); } nformats = nformatsTmp[0]; @@ -306,9 +299,20 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { 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]; - // FIXME: usually prefer to throw exceptions, but failure here is not critical if (wglExt.wglGetPixelFormatAttribivARB(parentHdc, pformats[whichFormat], 0, niattribs, iattributes, 0, ivalues, 0)) { - setChosenGLCapabilities(iattributes2GLCapabilities(iattributes, niattribs, ivalues, false)); + GLCapabilities newCaps = WindowsWGLGraphicsConfiguration.AttribList2GLCapabilities(iattributes, niattribs, ivalues, false); + PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); + if (WGL.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) { + throw new GLException("Unable to describe pixel format " + pformats[whichFormat]); + } + config.setCapsPFD(newCaps, pfd, pformats[whichFormat]); + } else { + PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); + if (WGL.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) { + throw new GLException("Unable to describe pixel format " + pformats[whichFormat]); + } + GLCapabilities newCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(pfd); + config.setCapsPFD(newCaps, pfd, pformats[whichFormat]); } } diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLContext.java index a02634a26..fc24979d9 100644 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLContext.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLContext.java @@ -121,10 +121,6 @@ public class WindowsWGLContext extends GLContextImpl { if (drawable.getNativeWindow().getSurfaceHandle() == 0) { throw new GLException("Internal error: attempted to create OpenGL context without an associated drawable"); } - hglrc = WGL.wglCreateContext(drawable.getNativeWindow().getSurfaceHandle()); - if (hglrc == 0) { - throw new GLException("Unable to create OpenGL context for device context " + toHexString(drawable.getNativeWindow().getSurfaceHandle())); - } if (DEBUG) { System.err.println(getThreadName() + ": !!! Created OpenGL context " + toHexString(hglrc) + " for " + this + ", device context " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) + ", not yet sharing"); } @@ -136,11 +132,95 @@ public class WindowsWGLContext extends GLContextImpl { if (hglrc2 == 0) { throw new GLException("GLContextShareSet returned an invalid OpenGL context"); } - if (!WGL.wglShareLists(hglrc2, hglrc)) { - throw new GLException("wglShareLists(" + toHexString(hglrc2) + - ", " + toHexString(hglrc) + ") failed: error code " + - WGL.GetLastError()); - } + } + + // To use WGL_ARB_create_context, we have to make a temp context current, + // so we are able to use GetProcAddress + long temp_hglrc = WGL.wglCreateContext(drawable.getNativeWindow().getSurfaceHandle()); + if (temp_hglrc == 0) { + throw new GLException("Unable to create temp OpenGL context for device context " + toHexString(drawable.getNativeWindow().getSurfaceHandle())); + } else { + if (!WGL.wglMakeCurrent(drawable.getNativeWindow().getSurfaceHandle(), temp_hglrc)) { + throw new GLException("Error making temp context current: " + WGL.GetLastError()); + } + resetGLFunctionAvailability(); + + if( !isFunctionAvailable("wglCreateContextAttribsARB") || + !isExtensionAvailable("WGL_ARB_create_context") ) { + if(GLProfile.isGL3()) { + if (!WGL.wglMakeCurrent(0, 0)) { + throw new GLException("Error freeing temp OpenGL context: " + WGL.GetLastError()); + } + if (!WGL.wglDeleteContext(temp_hglrc)) { + throw new GLException("Unable to delete OpenGL context"); + } + throw new GLException("Unable to create OpenGL 3.1 context (no WGL_ARB_create_context)"); + } + + // continue with temp context for GL < 3.0 + hglrc = temp_hglrc; + if(DEBUG) { + System.err.println("WindowsWGLContext.create done (old ctx < 3.0 - no WGL_ARB_create_context) 0x"+Long.toHexString(hglrc)); + } + } else { + WGLExt wglExt = getWGLExt(); + + // preset with default values + int attribs[] = { + WGLExt.WGL_CONTEXT_MAJOR_VERSION_ARB, 3, + WGLExt.WGL_CONTEXT_MINOR_VERSION_ARB, 0, + WGLExt.WGL_CONTEXT_FLAGS_ARB, 0, + 0 + }; + + if(GLProfile.isGL3()) { + attribs[1] |= 3; + attribs[3] |= 1; + attribs[5] |= WGLExt.WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB /* | WGLExt.WGL_CONTEXT_DEBUG_BIT_ARB */; + } + + hglrc = wglExt.wglCreateContextAttribsARB(drawable.getNativeWindow().getSurfaceHandle(), hglrc2, attribs, 0); + if(0==hglrc) { + if(GLProfile.isGL3()) { + if (!WGL.wglMakeCurrent(0, 0)) { + throw new GLException("Error freeing temp OpenGL context: " + WGL.GetLastError()); + } + if (!WGL.wglDeleteContext(temp_hglrc)) { + throw new GLException("Unable to delete OpenGL context"); + } + throw new GLException("Unable to create OpenGL 3.1 context (have WGL_ARB_create_context)"); + } + + // continue with temp context for GL < 3.0 + hglrc = temp_hglrc; + if(DEBUG) { + System.err.println("WindowsWGLContext.create done (old ctx < 3.0 - no 3.0) 0x"+Long.toHexString(hglrc)); + } + } else { + hglrc2 = 0; // mark as shared .. + if (!WGL.wglMakeCurrent(0, 0)) { + throw new GLException("Error freeing temp OpenGL context: " + WGL.GetLastError()); + } + if (!WGL.wglDeleteContext(temp_hglrc)) { + throw new GLException("Unable to delete temp OpenGL context"); + } + + if (!WGL.wglMakeCurrent(drawable.getNativeWindow().getSurfaceHandle(), hglrc)) { + throw new GLException("Error making new context current: " + WGL.GetLastError()); + } + resetGLFunctionAvailability(); + if(DEBUG) { + System.err.println("WindowsWGLContext.create done (new ctx >= 3.0) 0x"+Long.toHexString(hglrc)); + } + } + } + } + if(0!=hglrc2) { + if (!WGL.wglShareLists(hglrc2, hglrc)) { + throw new GLException("wglShareLists(" + toHexString(hglrc2) + + ", " + toHexString(hglrc) + ") failed: error code " + + WGL.GetLastError()); + } } GLContextShareSet.contextCreated(this); if (DEBUG) { @@ -176,7 +256,6 @@ public class WindowsWGLContext extends GLContextImpl { } if (created) { - resetGLFunctionAvailability(); return CONTEXT_CURRENT_NEW; } return CONTEXT_CURRENT; diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawable.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawable.java index fd2e158a9..1e908f703 100644 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawable.java @@ -46,21 +46,12 @@ import com.sun.opengl.impl.*; public abstract class WindowsWGLDrawable extends GLDrawableImpl { protected static final boolean DEBUG = Debug.debug("WindowsWGLDrawable"); - protected GLCapabilitiesChooser chooser; - protected boolean pixelFormatChosen; - // Workaround for problems on Intel 82855 cards private int setPixelFormatFailCount; private static final int MAX_SET_PIXEL_FORMAT_FAIL_COUNT = 5; - protected static final int MAX_PFORMATS = 256; - protected static final int MAX_ATTRIBS = 256; - - public WindowsWGLDrawable(GLDrawableFactory factory, NativeWindow comp, boolean realized, - GLCapabilities requestedCapabilities, - GLCapabilitiesChooser chooser) { - super(factory, comp, requestedCapabilities, realized); - this.chooser = chooser; + public WindowsWGLDrawable(GLDrawableFactory factory, NativeWindow comp, boolean realized) { + super(factory, comp, realized); } public int lockSurface() throws GLException { @@ -71,9 +62,11 @@ public abstract class WindowsWGLDrawable extends GLDrawableImpl { } return ret; } - if (!pixelFormatChosen) { + NativeWindow nativeWindow = getNativeWindow(); + WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)nativeWindow.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + if (!config.getIsUpdated()) { try { - choosePixelFormat(true); + config.update(getFactory(), nativeWindow, false); setPixelFormatFailCount = 0; } catch (RuntimeException e) { if (DEBUG) { @@ -100,577 +93,6 @@ public abstract class WindowsWGLDrawable extends GLDrawableImpl { return ret; } - - protected void choosePixelFormat(boolean onscreen) { - PIXELFORMATDESCRIPTOR pfd = null; - int pixelFormat = 0; - GLCapabilities chosenCaps = null; - GLCapabilities capabilities = getRequestedGLCapabilities(); - long hdc = getNativeWindow().getSurfaceHandle(); - if (onscreen) { - if ((pixelFormat = WGL.GetPixelFormat(hdc)) != 0) { - // The Java2D/OpenGL pipeline probably already set a pixel - // format for this canvas. - if (DEBUG) { - System.err.println("NOTE: pixel format already chosen (by Java2D/OpenGL pipeline?) for window: " + - WGL.GetPixelFormat(hdc)); - } - pfd = newPixelFormatDescriptor(); - if (WGL.DescribePixelFormat(hdc, pixelFormat, pfd.size(), pfd) == 0) { - // FIXME: should this just be a warning? Not really critical... - throw new GLException("Unable to describe pixel format " + pixelFormat + - " of window set by Java2D/OpenGL pipeline"); - } - setChosenGLCapabilities(pfd2GLCapabilities(pfd)); - pixelFormatChosen = true; - return; - } - - GLCapabilities[] availableCaps = null; - int numFormats = 0; - pfd = newPixelFormatDescriptor(); - // Produce a recommended pixel format selection for the GLCapabilitiesChooser. - // Use wglChoosePixelFormatARB if user requested multisampling and if we have it available - WindowsWGLDrawable dummyDrawable = null; - GLContextImpl dummyContext = null; - WGLExt dummyWGLExt = null; - if (capabilities.getSampleBuffers()) { - dummyDrawable = new WindowsDummyWGLDrawable(getFactory()); - dummyContext = (GLContextImpl) dummyDrawable.createContext(null); - if (dummyContext != null) { - dummyContext.makeCurrent(); - dummyWGLExt = (WGLExt) dummyContext.getPlatformGLExtensions(); - } - } - int recommendedPixelFormat = -1; - boolean haveWGLChoosePixelFormatARB = false; - boolean haveWGLARBMultisample = false; - boolean gotAvailableCaps = false; - if (dummyWGLExt != null) { - try { - haveWGLChoosePixelFormatARB = dummyWGLExt.isExtensionAvailable("WGL_ARB_pixel_format"); - if (haveWGLChoosePixelFormatARB) { - haveWGLARBMultisample = dummyWGLExt.isExtensionAvailable("WGL_ARB_multisample"); - - int[] iattributes = new int [2 * MAX_ATTRIBS]; - int[] iresults = new int [2 * MAX_ATTRIBS]; - float[] fattributes = new float[1]; - - if (glCapabilities2iattributes(capabilities, - iattributes, - dummyWGLExt, - false, - null)) { - int[] pformats = new int[MAX_PFORMATS]; - int[] numFormatsTmp = new int[1]; - if (dummyWGLExt.wglChoosePixelFormatARB(hdc, - iattributes, 0, - fattributes, 0, - MAX_PFORMATS, - pformats, 0, - numFormatsTmp, 0)) { - numFormats = numFormatsTmp[0]; - if (numFormats > 0) { - // Remove one-basing of pixel format (added on later) - recommendedPixelFormat = pformats[0] - 1; - if (DEBUG) { - System.err.println(getThreadName() + ": Used wglChoosePixelFormatARB to recommend pixel format " + recommendedPixelFormat); - } - } - } else { - if (DEBUG) { - System.err.println(getThreadName() + ": wglChoosePixelFormatARB failed: " + WGL.GetLastError() ); - Thread.dumpStack(); - } - } - if (DEBUG) { - if (recommendedPixelFormat < 0) { - System.err.print(getThreadName() + ": wglChoosePixelFormatARB didn't recommend a pixel format"); - if (capabilities.getSampleBuffers()) { - System.err.print(" for multisampled GLCapabilities"); - } - System.err.println(); - } - } - - // 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) - int niattribs = 0; - iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB; - if (dummyWGLExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) { - numFormats = iresults[0]; - - if (DEBUG) { - System.err.println("wglGetPixelFormatAttribivARB reported WGL_NUMBER_PIXEL_FORMATS = " + numFormats); - } - - // Should we be filtering out the pixel formats which aren't - // applicable, as we are doing here? - // We don't have enough information in the GLCapabilities to - // represent those that aren't... - iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB; - iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_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_PIXEL_TYPE_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_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; - if (haveWGLARBMultisample) { - iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB; - iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB; - } - - availableCaps = new GLCapabilities[numFormats]; - for (int i = 0; i < numFormats; i++) { - if (!dummyWGLExt.wglGetPixelFormatAttribivARB(hdc, i+1, 0, niattribs, iattributes, 0, iresults, 0)) { - throw new GLException("Error getting pixel format attributes for pixel format " + (i + 1) + " of device context"); - } - availableCaps[i] = iattributes2GLCapabilities(iattributes, niattribs, iresults, true); - } - gotAvailableCaps = true; - } else { - long lastErr = WGL.GetLastError(); - // Intel Extreme graphics fails with a zero error code - if (lastErr != 0) { - throw new GLException("Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + WGL.GetLastError()); - } - } - } - } - } finally { - dummyContext.release(); - dummyContext.destroy(); - dummyDrawable.destroy(); - } - } - - // Fallback path for older cards, in particular Intel Extreme motherboard graphics - if (!gotAvailableCaps) { - if (DEBUG) { - if (!capabilities.getSampleBuffers()) { - System.err.println(getThreadName() + ": Using ChoosePixelFormat because multisampling not requested"); - } else { - System.err.println(getThreadName() + ": Using ChoosePixelFormat because no wglChoosePixelFormatARB"); - } - } - pfd = glCapabilities2PFD(capabilities, onscreen); - // Remove one-basing of pixel format (added on later) - recommendedPixelFormat = WGL.ChoosePixelFormat(hdc, pfd) - 1; - if (DEBUG) { - System.err.println(getThreadName() + ": Recommended pixel format = " + recommendedPixelFormat); - } - - numFormats = WGL.DescribePixelFormat(hdc, 1, 0, null); - if (numFormats == 0) { - throw new GLException("Unable to enumerate pixel formats of window " + - toHexString(hdc) + " for GLCapabilitiesChooser"); - } - availableCaps = new GLCapabilities[numFormats]; - for (int i = 0; i < numFormats; i++) { - if (WGL.DescribePixelFormat(hdc, 1 + i, pfd.size(), pfd) == 0) { - throw new GLException("Error describing pixel format " + (1 + i) + " of device context"); - } - availableCaps[i] = pfd2GLCapabilities(pfd); - } - } - - // NOTE: officially, should make a copy of all of these - // GLCapabilities to avoid mutation by the end user during the - // chooseCapabilities call, but for the time being, assume they - // won't be changed - - // Supply information to chooser - try { - pixelFormat = chooser.chooseCapabilities(capabilities, availableCaps, recommendedPixelFormat); - } catch (NativeWindowException e) { - throw new GLException(e); - } - if ((pixelFormat < 0) || (pixelFormat >= numFormats)) { - throw new GLException("Invalid result " + pixelFormat + - " from GLCapabilitiesChooser (should be between 0 and " + - (numFormats - 1) + ")"); - } - if (DEBUG) { - System.err.println(getThreadName() + ": Chosen pixel format (" + pixelFormat + "):"); - System.err.println(availableCaps[pixelFormat]); - } - chosenCaps = availableCaps[pixelFormat]; - pixelFormat += 1; // one-base the index - if (WGL.DescribePixelFormat(hdc, pixelFormat, pfd.size(), pfd) == 0) { - throw new GLException("Error re-describing the chosen pixel format: " + WGL.GetLastError()); - } - } else { - // For now, use ChoosePixelFormat for offscreen surfaces until - // we figure out how to properly choose an offscreen- - // compatible pixel format - pfd = glCapabilities2PFD(capabilities, onscreen); - pixelFormat = WGL.ChoosePixelFormat(hdc, pfd); - } - if (!WGL.SetPixelFormat(hdc, pixelFormat, pfd)) { - long lastError = WGL.GetLastError(); - if (DEBUG) { - System.err.println(getThreadName() + ": SetPixelFormat failed: current context = " + WGL.wglGetCurrentContext() + - ", current DC = " + WGL.wglGetCurrentDC()); - System.err.println(getThreadName() + ": GetPixelFormat(hdc " + toHexString(hdc) + ") returns " + WGL.GetPixelFormat(hdc)); - } - throw new GLException("Unable to set pixel format " + pixelFormat + " for device context " + toHexString(hdc) + ": error code " + lastError); - } - // Reuse the previously-constructed GLCapabilities because it - // turns out that using DescribePixelFormat on some pixel formats - // (which, for example, support full-scene antialiasing) for some - // reason return that they are not OpenGL-capable - if (chosenCaps != null) { - setChosenGLCapabilities(chosenCaps); - } else { - setChosenGLCapabilities(pfd2GLCapabilities(pfd)); - } - pixelFormatChosen = true; - } - - protected static PIXELFORMATDESCRIPTOR glCapabilities2PFD(GLCapabilities caps, boolean onscreen) { - int colorDepth = (caps.getRedBits() + - caps.getGreenBits() + - caps.getBlueBits()); - if (colorDepth < 15) { - throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported"); - } - PIXELFORMATDESCRIPTOR pfd = newPixelFormatDescriptor(); - int pfdFlags = (WGL.PFD_SUPPORT_OPENGL | - WGL.PFD_GENERIC_ACCELERATED); - if (caps.getDoubleBuffered()) { - pfdFlags |= WGL.PFD_DOUBLEBUFFER; - } - if (onscreen) { - pfdFlags |= WGL.PFD_DRAW_TO_WINDOW; - } else { - pfdFlags |= WGL.PFD_DRAW_TO_BITMAP; - } - if (caps.getStereo()) { - pfdFlags |= WGL.PFD_STEREO; - } - pfd.dwFlags(pfdFlags); - pfd.iPixelType((byte) WGL.PFD_TYPE_RGBA); - pfd.cColorBits((byte) colorDepth); - pfd.cRedBits ((byte) caps.getRedBits()); - pfd.cGreenBits((byte) caps.getGreenBits()); - pfd.cBlueBits ((byte) caps.getBlueBits()); - pfd.cAlphaBits((byte) caps.getAlphaBits()); - int accumDepth = (caps.getAccumRedBits() + - caps.getAccumGreenBits() + - caps.getAccumBlueBits()); - pfd.cAccumBits ((byte) accumDepth); - pfd.cAccumRedBits ((byte) caps.getAccumRedBits()); - pfd.cAccumGreenBits((byte) caps.getAccumGreenBits()); - pfd.cAccumBlueBits ((byte) caps.getAccumBlueBits()); - pfd.cAccumAlphaBits((byte) caps.getAccumAlphaBits()); - pfd.cDepthBits((byte) caps.getDepthBits()); - pfd.cStencilBits((byte) caps.getStencilBits()); - pfd.iLayerType((byte) WGL.PFD_MAIN_PLANE); - return pfd; - } - - protected static PIXELFORMATDESCRIPTOR newPixelFormatDescriptor() { - PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create(); - pfd.nSize((short) pfd.size()); - pfd.nVersion((short) 1); - return pfd; - } - - protected static GLCapabilities pfd2GLCapabilities(PIXELFORMATDESCRIPTOR pfd) { - if ((pfd.dwFlags() & WGL.PFD_SUPPORT_OPENGL) == 0) { - return null; - } - GLCapabilities res = new GLCapabilities(); - res.setRedBits (pfd.cRedBits()); - res.setGreenBits (pfd.cGreenBits()); - res.setBlueBits (pfd.cBlueBits()); - res.setAlphaBits (pfd.cAlphaBits()); - res.setAccumRedBits (pfd.cAccumRedBits()); - res.setAccumGreenBits(pfd.cAccumGreenBits()); - res.setAccumBlueBits (pfd.cAccumBlueBits()); - res.setAccumAlphaBits(pfd.cAccumAlphaBits()); - res.setDepthBits (pfd.cDepthBits()); - res.setStencilBits (pfd.cStencilBits()); - res.setDoubleBuffered((pfd.dwFlags() & WGL.PFD_DOUBLEBUFFER) != 0); - res.setStereo ((pfd.dwFlags() & WGL.PFD_STEREO) != 0); - res.setHardwareAccelerated(((pfd.dwFlags() & WGL.PFD_GENERIC_FORMAT) == 0) || - ((pfd.dwFlags() & WGL.PFD_GENERIC_ACCELERATED) != 0)); - return res; - } - - protected static boolean glCapabilities2iattributes(GLCapabilities capabilities, - int[] iattributes, - WGLExt wglExt, - boolean pbuffer, - int[] floatMode) throws GLException { - if (!wglExt.isExtensionAvailable("WGL_ARB_pixel_format")) { - return false; - } - - int niattribs = 0; - - iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB; - iattributes[niattribs++] = GL.GL_TRUE; - if (pbuffer) { - iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB; - iattributes[niattribs++] = GL.GL_TRUE; - } else { - iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB; - iattributes[niattribs++] = GL.GL_TRUE; - } - - iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB; - if (capabilities.getDoubleBuffered()) { - iattributes[niattribs++] = GL.GL_TRUE; - } else { - iattributes[niattribs++] = GL.GL_FALSE; - } - - iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB; - if (capabilities.getStereo()) { - iattributes[niattribs++] = GL.GL_TRUE; - } else { - iattributes[niattribs++] = GL.GL_FALSE; - } - - iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB; - iattributes[niattribs++] = capabilities.getDepthBits(); - iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB; - iattributes[niattribs++] = capabilities.getRedBits(); - iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB; - iattributes[niattribs++] = capabilities.getGreenBits(); - iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB; - iattributes[niattribs++] = capabilities.getBlueBits(); - iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB; - iattributes[niattribs++] = capabilities.getAlphaBits(); - iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB; - iattributes[niattribs++] = capabilities.getStencilBits(); - if (capabilities.getAccumRedBits() > 0 || - capabilities.getAccumGreenBits() > 0 || - capabilities.getAccumBlueBits() > 0 || - capabilities.getAccumAlphaBits() > 0) { - iattributes[niattribs++] = WGLExt.WGL_ACCUM_BITS_ARB; - iattributes[niattribs++] = (capabilities.getAccumRedBits() + - capabilities.getAccumGreenBits() + - capabilities.getAccumBlueBits() + - capabilities.getAccumAlphaBits()); - iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB; - iattributes[niattribs++] = capabilities.getAccumRedBits(); - iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB; - iattributes[niattribs++] = capabilities.getAccumGreenBits(); - iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB; - iattributes[niattribs++] = capabilities.getAccumBlueBits(); - iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB; - iattributes[niattribs++] = capabilities.getAccumAlphaBits(); - } - - if (wglExt.isExtensionAvailable("WGL_ARB_multisample")) { - if (capabilities.getSampleBuffers()) { - iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB; - iattributes[niattribs++] = GL.GL_TRUE; - iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB; - iattributes[niattribs++] = capabilities.getNumSamples(); - } - } - - boolean rtt = capabilities.getPbufferRenderToTexture(); - boolean rect = capabilities.getPbufferRenderToTextureRectangle(); - boolean useFloat = capabilities.getPbufferFloatingPointBuffers(); - boolean ati = false; - if (pbuffer) { - // Check some invariants and set up some state - if (rect && !rtt) { - throw new GLException("Render-to-texture-rectangle requires render-to-texture to be specified"); - } - - if (rect) { - if (!wglExt.isExtensionAvailable("GL_NV_texture_rectangle")) { - throw new GLException("Render-to-texture-rectangle requires GL_NV_texture_rectangle extension"); - } - } - - if (useFloat) { - if (!wglExt.isExtensionAvailable("WGL_ATI_pixel_format_float") && - !wglExt.isExtensionAvailable("WGL_NV_float_buffer")) { - throw new GLException("Floating-point pbuffers not supported by this hardware"); - } - - // Prefer NVidia extension over ATI - if (wglExt.isExtensionAvailable("WGL_NV_float_buffer")) { - ati = false; - floatMode[0] = GLPbuffer.NV_FLOAT; - } else { - ati = true; - floatMode[0] = GLPbuffer.ATI_FLOAT; - } - if (DEBUG) { - System.err.println("Using " + (ati ? "ATI" : "NVidia") + " floating-point extension"); - } - } - - // See whether we need to change the pixel type to support ATI's - // floating-point pbuffers - if (useFloat && ati) { - if (rtt) { - throw new GLException("Render-to-floating-point-texture not supported on ATI hardware"); - } else { - iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB; - iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_FLOAT_ARB; - } - } else { - if (!rtt) { - // Currently we don't support non-truecolor visuals in the - // GLCapabilities, so we don't offer the option of making - // color-index pbuffers. - iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB; - iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_ARB; - } - } - - if (useFloat && !ati) { - iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV; - iattributes[niattribs++] = GL.GL_TRUE; - } - - if (rtt) { - if (useFloat) { - assert(!ati); - if (!rect) { - throw new GLException("Render-to-floating-point-texture only supported on NVidia hardware with render-to-texture-rectangle"); - } - iattributes[niattribs++] = WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV; - iattributes[niattribs++] = GL.GL_TRUE; - } else { - iattributes[niattribs++] = rect ? WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV : WGLExt.WGL_BIND_TO_TEXTURE_RGB_ARB; - iattributes[niattribs++] = GL.GL_TRUE; - } - } - } else { - iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB; - iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_ARB; - } - - return true; - } - - protected static GLCapabilities iattributes2GLCapabilities(int[] iattribs, - int niattribs, - int[] iresults, - boolean requireRenderToWindow) { - GLCapabilities res = new GLCapabilities(); - for (int i = 0; i < niattribs; i++) { - int attr = iattribs[i]; - switch (attr) { - case WGLExt.WGL_DRAW_TO_WINDOW_ARB: - if (requireRenderToWindow && iresults[i] != GL.GL_TRUE) - return null; - break; - - 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; - } - protected static String getThreadName() { return Thread.currentThread().getName(); } diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java index 3380de742..9bb8797dc 100644 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java @@ -55,29 +55,26 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { public WindowsWGLDrawableFactory() { super(); + + // Register our GraphicsConfigurationFactory implementations + // The act of constructing them causes them to be registered + new WindowsWGLGraphicsConfigurationFactory(); } - public GLDrawable createGLDrawable(NativeWindow target, - GLCapabilities capabilities, - GLCapabilitiesChooser chooser) { + public GLDrawable createGLDrawable(NativeWindow target) { if (target == null) { throw new IllegalArgumentException("Null target"); } - target = NativeWindowFactory.getNativeWindow(target); - if (capabilities == null) { - capabilities = new GLCapabilities(); - } - if (chooser == null) { - chooser = new DefaultGLCapabilitiesChooser(); - } - return new WindowsOnscreenWGLDrawable(this, target, capabilities, chooser); + target = NativeWindowFactory.getNativeWindow(target, null); + return new WindowsOnscreenWGLDrawable(this, target); } public GLDrawableImpl createOffscreenDrawable(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) { - return new WindowsOffscreenWGLDrawable(this, capabilities, chooser, width, height); + AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(); + return new WindowsOffscreenWGLDrawable(this, aScreen, capabilities, chooser, width, height); } private boolean pbufferSupportInitialized = false; @@ -136,7 +133,8 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { dummyContext.makeCurrent(); WGLExt dummyWGLExt = dummyContext.getWGLExt(); try { - WindowsPbufferWGLDrawable pbufferDrawable = new WindowsPbufferWGLDrawable(factory, capabilities, + AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(); + WindowsPbufferWGLDrawable pbufferDrawable = new WindowsPbufferWGLDrawable(factory, aScreen, capabilities, chooser, initialWidth, initialHeight, dummyDrawable, @@ -158,7 +156,8 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } public GLContext createExternalGLContext() { - return new WindowsExternalWGLContext(); + AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(); + return new WindowsExternalWGLContext(aScreen); } public boolean canCreateExternalGLDrawable() { @@ -166,7 +165,8 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } public GLDrawable createExternalGLDrawable() { - return WindowsExternalWGLDrawable.create(this); + AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(); + return WindowsExternalWGLDrawable.create(this, aScreen); } public void loadGLULibrary() { diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java new file mode 100644 index 000000000..d7293e3d4 --- /dev/null +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution 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. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package com.sun.opengl.impl.windows.wgl; + +import java.util.*; +import javax.media.nativewindow.*; +import javax.media.opengl.*; +import com.sun.opengl.impl.*; +import com.sun.gluegen.runtime.NativeLibrary; + +public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable { + // Keep this under the same debug flag as the drawable factory for convenience + protected static final boolean DEBUG = com.sun.opengl.impl.Debug.debug("GraphicsConfiguration"); + + protected static final int MAX_PFORMATS = 256; + protected static final int MAX_ATTRIBS = 256; + + private PIXELFORMATDESCRIPTOR pixelfmt; + private int pixelfmtID; + private boolean isUpdated = false; + private GLCapabilitiesChooser chooser; + + public WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen, GLCapabilities caps, PIXELFORMATDESCRIPTOR pixelfmt, int pixelfmtID, + GLCapabilitiesChooser chooser) { + super(screen, caps); + this.chooser=chooser; + this.pixelfmt = pixelfmt; + this.pixelfmtID = pixelfmtID; + } + + public Object clone() { + return super.clone(); + } + + protected void update(GLDrawableFactory factory, NativeWindow nativeWindow, boolean useOffScreen) { + WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration(chooser, factory, nativeWindow, useOffScreen); + } + protected void setCapsPFD(GLCapabilities caps, PIXELFORMATDESCRIPTOR pfd, int pfdID) { + this.pixelfmt = pfd; + this.pixelfmtID = pfdID; + setCapabilities(caps); + isUpdated=true; + } + + public boolean getIsUpdated() { + return isUpdated; + } + + public PIXELFORMATDESCRIPTOR getPixelFormat() { return pixelfmt; } + public int getPixelFormatID() { return pixelfmtID; } + + public static boolean GLCapabilities2AttribList(GLCapabilities caps, + int[] iattributes, + WGLExt wglExt, + boolean pbuffer, + int[] floatMode) throws GLException { + if (!wglExt.isExtensionAvailable("WGL_ARB_pixel_format")) { + return false; + } + + int niattribs = 0; + + iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB; + iattributes[niattribs++] = GL.GL_TRUE; + if (pbuffer) { + iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB; + iattributes[niattribs++] = GL.GL_TRUE; + } else { + iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB; + iattributes[niattribs++] = GL.GL_TRUE; + } + + iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB; + if (caps.getDoubleBuffered()) { + iattributes[niattribs++] = GL.GL_TRUE; + } else { + iattributes[niattribs++] = GL.GL_FALSE; + } + + iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB; + if (caps.getStereo()) { + iattributes[niattribs++] = GL.GL_TRUE; + } else { + iattributes[niattribs++] = GL.GL_FALSE; + } + + iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB; + iattributes[niattribs++] = caps.getDepthBits(); + iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB; + iattributes[niattribs++] = caps.getRedBits(); + iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB; + iattributes[niattribs++] = caps.getGreenBits(); + iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB; + iattributes[niattribs++] = caps.getBlueBits(); + iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB; + iattributes[niattribs++] = caps.getAlphaBits(); + iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB; + iattributes[niattribs++] = caps.getStencilBits(); + if (caps.getAccumRedBits() > 0 || + caps.getAccumGreenBits() > 0 || + caps.getAccumBlueBits() > 0 || + caps.getAccumAlphaBits() > 0) { + iattributes[niattribs++] = WGLExt.WGL_ACCUM_BITS_ARB; + iattributes[niattribs++] = (caps.getAccumRedBits() + + caps.getAccumGreenBits() + + caps.getAccumBlueBits() + + caps.getAccumAlphaBits()); + iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB; + iattributes[niattribs++] = caps.getAccumRedBits(); + iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB; + iattributes[niattribs++] = caps.getAccumGreenBits(); + iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB; + iattributes[niattribs++] = caps.getAccumBlueBits(); + iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB; + iattributes[niattribs++] = caps.getAccumAlphaBits(); + } + + if (wglExt.isExtensionAvailable("WGL_ARB_multisample")) { + if (caps.getSampleBuffers()) { + iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB; + iattributes[niattribs++] = GL.GL_TRUE; + iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB; + iattributes[niattribs++] = caps.getNumSamples(); + } + } + + boolean rtt = caps.getPbufferRenderToTexture(); + boolean rect = caps.getPbufferRenderToTextureRectangle(); + boolean useFloat = caps.getPbufferFloatingPointBuffers(); + boolean ati = false; + if (pbuffer) { + // Check some invariants and set up some state + if (rect && !rtt) { + throw new GLException("Render-to-texture-rectangle requires render-to-texture to be specified"); + } + + if (rect) { + if (!wglExt.isExtensionAvailable("GL_NV_texture_rectangle")) { + throw new GLException("Render-to-texture-rectangle requires GL_NV_texture_rectangle extension"); + } + } + + if (useFloat) { + if (!wglExt.isExtensionAvailable("WGL_ATI_pixel_format_float") && + !wglExt.isExtensionAvailable("WGL_NV_float_buffer")) { + throw new GLException("Floating-point pbuffers not supported by this hardware"); + } + + // Prefer NVidia extension over ATI + if (wglExt.isExtensionAvailable("WGL_NV_float_buffer")) { + ati = false; + floatMode[0] = GLPbuffer.NV_FLOAT; + } else { + ati = true; + floatMode[0] = GLPbuffer.ATI_FLOAT; + } + if (DEBUG) { + System.err.println("Using " + (ati ? "ATI" : "NVidia") + " floating-point extension"); + } + } + + // See whether we need to change the pixel type to support ATI's + // floating-point pbuffers + if (useFloat && ati) { + if (rtt) { + throw new GLException("Render-to-floating-point-texture not supported on ATI hardware"); + } else { + iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB; + iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_FLOAT_ARB; + } + } else { + if (!rtt) { + // Currently we don't support non-truecolor visuals in the + // GLCapabilities, so we don't offer the option of making + // color-index pbuffers. + iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB; + iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_ARB; + } + } + + if (useFloat && !ati) { + iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV; + iattributes[niattribs++] = GL.GL_TRUE; + } + + if (rtt) { + if (useFloat) { + assert(!ati); + if (!rect) { + throw new GLException("Render-to-floating-point-texture only supported on NVidia hardware with render-to-texture-rectangle"); + } + iattributes[niattribs++] = WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV; + iattributes[niattribs++] = GL.GL_TRUE; + } else { + iattributes[niattribs++] = rect ? WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV : WGLExt.WGL_BIND_TO_TEXTURE_RGB_ARB; + iattributes[niattribs++] = GL.GL_TRUE; + } + } + } else { + iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB; + iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_ARB; + } + iattributes[niattribs++] = 0; + + return true; + } + + public static GLCapabilities AttribList2GLCapabilities(int[] iattribs, + int niattribs, + int[] iresults, + boolean requireRenderToWindow) { + GLCapabilities res = new GLCapabilities(); + for (int i = 0; i < niattribs; i++) { + int attr = iattribs[i]; + switch (attr) { + case WGLExt.WGL_DRAW_TO_WINDOW_ARB: + if (requireRenderToWindow && iresults[i] != GL.GL_TRUE) { + return null; + } + break; + + 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; + } + + // PIXELFORMAT + + public static GLCapabilities PFD2GLCapabilities(PIXELFORMATDESCRIPTOR pfd) { + if ((pfd.dwFlags() & WGL.PFD_SUPPORT_OPENGL) == 0) { + return null; + } + GLCapabilities res = new GLCapabilities(); + res.setRedBits (pfd.cRedBits()); + res.setGreenBits (pfd.cGreenBits()); + res.setBlueBits (pfd.cBlueBits()); + res.setAlphaBits (pfd.cAlphaBits()); + res.setAccumRedBits (pfd.cAccumRedBits()); + res.setAccumGreenBits(pfd.cAccumGreenBits()); + res.setAccumBlueBits (pfd.cAccumBlueBits()); + res.setAccumAlphaBits(pfd.cAccumAlphaBits()); + res.setDepthBits (pfd.cDepthBits()); + res.setStencilBits (pfd.cStencilBits()); + res.setDoubleBuffered((pfd.dwFlags() & WGL.PFD_DOUBLEBUFFER) != 0); + res.setStereo ((pfd.dwFlags() & WGL.PFD_STEREO) != 0); + res.setHardwareAccelerated(((pfd.dwFlags() & WGL.PFD_GENERIC_FORMAT) == 0) || + ((pfd.dwFlags() & WGL.PFD_GENERIC_ACCELERATED) != 0)); + /* FIXME: Missing ?? + if (GLXUtil.isMultisampleAvailable()) { + res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0); + res.setNumSamples (glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLES, tmp, 0)); + } + res.setBackgroundOpaque(glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_TYPE, tmp, 0) != GLX.GLX_NONE); + try { + res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE); + } catch (Exception e) {} + */ + return res; + } + + public static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilities caps, boolean offscreen) { + int colorDepth = (caps.getRedBits() + + caps.getGreenBits() + + caps.getBlueBits()); + if (colorDepth < 15) { + throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported"); + } + PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); + int pfdFlags = (WGL.PFD_SUPPORT_OPENGL | + WGL.PFD_GENERIC_ACCELERATED); + if (caps.getDoubleBuffered()) { + pfdFlags |= WGL.PFD_DOUBLEBUFFER; + } + if (offscreen) { + pfdFlags |= WGL.PFD_DRAW_TO_BITMAP; + } else { + pfdFlags |= WGL.PFD_DRAW_TO_WINDOW; + } + if (caps.getStereo()) { + pfdFlags |= WGL.PFD_STEREO; + } + pfd.dwFlags(pfdFlags); + pfd.iPixelType((byte) WGL.PFD_TYPE_RGBA); + pfd.cColorBits((byte) colorDepth); + pfd.cRedBits ((byte) caps.getRedBits()); + pfd.cGreenBits((byte) caps.getGreenBits()); + pfd.cBlueBits ((byte) caps.getBlueBits()); + pfd.cAlphaBits((byte) caps.getAlphaBits()); + int accumDepth = (caps.getAccumRedBits() + + caps.getAccumGreenBits() + + caps.getAccumBlueBits()); + pfd.cAccumBits ((byte) accumDepth); + pfd.cAccumRedBits ((byte) caps.getAccumRedBits()); + pfd.cAccumGreenBits((byte) caps.getAccumGreenBits()); + pfd.cAccumBlueBits ((byte) caps.getAccumBlueBits()); + pfd.cAccumAlphaBits((byte) caps.getAccumAlphaBits()); + pfd.cDepthBits((byte) caps.getDepthBits()); + pfd.cStencilBits((byte) caps.getStencilBits()); + pfd.iLayerType((byte) WGL.PFD_MAIN_PLANE); + + /* FIXME: Missing: + caps.getSampleBuffers() + caps.getNumSamples () + } + caps.getBackgroundOpaque() + try { + caps.getPbufferFloatingPointBuffers() + } catch (Exception e) {} + */ + return pfd; + } + + public static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() { + PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create(); + pfd.nSize((short) pfd.size()); + pfd.nVersion((short) 1); + return pfd; + } + + public String toString() { + return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + pixelfmtID + ", " + getCapabilities() +"]"; + } +} + diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java new file mode 100644 index 000000000..64d55effb --- /dev/null +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution 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. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package com.sun.opengl.impl.windows.wgl; + +import javax.media.nativewindow.*; +import com.sun.nativewindow.impl.*; + +import javax.media.opengl.*; +import com.sun.opengl.impl.*; + +/** 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 GraphicsConfigurationFactory { + protected static final boolean DEBUG = com.sun.opengl.impl.Debug.debug("GraphicsConfiguration"); + + public WindowsWGLGraphicsConfigurationFactory() { + Class awtDeviceClass = NWReflection.getClass("javax.media.nativewindow.awt.AWTGraphicsDevice"); + if(null!=awtDeviceClass) { + GraphicsConfigurationFactory.registerFactory(awtDeviceClass, this); + } + GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.AbstractGraphicsDevice.class, this); + } + + public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, + CapabilitiesChooser chooser, + AbstractGraphicsScreen absScreen) { + return chooseGraphicsConfigurationStatic((GLCapabilities)capabilities, chooser, absScreen, false); + } + + protected static WindowsWGLGraphicsConfiguration createDefaultGraphicsConfiguration(AbstractGraphicsScreen absScreen, boolean useOffScreen) { + GLCapabilities caps = new GLCapabilities(); + if(null==absScreen) { + absScreen = DefaultGraphicsScreen.createScreenDevice(0); + } + return new WindowsWGLGraphicsConfiguration(absScreen, caps, WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps, useOffScreen), -1, null); + } + + protected static WindowsWGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilities caps, + CapabilitiesChooser chooser, + AbstractGraphicsScreen absScreen, boolean useOffScreen) { + if(null==absScreen) { + absScreen = DefaultGraphicsScreen.createScreenDevice(0); + } + return new WindowsWGLGraphicsConfiguration(absScreen, caps, WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps, useOffScreen), -1, + (GLCapabilitiesChooser)chooser); + } + + protected static void updateGraphicsConfiguration(CapabilitiesChooser chooser, + GLDrawableFactory factory, NativeWindow nativeWindow, boolean useOffScreen) { + if (nativeWindow == null) { + throw new IllegalArgumentException("NativeWindow is null"); + } + + if (chooser != null && + !(chooser instanceof GLCapabilitiesChooser)) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); + } + + WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) nativeWindow.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilities capabilities = (GLCapabilities) config.getCapabilities(); + long hdc = nativeWindow.getSurfaceHandle(); + + PIXELFORMATDESCRIPTOR pfd = null; + int pixelFormat = 0; + GLCapabilities chosenCaps = null; + + if (!useOffScreen) { + if ((pixelFormat = WGL.GetPixelFormat(hdc)) != 0) { + // The Java2D/OpenGL pipeline probably already set a pixel + // format for this canvas. + if (DEBUG) { + System.err.println("NOTE: pixel format already chosen (by Java2D/OpenGL pipeline?) for window: " + + WGL.GetPixelFormat(hdc)); + } + pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); + if (WGL.DescribePixelFormat(hdc, pixelFormat, pfd.size(), pfd) == 0) { + // FIXME: should this just be a warning? Not really critical... + throw new GLException("Unable to describe pixel format " + pixelFormat + + " of window set by Java2D/OpenGL pipeline"); + } + config.setCapsPFD(WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(pfd), pfd, pixelFormat); + return; + } + + GLCapabilities[] availableCaps = null; + int numFormats = 0; + pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); + // Produce a recommended pixel format selection for the GLCapabilitiesChooser. + // Use wglChoosePixelFormatARB if user requested multisampling and if we have it available + WindowsWGLDrawable dummyDrawable = null; + GLContextImpl dummyContext = null; + WGLExt dummyWGLExt = null; + if (capabilities.getSampleBuffers()) { + dummyDrawable = new WindowsDummyWGLDrawable(factory); + dummyContext = (GLContextImpl) dummyDrawable.createContext(null); + if (dummyContext != null) { + dummyContext.makeCurrent(); + dummyWGLExt = (WGLExt) dummyContext.getPlatformGLExtensions(); + } + } + int recommendedPixelFormat = -1; + boolean haveWGLChoosePixelFormatARB = false; + boolean haveWGLARBMultisample = false; + boolean gotAvailableCaps = false; + if (dummyWGLExt != null) { + try { + haveWGLChoosePixelFormatARB = dummyWGLExt.isExtensionAvailable("WGL_ARB_pixel_format"); + if (haveWGLChoosePixelFormatARB) { + haveWGLARBMultisample = dummyWGLExt.isExtensionAvailable("WGL_ARB_multisample"); + + int[] iattributes = new int [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS]; + int[] iresults = new int [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS]; + float[] fattributes = new float[1]; + + if(WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities, + iattributes, + dummyWGLExt, + false, + null)) { + int[] pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS]; + int[] numFormatsTmp = new int[1]; + if (dummyWGLExt.wglChoosePixelFormatARB(hdc, + iattributes, 0, + fattributes, 0, + WindowsWGLGraphicsConfiguration.MAX_PFORMATS, + pformats, 0, + numFormatsTmp, 0)) { + numFormats = numFormatsTmp[0]; + if (numFormats > 0) { + // Remove one-basing of pixel format (added on later) + recommendedPixelFormat = pformats[0] - 1; + if (DEBUG) { + System.err.println(getThreadName() + ": Used wglChoosePixelFormatARB to recommend pixel format " + recommendedPixelFormat); + } + } + } else { + if (DEBUG) { + System.err.println(getThreadName() + ": wglChoosePixelFormatARB failed: " + WGL.GetLastError() ); + Thread.dumpStack(); + } + } + if (DEBUG) { + if (recommendedPixelFormat < 0) { + System.err.print(getThreadName() + ": wglChoosePixelFormatARB didn't recommend a pixel format"); + if (capabilities.getSampleBuffers()) { + System.err.print(" for multisampled GLCapabilities"); + } + System.err.println(); + } + } + + // 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) + int niattribs = 0; + iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB; + if (dummyWGLExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) { + numFormats = iresults[0]; + + if (DEBUG) { + System.err.println("wglGetPixelFormatAttribivARB reported WGL_NUMBER_PIXEL_FORMATS = " + numFormats); + } + + // Should we be filtering out the pixel formats which aren't + // applicable, as we are doing here? + // We don't have enough information in the GLCapabilities to + // represent those that aren't... + iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB; + iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB; + iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_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_PIXEL_TYPE_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_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; + if (haveWGLARBMultisample) { + iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB; + iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB; + } + + availableCaps = new GLCapabilities[numFormats]; + for (int i = 0; i < numFormats; i++) { + if (!dummyWGLExt.wglGetPixelFormatAttribivARB(hdc, i+1, 0, niattribs, iattributes, 0, iresults, 0)) { + throw new GLException("Error getting pixel format attributes for pixel format " + (i + 1) + " of device context"); + } + availableCaps[i] = WindowsWGLGraphicsConfiguration.AttribList2GLCapabilities(iattributes, niattribs, iresults, true); + } + gotAvailableCaps = true; + } else { + long lastErr = WGL.GetLastError(); + // Intel Extreme graphics fails with a zero error code + if (lastErr != 0) { + throw new GLException("Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + WGL.GetLastError()); + } + } + } + } + } finally { + dummyContext.release(); + dummyContext.destroy(); + dummyDrawable.destroy(); + } + } + + // Fallback path for older cards, in particular Intel Extreme motherboard graphics + if (!gotAvailableCaps) { + if (DEBUG) { + if (!capabilities.getSampleBuffers()) { + System.err.println(getThreadName() + ": Using ChoosePixelFormat because multisampling not requested"); + } else { + System.err.println(getThreadName() + ": Using ChoosePixelFormat because no wglChoosePixelFormatARB"); + } + } + pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capabilities, !useOffScreen); + // Remove one-basing of pixel format (added on later) + recommendedPixelFormat = WGL.ChoosePixelFormat(hdc, pfd) - 1; + if (DEBUG) { + System.err.println(getThreadName() + ": Recommended pixel format = " + recommendedPixelFormat); + } + + numFormats = WGL.DescribePixelFormat(hdc, 1, 0, null); + if (numFormats == 0) { + throw new GLException("Unable to enumerate pixel formats of window " + + toHexString(hdc) + " for GLCapabilitiesChooser"); + } + availableCaps = new GLCapabilities[numFormats]; + for (int i = 0; i < numFormats; i++) { + if (WGL.DescribePixelFormat(hdc, 1 + i, pfd.size(), pfd) == 0) { + throw new GLException("Error describing pixel format " + (1 + i) + " of device context"); + } + availableCaps[i] = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(pfd); + } + } + + // NOTE: officially, should make a copy of all of these + // GLCapabilities to avoid mutation by the end user during the + // chooseCapabilities call, but for the time being, assume they + // won't be changed + + if(null!=chooser) { + // Supply information to chooser + try { + pixelFormat = chooser.chooseCapabilities(capabilities, availableCaps, recommendedPixelFormat); + } catch (NativeWindowException e) { + throw new GLException(e); + } + } else { + pixelFormat = recommendedPixelFormat; + } + if ((pixelFormat < 0) || (pixelFormat >= numFormats)) { + throw new GLException("Invalid result " + pixelFormat + + " from GLCapabilitiesChooser (should be between 0 and " + + (numFormats - 1) + ")"); + } + if (DEBUG) { + System.err.println(getThreadName() + ": Chosen pixel format (" + pixelFormat + "):"); + System.err.println(availableCaps[pixelFormat]); + } + chosenCaps = availableCaps[pixelFormat]; + pixelFormat += 1; // one-base the index + if (WGL.DescribePixelFormat(hdc, pixelFormat, pfd.size(), pfd) == 0) { + throw new GLException("Error re-describing the chosen pixel format: " + WGL.GetLastError()); + } + } else { + // For now, use ChoosePixelFormat for offscreen surfaces until + // we figure out how to properly choose an offscreen- + // compatible pixel format + pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capabilities, !useOffScreen); + pixelFormat = WGL.ChoosePixelFormat(hdc, pfd); + } + if (!WGL.SetPixelFormat(hdc, pixelFormat, pfd)) { + long lastError = WGL.GetLastError(); + if (DEBUG) { + System.err.println(getThreadName() + ": SetPixelFormat failed: current context = " + WGL.wglGetCurrentContext() + + ", current DC = " + WGL.wglGetCurrentDC()); + System.err.println(getThreadName() + ": GetPixelFormat(hdc " + toHexString(hdc) + ") returns " + WGL.GetPixelFormat(hdc)); + } + throw new GLException("Unable to set pixel format " + pixelFormat + " for device context " + toHexString(hdc) + ": error code " + lastError); + } + // Reuse the previously-constructed GLCapabilities because it + // turns out that using DescribePixelFormat on some pixel formats + // (which, for example, support full-scene antialiasing) for some + // reason return that they are not OpenGL-capable + if (chosenCaps != null) { + capabilities = chosenCaps; + } else { + capabilities = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(pfd); + } + config.setCapsPFD(capabilities, pfd, pixelFormat); + } + + protected static String getThreadName() { + return Thread.currentThread().getName(); + } + public static String toHexString(long hex) { + return "0x" + Long.toHexString(hex); + } +} + diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/GLXUtil.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/GLXUtil.java index 7b4165ba2..650499207 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/GLXUtil.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/GLXUtil.java @@ -36,7 +36,6 @@ import javax.media.opengl.*; import com.sun.opengl.impl.*; import javax.media.nativewindow.NativeWindowFactory; -import com.sun.nativewindow.impl.NullWindow; import com.sun.nativewindow.impl.x11.*; public class GLXUtil { diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11ExternalGLXContext.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11ExternalGLXContext.java index c68827862..3d88b9ac4 100755 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11ExternalGLXContext.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11ExternalGLXContext.java @@ -50,7 +50,7 @@ public class X11ExternalGLXContext extends X11GLXContext { private boolean created = true; private GLContext lastContext; - public X11ExternalGLXContext() { + public X11ExternalGLXContext(AbstractGraphicsScreen screen) { super(null, null); getDrawableImpl().getFactoryImpl().lockToolkit(); try { @@ -58,8 +58,7 @@ public class X11ExternalGLXContext extends X11GLXContext { if (context == 0) { throw new GLException("Error: attempted to make an external GLContext without a drawable/context current"); } - NullWindow nw = new NullWindow(); - nw.setDisplayHandle(GLX.glXGetCurrentDisplay()); + NullWindow nw = new NullWindow(X11GLXGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(screen, false)); drawable = new Drawable(getGLDrawable().getFactory(), nw); } finally { getDrawableImpl().getFactoryImpl().unlockToolkit(); @@ -111,7 +110,7 @@ public class X11ExternalGLXContext extends X11GLXContext { // Need to provide the display connection to extension querying APIs class Drawable extends X11GLXDrawable { Drawable(GLDrawableFactory factory, NativeWindow comp) { - super(factory, comp, true, null, null); + super(factory, comp, true); } public GLContext createContext(GLContext shareWith) { diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11ExternalGLXDrawable.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11ExternalGLXDrawable.java index 2629b2362..27427808c 100755 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11ExternalGLXDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11ExternalGLXDrawable.java @@ -53,7 +53,7 @@ public class X11ExternalGLXDrawable extends X11GLXDrawable { private long readDrawable; private X11ExternalGLXDrawable(GLDrawableFactory factory, NativeWindow component) { - super(factory, component, true, null, null); + super(factory, component, true); readDrawable = GLX.glXGetCurrentReadDrawable(); @@ -73,22 +73,28 @@ public class X11ExternalGLXDrawable extends X11GLXDrawable { } } - protected static X11ExternalGLXDrawable create(GLDrawableFactory factory) { + protected static X11ExternalGLXDrawable create(GLDrawableFactory factory, AbstractGraphicsScreen aScreen) { ((GLDrawableFactoryImpl) factory).lockToolkit(); try { long display = GLX.glXGetCurrentDisplay(); + long context = GLX.glXGetCurrentContext(); + int[] val = new int[1]; + GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val, 0); + int screen = val[0]; long drawable = GLX.glXGetCurrentDrawable(); if (drawable == 0) { throw new GLException("Error: attempted to make an external GLDrawable without a drawable/context current"); } - long context = GLX.glXGetCurrentContext(); - int[] val = new int[1]; - GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val, 0); - int screen = val[0]; - NullWindow nw = new NullWindow(); + if(screen!=aScreen.getIndex()) { + throw new GLException("Error: Passed AbstractGraphicsScreen's index is not current: "+aScreen+", GLX-screen "+screen); + } + if(display!=aScreen.getDevice().getHandle()) { + throw new GLException("Error: Passed AbstractGraphicsScreen's display is not current: "+aScreen+", GLX-display 0x"+Long.toHexString(display)); + } + + NullWindow nw = new NullWindow(X11GLXGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(aScreen, false)); nw.setSurfaceHandle(drawable); - nw.setScreenIndex(screen); return new X11ExternalGLXDrawable(factory, nw); } finally { ((GLDrawableFactoryImpl) factory).unlockToolkit(); @@ -187,7 +193,7 @@ public class X11ExternalGLXDrawable extends X11GLXDrawable { }; float[] fattributes = new float[0]; int[] nelementsTmp = new int[1]; - LongBuffer fbConfigs = GLX.glXChooseFBConfig(display, screen, iattributes, 0, nelementsTmp, 0); + LongBuffer fbConfigs = GLX.glXChooseFBConfigCopied(display, screen, iattributes, 0, nelementsTmp, 0); int nelements = nelementsTmp[0]; if (nelements <= 0) { throw new GLException("context creation error: couldn't find a suitable frame buffer configuration"); diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java index 61d482f4f..2551390c9 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java @@ -42,6 +42,8 @@ package com.sun.opengl.impl.x11.glx; import java.nio.*; import java.util.*; import javax.media.opengl.*; +import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.*; import com.sun.opengl.impl.*; import com.sun.opengl.impl.x11.glx.*; import com.sun.nativewindow.impl.x11.*; @@ -117,7 +119,6 @@ public abstract class X11GLXContext extends GLContextImpl { * called by {@link create()}. */ protected void createContext(boolean onscreen) { - XVisualInfo vis = drawable.chooseVisual(onscreen); X11GLXContext other = (X11GLXContext) GLContextShareSet.getShareContext(this); long share = 0; if (other != null) { @@ -126,10 +127,119 @@ public abstract class X11GLXContext extends GLContextImpl { throw new GLException("GLContextShareSet returned an invalid OpenGL context"); } } - context = GLX.glXCreateContext(drawable.getNativeWindow().getDisplayHandle(), vis, share, onscreen); - if (context == 0) { - throw new GLException("Unable to create OpenGL context"); + + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + if(DEBUG) { + System.err.println("X11GLXContext.createContext got "+config); } + long display = config.getScreen().getDevice().getHandle(); + + if(config.getFBConfigID()<0) { + // not able to use FBConfig + if(GLProfile.isGL3()) { + throw new GLException("Unable to create OpenGL 3.1 context"); + } + context = GLX.glXCreateContext(display, config.getXVisualInfo(), share, onscreen); + if (context == 0) { + throw new GLException("Unable to create OpenGL context"); + } + if (!GLX.glXMakeContextCurrent(display, + drawable.getNativeWindow().getSurfaceHandle(), + drawable.getNativeWindow().getSurfaceHandle(), + context)) { + throw new GLException("Error making temp context (old2) current: display 0x"+Long.toHexString(display)+", context 0x"+Long.toHexString(context)+", drawable "+drawable); + } + resetGLFunctionAvailability(); + if(DEBUG) { + System.err.println("X11GLXContext.createContext done (old2 ctx) 0x"+Long.toHexString(context)); + } + + } else { + + // To use GLX_ARB_create_context, we have to make a temp context current, + // so we are able to use GetProcAddress + long temp_context = GLX.glXCreateNewContext(display, config.getFBConfig(), GLX.GLX_RGBA_TYPE, share, onscreen); + if (temp_context == 0) { + throw new GLException("Unable to create temp OpenGL context"); + } else { + if (!GLX.glXMakeContextCurrent(display, + drawable.getNativeWindow().getSurfaceHandle(), + drawable.getNativeWindow().getSurfaceHandle(), + temp_context)) { + throw new GLException("Error making temp context (old) current: display 0x"+Long.toHexString(display)+", context 0x"+Long.toHexString(context)+", drawable "+drawable); + } + resetGLFunctionAvailability(); + + if( !isFunctionAvailable("glXCreateContextAttribsARB") || + !isExtensionAvailable("GLX_ARB_create_context") ) { + if(GLProfile.isGL3()) { + if (!GLX.glXMakeContextCurrent(display, 0, 0, 0)) { + throw new GLException("Error freeing temp OpenGL context"); + } + GLX.glXDestroyContext(display, temp_context); + throw new GLException("Unable to create OpenGL 3.1 context (no GLX_ARB_create_context)"); + } + + // continue with temp context for GL < 3.0 + context = temp_context; + if(DEBUG) { + System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no GLX_ARB_create_context) 0x"+Long.toHexString(context)); + } + } else { + GLXExt glXExt = getGLXExt(); + + // preset with default values + int attribs[] = { + GLX.GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX.GLX_CONTEXT_MINOR_VERSION_ARB, 0, + GLX.GLX_CONTEXT_FLAGS_ARB, 0, + GLX.GLX_RENDER_TYPE, GLX.GLX_RGBA_TYPE, + 0 + }; + + if(GLProfile.isGL3()) { + attribs[1] |= 3; + attribs[3] |= 1; + attribs[5] |= GLX.GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB /* | GLX.GLX_CONTEXT_DEBUG_BIT_ARB */; + } + + context = glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, onscreen, attribs, 0); + if(0==context) { + if(GLProfile.isGL3()) { + if (!GLX.glXMakeContextCurrent(display, 0, 0, 0)) { + throw new GLException("Error freeing temp OpenGL context"); + } + GLX.glXDestroyContext(display, temp_context); + throw new GLException("Unable to create OpenGL 3.1 context (have GLX_ARB_create_context)"); + } + + // continue with temp context for GL < 3.0 + context = temp_context; + if(DEBUG) { + System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no 3.0) 0x"+Long.toHexString(context)); + } + } else { + if (!GLX.glXMakeContextCurrent(display, 0, 0, 0)) { + throw new GLException("Error freeing temp OpenGL context"); + } + GLX.glXDestroyContext(display, temp_context); + + // need to update the GL func table .. + if (!GLX.glXMakeContextCurrent(display, + drawable.getNativeWindow().getSurfaceHandle(), + drawable.getNativeWindow().getSurfaceHandle(), + context)) { + // FIXME: Nvidia driver 185.18.10 can't make the 3.1 context current .. + throw new GLException("Error making context (new) current: display 0x"+Long.toHexString(display)+", context 0x"+Long.toHexString(context)+", drawable "+drawable); + } + resetGLFunctionAvailability(); + if(DEBUG) { + System.err.println("X11GLXContext.createContext done (new ctx >= 3.0) 0x"+Long.toHexString(context)); + } + } + } + } + } GLContextShareSet.contextCreated(this); } @@ -155,18 +265,16 @@ public abstract class X11GLXContext extends GLContextImpl { drawable.getNativeWindow().getSurfaceHandle(), context)) { throw new GLException("Error making context current"); - } else { - if (DEBUG && (VERBOSE || created)) { - System.err.println(getThreadName() + ": glXMakeCurrent(display " + - toHexString(drawable.getNativeWindow().getDisplayHandle()) + - ", drawable " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) + - ", context " + toHexString(context) + ") succeeded"); - } + } + if (DEBUG && (VERBOSE || created)) { + System.err.println(getThreadName() + ": glXMakeCurrent(display " + + toHexString(drawable.getNativeWindow().getDisplayHandle()) + + ", drawable " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) + + ", context " + toHexString(context) + ") succeeded"); } } if (created) { - resetGLFunctionAvailability(); return CONTEXT_CURRENT_NEW; } return CONTEXT_CURRENT; @@ -267,25 +375,6 @@ public abstract class X11GLXContext extends GLContextImpl { } } - /** - * using dynamic ProcAddressTable verification always - * - public boolean isFunctionAvailable(String glFunctionName) - { - boolean available = super.isFunctionAvailable(glFunctionName); - - // Sanity check for implementations that use proc addresses for run-time - // linking: if the function IS available, then make sure there's a proc - // address for it if it's an extension or not part of the OpenGL 1.1 core - // (post GL 1.1 functions are run-time linked on windows). - assert(!available || - (getGLProcAddressTable().getAddressFor(mapToRealGLFunctionName(glFunctionName)) != 0 || - FunctionAvailabilityCache.isPartOfGLCore("1.1", mapToRealGLFunctionName(glFunctionName))) - ); - - return available; - }*/ - public boolean isExtensionAvailable(String glExtensionName) { if (glExtensionName.equals("GL_ARB_pbuffer") || glExtensionName.equals("GL_ARB_pixel_format")) { diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawable.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawable.java index 0b916213c..baffad289 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawable.java @@ -45,103 +45,13 @@ import com.sun.opengl.impl.*; import com.sun.nativewindow.impl.x11.*; public abstract class X11GLXDrawable extends GLDrawableImpl { - protected static final boolean DEBUG = Debug.debug("X11GLXDrawable"); + protected static final boolean DEBUG = Debug.debug("X11GLXDrawable"); - protected GLCapabilitiesChooser chooser; - - protected X11GLXDrawable(GLDrawableFactory factory, NativeWindow comp, boolean realized, - GLCapabilities requestedCapabilities, - GLCapabilitiesChooser chooser) { - super(factory, comp, requestedCapabilities, realized); - this.chooser = chooser; - } + protected X11GLXDrawable(GLDrawableFactory factory, NativeWindow comp, boolean realized) { + super(factory, comp, realized); + } //--------------------------------------------------------------------------- // Internals only below this point // - - protected XVisualInfo chooseVisual(boolean onscreen) { - long display = getNativeWindow().getDisplayHandle(); - long visualID = ((X11GLXDrawableFactory) getFactory()).getVisualID(getNativeWindow().getGraphicsConfiguration()); - if (display == 0) { - throw new GLException("null display"); - } - - // FIXME - if (onscreen) { - // The visual has already been chosen by the time we get here; - // it's specified by the GraphicsConfiguration of the - // GLCanvas. Fortunately, the JAWT supplies the visual ID for - // the component in a portable fashion, so all we have to do is - // use XGetVisualInfo with a VisualIDMask to get the - // corresponding XVisualInfo to pass into glXChooseVisual. - int[] count = new int[1]; - XVisualInfo template = XVisualInfo.create(); - // FIXME: probably not 64-bit clean - template.visualid((int) visualID); - getFactoryImpl().lockToolkit(); - XVisualInfo[] infos = X11Lib.XGetVisualInfo(display, X11Lib.VisualIDMask, template, count, 0); - getFactoryImpl().unlockToolkit(); - if (infos == null || infos.length == 0) { - throw new GLException("Error while getting XVisualInfo for visual ID " + visualID+", "+this); - } - if (DEBUG) { - System.err.println("!!! Fetched XVisualInfo for visual ID 0x" + Long.toHexString(visualID)); - System.err.println("!!! Resulting XVisualInfo: visualid = 0x" + Long.toHexString(infos[0].visualid())); - } - // FIXME: the storage for the infos array is leaked (should - // clean it up somehow when we're done with the visual we're - // returning) - return infos[0]; - } else { - // It isn't clear to me whether we need this much code to handle - // the offscreen case, where we're creating a pixmap into which - // to render...this is what we (incorrectly) used to do for the - // onscreen case - - int screen = 0; // FIXME: provide way to specify this? - XVisualInfo vis = null; - int[] count = new int[1]; - XVisualInfo template = XVisualInfo.create(); - template.screen(screen); - XVisualInfo[] infos = null; - GLCapabilities[] caps = null; - getFactoryImpl().lockToolkit(); - try { - infos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); - if (infos == null) { - throw new GLException("Error while enumerating available XVisualInfos"); - } - caps = new GLCapabilities[infos.length]; - for (int i = 0; i < infos.length; i++) { - caps[i] = ((X11GLXDrawableFactory)getFactory()).xvi2GLCapabilities(display, infos[i]); - } - } finally { - getFactoryImpl().unlockToolkit(); - } - GLCapabilities capabilities = getRequestedGLCapabilities(); - int chosen; - try { - chosen = chooser.chooseCapabilities(capabilities, caps, -1); - } catch (NativeWindowException e) { - throw new GLException(e); - } - if (chosen < 0 || chosen >= caps.length) { - throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); - } - if (DEBUG) { - System.err.println("Chosen visual (" + chosen + "):"); - System.err.println(caps[chosen]); - } - vis = infos[chosen]; - if (vis == null) { - throw new GLException("GLCapabilitiesChooser chose an invalid visual"); - } - // FIXME: the storage for the infos array is leaked (should - // clean it up somehow when we're done with the visual we're - // returning) - - return vis; - } - } } diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawableFactory.java index 3ca1396d2..bb284d60f 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawableFactory.java @@ -54,40 +54,6 @@ import com.sun.nativewindow.impl.jawt.x11.*; public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { protected static final boolean DEBUG = Debug.debug("X11GLXDrawableFactory"); - // Map for rediscovering the GLCapabilities associated with a - // particular screen and visualID after the fact - protected static Map visualToGLCapsMap = Collections.synchronizedMap(new HashMap()); - // The screens for which we've already initialized it - protected static Set/*<Integer>*/ initializedScreenSet = Collections.synchronizedSet(new HashSet()); - - public static class ScreenAndVisualIDKey { - private int screen; - private long visualID; - - public ScreenAndVisualIDKey(int screen, - long visualID) { - this.screen = screen; - this.visualID = visualID; - } - - public int hashCode() { - return (int) (screen + 13 * visualID); - } - - public boolean equals(Object obj) { - if ((obj == null) || (!(obj instanceof ScreenAndVisualIDKey))) { - return false; - } - - ScreenAndVisualIDKey key = (ScreenAndVisualIDKey) obj; - return (screen == key.screen && - visualID == key.visualID); - } - - int screen() { return screen; } - long visualID() { return visualID; } - } - public X11GLXDrawableFactory() { super(); // Must initialize GLX support eagerly in case a pbuffer is the @@ -103,68 +69,20 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } } - private static final int MAX_ATTRIBS = 128; - - public AbstractGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities, - GLCapabilitiesChooser chooser, - AbstractGraphicsDevice absDevice) { - return null; - } - - public GLDrawable createGLDrawable(NativeWindow target, - GLCapabilities capabilities, - GLCapabilitiesChooser chooser) { + public GLDrawable createGLDrawable(NativeWindow target) { if (target == null) { throw new IllegalArgumentException("Null target"); } - target = NativeWindowFactory.getNativeWindow(target); + target = NativeWindowFactory.getNativeWindow(target, null); return new X11OnscreenGLXDrawable(this, target); } - public void initializeVisualToGLCapabilitiesMap(int screen, - XVisualInfo[] infos, - GLCapabilities[] caps) { - Integer key = new Integer(screen); - if (!initializedScreenSet.contains(key)) { - for (int i = 0; i < infos.length; i++) { - if (caps[i] != null) { - visualToGLCapsMap.put(new ScreenAndVisualIDKey(screen, infos[i].visualid()), - caps[i].clone()); - } - } - initializedScreenSet.add(key); - } - } - - public GLCapabilities lookupCapabilitiesByScreenAndConfig(int screenIndex, - AbstractGraphicsConfiguration config) { - return (GLCapabilities) visualToGLCapsMap.get(new ScreenAndVisualIDKey(screenIndex, getVisualID(config))); - } - - public long getVisualID(AbstractGraphicsConfiguration config) { - if (config == null) { - return 0; - } - // FIXME: this is hopefully the last remaining place in this - // implementation that is over-specialized; third-party toolkits - // would need to use the X11GraphicsConfiguration in order to - // interoperate with this code - if (config instanceof X11GraphicsConfiguration) { - return ((X11GraphicsConfiguration) config).getVisualID(); - } - try { - // The AWT-specific code and casts have been moved to the X11SunJDKReflection helper class - return X11SunJDKReflection.graphicsConfigurationGetVisualID(config); - } catch (Throwable t) { - return 0; - } - } - public GLDrawableImpl createOffscreenDrawable(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) { - return new X11OffscreenGLXDrawable(this, capabilities, chooser, width, height); + AbstractGraphicsScreen screen = X11GraphicsScreen.createDefault(); + return new X11OffscreenGLXDrawable(this, screen, capabilities, chooser, width, height); } private boolean pbufferSupportInitialized = false; @@ -223,7 +141,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { final GLDrawableFactory factory = this; Runnable r = new Runnable() { public void run() { - X11PbufferGLXDrawable pbufferDrawable = new X11PbufferGLXDrawable(factory, capabilities, + AbstractGraphicsScreen screen = X11GraphicsScreen.createDefault(); + X11PbufferGLXDrawable pbufferDrawable = new X11PbufferGLXDrawable(factory, screen, capabilities, chooser, initialWidth, initialHeight); GLPbufferImpl pbuffer = new GLPbufferImpl(pbufferDrawable, shareWith); @@ -235,7 +154,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } public GLContext createExternalGLContext() { - return new X11ExternalGLXContext(); + AbstractGraphicsScreen screen = X11GraphicsScreen.createDefault(); + return new X11ExternalGLXContext(screen); } public boolean canCreateExternalGLDrawable() { @@ -243,7 +163,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } public GLDrawable createExternalGLDrawable() { - return X11ExternalGLXDrawable.create(this); + AbstractGraphicsScreen screen = X11GraphicsScreen.createDefault(); + return X11ExternalGLXDrawable.create(this, screen); } public void loadGLULibrary() { @@ -260,231 +181,6 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return res; } - public GLCapabilities xvi2GLCapabilities(long display, XVisualInfo info) { - int[] tmp = new int[1]; - int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0); - if (val == 0) { - // Visual does not support OpenGL - return null; - } - val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp, 0); - if (val == 0) { - // Visual does not support RGBA - return null; - } - GLCapabilities res = new GLCapabilities(); - 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 - // glXCreateContext, not by the XVisualInfo. Optimistically claim - // that all GLCapabilities have the capability to be hardware - // accelerated. - res.setHardwareAccelerated(true); - res.setDepthBits (glXGetConfig(display, info, GLX.GLX_DEPTH_SIZE, tmp, 0)); - res.setStencilBits (glXGetConfig(display, info, GLX.GLX_STENCIL_SIZE, tmp, 0)); - res.setRedBits (glXGetConfig(display, info, GLX.GLX_RED_SIZE, tmp, 0)); - res.setGreenBits (glXGetConfig(display, info, GLX.GLX_GREEN_SIZE, tmp, 0)); - res.setBlueBits (glXGetConfig(display, info, GLX.GLX_BLUE_SIZE, tmp, 0)); - res.setAlphaBits (glXGetConfig(display, info, GLX.GLX_ALPHA_SIZE, tmp, 0)); - res.setAccumRedBits (glXGetConfig(display, info, GLX.GLX_ACCUM_RED_SIZE, tmp, 0)); - res.setAccumGreenBits(glXGetConfig(display, info, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0)); - res.setAccumBlueBits (glXGetConfig(display, info, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0)); - res.setAccumAlphaBits(glXGetConfig(display, info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0)); - if (GLXUtil.isMultisampleAvailable()) { - res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0); - res.setNumSamples (glXGetConfig(display, info, GLX.GLX_SAMPLES, tmp, 0)); - } - return res; - } - - public static int[] glCapabilities2AttribList(GLCapabilities caps, - boolean isMultisampleAvailable, - boolean pbuffer, - long display, - int screen) { - int colorDepth = (caps.getRedBits() + - caps.getGreenBits() + - caps.getBlueBits()); - if (colorDepth < 15) { - throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported"); - } - int[] res = new int[MAX_ATTRIBS]; - int idx = 0; - if (pbuffer) { - res[idx++] = GLX.GLX_DRAWABLE_TYPE; - res[idx++] = GLX.GLX_PBUFFER_BIT; - - res[idx++] = GLX.GLX_RENDER_TYPE; - res[idx++] = GLX.GLX_RGBA_BIT; - } else { - res[idx++] = GLX.GLX_RGBA; - } - if (caps.getDoubleBuffered()) { - res[idx++] = GLX.GLX_DOUBLEBUFFER; - if (pbuffer) { - res[idx++] = GL.GL_TRUE; - } - } else { - if (pbuffer) { - res[idx++] = GLX.GLX_DOUBLEBUFFER; - res[idx++] = GL.GL_FALSE; - } - } - if (caps.getStereo()) { - res[idx++] = GLX.GLX_STEREO; - if (pbuffer) { - res[idx++] = GL.GL_TRUE; - } - } - // NOTE: don't set (GLX_STEREO, GL_FALSE) in "else" branch for - // pbuffer case to work around Mesa bug - - res[idx++] = GLX.GLX_RED_SIZE; - res[idx++] = caps.getRedBits(); - res[idx++] = GLX.GLX_GREEN_SIZE; - res[idx++] = caps.getGreenBits(); - res[idx++] = GLX.GLX_BLUE_SIZE; - res[idx++] = caps.getBlueBits(); - res[idx++] = GLX.GLX_ALPHA_SIZE; - res[idx++] = caps.getAlphaBits(); - res[idx++] = GLX.GLX_DEPTH_SIZE; - res[idx++] = caps.getDepthBits(); - if (caps.getStencilBits() > 0) { - res[idx++] = GLX.GLX_STENCIL_SIZE; - res[idx++] = caps.getStencilBits(); - } - if (caps.getAccumRedBits() > 0 || - caps.getAccumGreenBits() > 0 || - caps.getAccumBlueBits() > 0 || - caps.getAccumAlphaBits() > 0) { - res[idx++] = GLX.GLX_ACCUM_RED_SIZE; - res[idx++] = caps.getAccumRedBits(); - res[idx++] = GLX.GLX_ACCUM_GREEN_SIZE; - res[idx++] = caps.getAccumGreenBits(); - res[idx++] = GLX.GLX_ACCUM_BLUE_SIZE; - res[idx++] = caps.getAccumBlueBits(); - res[idx++] = GLX.GLX_ACCUM_ALPHA_SIZE; - res[idx++] = caps.getAccumAlphaBits(); - } - if (isMultisampleAvailable && caps.getSampleBuffers()) { - res[idx++] = GLX.GLX_SAMPLE_BUFFERS; - res[idx++] = GL.GL_TRUE; - res[idx++] = GLX.GLX_SAMPLES; - res[idx++] = caps.getNumSamples(); - } - if (pbuffer) { - if (caps.getPbufferFloatingPointBuffers()) { - String glXExtensions = GLX.glXQueryExtensionsString(display, screen); - if (glXExtensions == null || - glXExtensions.indexOf("GLX_NV_float_buffer") < 0) { - throw new GLException("Floating-point pbuffers on X11 currently require NVidia hardware"); - } - res[idx++] = GLXExt.GLX_FLOAT_COMPONENTS_NV; - res[idx++] = GL.GL_TRUE; - } - } - res[idx++] = 0; - return res; - } - - public static GLCapabilities attribList2GLCapabilities(int[] iattribs, - int niattribs, - int[] ivalues, - boolean pbuffer) { - GLCapabilities caps = new GLCapabilities(); - - for (int i = 0; i < niattribs; i++) { - int attr = iattribs[i]; - switch (attr) { - case GLX.GLX_DOUBLEBUFFER: - caps.setDoubleBuffered(ivalues[i] != GL.GL_FALSE); - break; - - case GLX.GLX_STEREO: - caps.setStereo(ivalues[i] != GL.GL_FALSE); - break; - - case GLX.GLX_RED_SIZE: - caps.setRedBits(ivalues[i]); - break; - - case GLX.GLX_GREEN_SIZE: - caps.setGreenBits(ivalues[i]); - break; - - case GLX.GLX_BLUE_SIZE: - caps.setBlueBits(ivalues[i]); - break; - - case GLX.GLX_ALPHA_SIZE: - caps.setAlphaBits(ivalues[i]); - break; - - case GLX.GLX_DEPTH_SIZE: - caps.setDepthBits(ivalues[i]); - break; - - case GLX.GLX_STENCIL_SIZE: - caps.setStencilBits(ivalues[i]); - break; - - case GLX.GLX_ACCUM_RED_SIZE: - caps.setAccumRedBits(ivalues[i]); - break; - - case GLX.GLX_ACCUM_GREEN_SIZE: - caps.setAccumGreenBits(ivalues[i]); - break; - - case GLX.GLX_ACCUM_BLUE_SIZE: - caps.setAccumBlueBits(ivalues[i]); - break; - - case GLX.GLX_ACCUM_ALPHA_SIZE: - caps.setAccumAlphaBits(ivalues[i]); - break; - - case GLX.GLX_SAMPLE_BUFFERS: - caps.setSampleBuffers(ivalues[i] != GL.GL_FALSE); - break; - - case GLX.GLX_SAMPLES: - caps.setNumSamples(ivalues[i]); - break; - - case GLXExt.GLX_FLOAT_COMPONENTS_NV: - caps.setPbufferFloatingPointBuffers(ivalues[i] != GL.GL_FALSE); - break; - - default: - break; - } - } - - return caps; - } - - private static String glXGetConfigErrorCode(int err) { - switch (err) { - case GLX.GLX_NO_EXTENSION: return "GLX_NO_EXTENSION"; - case GLX.GLX_BAD_SCREEN: return "GLX_BAD_SCREEN"; - case GLX.GLX_BAD_ATTRIBUTE: return "GLX_BAD_ATTRIBUTE"; - case GLX.GLX_BAD_VISUAL: return "GLX_BAD_VISUAL"; - default: return "Unknown error code " + err; - } - } - - public static int glXGetConfig(long display, XVisualInfo info, int attrib, int[] tmp, int tmp_offset) { - if (display == 0) { - throw new GLException("No display connection"); - } - int res = GLX.glXGetConfig(display, info, attrib, tmp, tmp_offset); - if (res != 0) { - throw new GLException("glXGetConfig failed: error code " + glXGetConfigErrorCode(res)); - } - return tmp[tmp_offset]; - } - private void maybeDoSingleThreadedWorkaround(Runnable action) { if (Threading.isSingleThreaded() && !Threading.isOpenGLThread()) { diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java new file mode 100644 index 000000000..5ff9b5368 --- /dev/null +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution 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. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package com.sun.opengl.impl.x11.glx; + +import java.util.*; +import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.*; +import javax.media.opengl.*; +import com.sun.opengl.impl.*; +import com.sun.gluegen.runtime.NativeLibrary; +import com.sun.nativewindow.impl.x11.*; + +public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implements Cloneable { + // Keep this under the same debug flag as the drawable factory for convenience + protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); + + public static final int MAX_ATTRIBS = 128; + private long fbConfig; + private int fbConfigID; + + public X11GLXGraphicsConfiguration(X11GraphicsScreen screen, GLCapabilities caps, XVisualInfo info, long fbcfg, int fbcfgID) { + super(screen, caps, info); + fbConfig = fbcfg; + fbConfigID = fbcfgID; + } + + public Object clone() { + return super.clone(); + } + + public long getFBConfig() { return fbConfig; } + public int getFBConfigID() { return fbConfigID; } + + public static int[] GLCapabilities2AttribList(GLCapabilities caps, + boolean forFBAttr, + boolean isMultisampleAvailable, + boolean usePBuffer, + long display, + int screen) + { + int colorDepth = (caps.getRedBits() + + caps.getGreenBits() + + caps.getBlueBits()); + if (colorDepth < 15) { + throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported"); + } + int[] res = new int[MAX_ATTRIBS]; + int idx = 0; + + if (forFBAttr) { + res[idx++] = GLX.GLX_DRAWABLE_TYPE; + res[idx++] = usePBuffer?GLX.GLX_PBUFFER_BIT:GLX.GLX_WINDOW_BIT; + } + + if (forFBAttr) { + res[idx++] = GLX.GLX_RENDER_TYPE; + res[idx++] = GLX.GLX_RGBA_BIT; + } else { + res[idx++] = GLX.GLX_RGBA; + } + + // FIXME: Still a bug is Mesa: PBUFFER && GLX_STEREO==GL_FALSE ? + if (forFBAttr) { + res[idx++] = GLX.GLX_DOUBLEBUFFER; + res[idx++] = caps.getDoubleBuffered()?GL.GL_TRUE:GL.GL_FALSE; + res[idx++] = GLX.GLX_STEREO; + res[idx++] = caps.getStereo()?GL.GL_TRUE:GL.GL_FALSE; + res[idx++] = GLX.GLX_TRANSPARENT_TYPE; + res[idx++] = caps.isBackgroundOpaque()?GLX.GLX_NONE:GLX.GLX_TRANSPARENT_RGB; + if(!caps.isBackgroundOpaque()) { + // FIXME - Add transparency values to Capabilities ! + res[idx++] = GLX.GLX_TRANSPARENT_RED_VALUE; + res[idx++] = 64; + res[idx++] = GLX.GLX_TRANSPARENT_GREEN_VALUE; + res[idx++] = 64; + res[idx++] = GLX.GLX_TRANSPARENT_BLUE_VALUE; + res[idx++] = 64; + res[idx++] = GLX.GLX_TRANSPARENT_ALPHA_VALUE; + res[idx++] = 64; + } + } else { + if (caps.getDoubleBuffered()) { + res[idx++] = GLX.GLX_DOUBLEBUFFER; + } + if (caps.getStereo()) { + res[idx++] = GLX.GLX_STEREO; + } + } + + res[idx++] = GLX.GLX_RED_SIZE; + res[idx++] = caps.getRedBits(); + res[idx++] = GLX.GLX_GREEN_SIZE; + res[idx++] = caps.getGreenBits(); + res[idx++] = GLX.GLX_BLUE_SIZE; + res[idx++] = caps.getBlueBits(); + res[idx++] = GLX.GLX_ALPHA_SIZE; + res[idx++] = caps.getAlphaBits(); + res[idx++] = GLX.GLX_DEPTH_SIZE; + res[idx++] = caps.getDepthBits(); + if (caps.getStencilBits() > 0) { + res[idx++] = GLX.GLX_STENCIL_SIZE; + res[idx++] = caps.getStencilBits(); + } + if (caps.getAccumRedBits() > 0 || + caps.getAccumGreenBits() > 0 || + caps.getAccumBlueBits() > 0 || + caps.getAccumAlphaBits() > 0) { + res[idx++] = GLX.GLX_ACCUM_RED_SIZE; + res[idx++] = caps.getAccumRedBits(); + res[idx++] = GLX.GLX_ACCUM_GREEN_SIZE; + res[idx++] = caps.getAccumGreenBits(); + res[idx++] = GLX.GLX_ACCUM_BLUE_SIZE; + res[idx++] = caps.getAccumBlueBits(); + res[idx++] = GLX.GLX_ACCUM_ALPHA_SIZE; + res[idx++] = caps.getAccumAlphaBits(); + } + if (isMultisampleAvailable && caps.getSampleBuffers()) { + res[idx++] = GLX.GLX_SAMPLE_BUFFERS; + res[idx++] = GL.GL_TRUE; + res[idx++] = GLX.GLX_SAMPLES; + res[idx++] = caps.getNumSamples(); + } + if (usePBuffer) { + if (caps.getPbufferFloatingPointBuffers()) { + String glXExtensions = GLX.glXQueryExtensionsString(display, screen); + if (glXExtensions == null || + glXExtensions.indexOf("GLX_NV_float_buffer") < 0) { + throw new GLException("Floating-point pbuffers on X11 currently require NVidia hardware"); + } + res[idx++] = GLXExt.GLX_FLOAT_COMPONENTS_NV; + res[idx++] = GL.GL_TRUE; + } + } + res[idx++] = 0; + return res; + } + + public static GLCapabilities AttribList2GLCapabilities(int[] iattribs, + int niattribs, + int[] ivalues, + boolean usePBuffer) { + GLCapabilities caps = new GLCapabilities(); + + for (int i = 0; i < niattribs; i++) { + int attr = iattribs[i]; + switch (attr) { + case GLX.GLX_DOUBLEBUFFER: + caps.setDoubleBuffered(ivalues[i] != GL.GL_FALSE); + break; + + case GLX.GLX_STEREO: + caps.setStereo(ivalues[i] != GL.GL_FALSE); + break; + + case GLX.GLX_RED_SIZE: + caps.setRedBits(ivalues[i]); + break; + + case GLX.GLX_GREEN_SIZE: + caps.setGreenBits(ivalues[i]); + break; + + case GLX.GLX_BLUE_SIZE: + caps.setBlueBits(ivalues[i]); + break; + + case GLX.GLX_ALPHA_SIZE: + caps.setAlphaBits(ivalues[i]); + break; + + case GLX.GLX_DEPTH_SIZE: + caps.setDepthBits(ivalues[i]); + break; + + case GLX.GLX_STENCIL_SIZE: + caps.setStencilBits(ivalues[i]); + break; + + case GLX.GLX_ACCUM_RED_SIZE: + caps.setAccumRedBits(ivalues[i]); + break; + + case GLX.GLX_ACCUM_GREEN_SIZE: + caps.setAccumGreenBits(ivalues[i]); + break; + + case GLX.GLX_ACCUM_BLUE_SIZE: + caps.setAccumBlueBits(ivalues[i]); + break; + + case GLX.GLX_ACCUM_ALPHA_SIZE: + caps.setAccumAlphaBits(ivalues[i]); + break; + + case GLX.GLX_SAMPLE_BUFFERS: + caps.setSampleBuffers(ivalues[i] != GL.GL_FALSE); + break; + + case GLX.GLX_SAMPLES: + caps.setNumSamples(ivalues[i]); + break; + + case GLX.GLX_CONFIG_CAVEAT: + caps.setHardwareAccelerated(ivalues[i] != GLX.GLX_SLOW_CONFIG); + break; + + case GLX.GLX_TRANSPARENT_TYPE: + caps.setBackgroundOpaque(ivalues[i] == GLX.GLX_NONE); + break; + + case GLXExt.GLX_FLOAT_COMPONENTS_NV: + caps.setPbufferFloatingPointBuffers(ivalues[i] != GL.GL_FALSE); + break; + + default: + break; + } + } + + return caps; + } + + // FBConfig + + public static GLCapabilities GLXFBConfig2GLCapabilities(long display, long fbcfg) { + int[] tmp = new int[1]; + int val; + val = glXGetFBConfig(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0); + if (val != GLX.GLX_RGBA_BIT) { + throw new GLException("Visual does not support RGBA"); + } + GLCapabilities res = new GLCapabilities(); + 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); + res.setDepthBits (glXGetFBConfig(display, fbcfg, GLX.GLX_DEPTH_SIZE, tmp, 0)); + res.setStencilBits (glXGetFBConfig(display, fbcfg, GLX.GLX_STENCIL_SIZE, tmp, 0)); + res.setRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_RED_SIZE, tmp, 0)); + res.setGreenBits (glXGetFBConfig(display, fbcfg, GLX.GLX_GREEN_SIZE, tmp, 0)); + res.setBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_BLUE_SIZE, tmp, 0)); + res.setAlphaBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ALPHA_SIZE, tmp, 0)); + res.setAccumRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_RED_SIZE, tmp, 0)); + res.setAccumGreenBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0)); + res.setAccumBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0)); + res.setAccumAlphaBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0)); + if (GLXUtil.isMultisampleAvailable()) { + res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0); + res.setNumSamples (glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLES, tmp, 0)); + } + res.setBackgroundOpaque(glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_TYPE, tmp, 0) == GLX.GLX_NONE); + try { + res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE); + } catch (Exception e) {} + return res; + } + + private static String glXGetFBConfigErrorCode(int err) { + switch (err) { + case GLX.GLX_NO_EXTENSION: return "GLX_NO_EXTENSION"; + case GLX.GLX_BAD_ATTRIBUTE: return "GLX_BAD_ATTRIBUTE"; + default: return "Unknown error code " + err; + } + } + + public static int glXGetFBConfig(long display, long cfg, int attrib, int[] tmp, int tmp_offset) { + if (display == 0) { + throw new GLException("No display connection"); + } + int res = GLX.glXGetFBConfigAttrib(display, cfg, attrib, tmp, tmp_offset); + if (res != 0) { + throw new GLException("glXGetFBConfig(0x"+Long.toHexString(attrib)+") failed: error code " + glXGetFBConfigErrorCode(res)); + } + return tmp[tmp_offset]; + } + + // Visual Info + + public static XVisualInfo XVisualID2XVisualInfo(long display, long visualID) { + XVisualInfo res = null; + NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); + try{ + int[] count = new int[1]; + XVisualInfo template = XVisualInfo.create(); + template.visualid(visualID); + XVisualInfo[] infos = X11Lib.XGetVisualInfoCopied(display, X11Lib.VisualIDMask, template, count, 0); + if (infos == null || infos.length == 0) { + return null; + } + res = XVisualInfo.create(infos[0]); + } finally { + NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); + } + if (DEBUG) { + System.err.println("!!! Fetched XVisualInfo for visual ID 0x" + Long.toHexString(visualID)); + System.err.println("!!! Resulting XVisualInfo: visualid = 0x" + Long.toHexString(res.visualid())); + } + return res; + } + + public static GLCapabilities XVisualInfo2GLCapabilities(long display, XVisualInfo info) { + int[] tmp = new int[1]; + int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0); + if (val == 0) { + throw new GLException("Visual does not support OpenGL"); + } + val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp, 0); + if (val == 0) { + throw new GLException("Visual does not support RGBA"); + } + GLCapabilities res = new GLCapabilities(); + 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 + // glXCreateContext, not by the XVisualInfo. Optimistically claim + // that all GLCapabilities have the capability to be hardware + // accelerated. + res.setHardwareAccelerated(true); + res.setDepthBits (glXGetConfig(display, info, GLX.GLX_DEPTH_SIZE, tmp, 0)); + res.setStencilBits (glXGetConfig(display, info, GLX.GLX_STENCIL_SIZE, tmp, 0)); + res.setRedBits (glXGetConfig(display, info, GLX.GLX_RED_SIZE, tmp, 0)); + res.setGreenBits (glXGetConfig(display, info, GLX.GLX_GREEN_SIZE, tmp, 0)); + res.setBlueBits (glXGetConfig(display, info, GLX.GLX_BLUE_SIZE, tmp, 0)); + res.setAlphaBits (glXGetConfig(display, info, GLX.GLX_ALPHA_SIZE, tmp, 0)); + res.setAccumRedBits (glXGetConfig(display, info, GLX.GLX_ACCUM_RED_SIZE, tmp, 0)); + res.setAccumGreenBits(glXGetConfig(display, info, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0)); + res.setAccumBlueBits (glXGetConfig(display, info, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0)); + res.setAccumAlphaBits(glXGetConfig(display, info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0)); + if (GLXUtil.isMultisampleAvailable()) { + res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0); + res.setNumSamples (glXGetConfig(display, info, GLX.GLX_SAMPLES, tmp, 0)); + } + return res; + } + + private static String glXGetConfigErrorCode(int err) { + switch (err) { + case GLX.GLX_NO_EXTENSION: return "GLX_NO_EXTENSION"; + case GLX.GLX_BAD_SCREEN: return "GLX_BAD_SCREEN"; + case GLX.GLX_BAD_ATTRIBUTE: return "GLX_BAD_ATTRIBUTE"; + case GLX.GLX_BAD_VISUAL: return "GLX_BAD_VISUAL"; + default: return "Unknown error code " + err; + } + } + + public static int glXGetConfig(long display, XVisualInfo info, int attrib, int[] tmp, int tmp_offset) { + if (display == 0) { + throw new GLException("No display connection"); + } + int res = GLX.glXGetConfig(display, info, attrib, tmp, tmp_offset); + if (res != 0) { + throw new GLException("glXGetConfig(0x"+Long.toHexString(attrib)+") failed: error code " + glXGetConfigErrorCode(res)); + } + return tmp[tmp_offset]; + } + + public String toString() { + return "X11GLXGraphicsConfiguration["+getScreen()+", visualID 0x" + Long.toHexString(getVisualID()) + ", fbConfigID 0x" + Long.toHexString(fbConfigID) + ", " + getCapabilities() +"]"; + } +} + diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java index 8120dca52..8def9be0a 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java @@ -33,9 +33,7 @@ package com.sun.opengl.impl.x11.glx; import javax.media.nativewindow.*; -import javax.media.nativewindow.x11.X11GraphicsDevice; -import javax.media.nativewindow.x11.X11GraphicsConfiguration; -import com.sun.nativewindow.impl.NullWindow; +import javax.media.nativewindow.x11.*; import com.sun.nativewindow.impl.NativeWindowFactoryImpl; import com.sun.nativewindow.impl.x11.*; @@ -49,8 +47,7 @@ import com.sun.opengl.impl.x11.glx.*; GraphicsDevice and GraphicsConfiguration abstractions. */ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFactory { - // Keep this under the same debug flag as the drawable factory for convenience - protected static final boolean DEBUG = Debug.debug("X11GLXDrawableFactory"); + protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); public X11GLXGraphicsConfigurationFactory() { GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, @@ -59,12 +56,72 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, CapabilitiesChooser chooser, - AbstractGraphicsDevice absDevice) { - if (absDevice != null && - !(absDevice instanceof X11GraphicsDevice)) { - throw new IllegalArgumentException("This NativeWindowFactory accepts only X11GraphicsDevice objects"); + AbstractGraphicsScreen absScreen) { + return chooseGraphicsConfigurationStatic(capabilities, chooser, absScreen, false); + } + + protected static X11GLXGraphicsConfiguration createDefaultGraphicsConfiguration(AbstractGraphicsScreen absScreen, boolean usePBuffer) { + if (absScreen == null) { + throw new IllegalArgumentException("AbstractGraphicsScreen is null"); + } + if (!(absScreen instanceof X11GraphicsScreen)) { + throw new IllegalArgumentException("Only X11GraphicsScreen are allowed here"); + } + X11GraphicsScreen x11Screen = (X11GraphicsScreen)absScreen; + + GLCapabilities caps=null; + XVisualInfo xvis=null; + long fbcfg = 0; + int fbid = -1; + + long display = x11Screen.getDevice().getHandle(); + int screen = x11Screen.getIndex(); + + // Utilizing FBConfig + // + NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); + try { + long visID = X11Lib.DefaultVisualID(display, x11Screen.getIndex()); + xvis = X11GLXGraphicsConfiguration.XVisualID2XVisualInfo(display, visID); + caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(display, xvis); + + int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(caps, true, GLXUtil.isMultisampleAvailable(), usePBuffer, 0, 0); + int[] count = { -1 }; + java.nio.LongBuffer fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0); + if (fbcfgsL == null || fbcfgsL.limit()<1) { + throw new Exception("Could not fetch FBConfig for "+caps); + } + fbcfg = fbcfgsL.get(0); + GLCapabilities capFB = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(display, fbcfg); + + int[] tmpID = new int[1]; + fbid = X11GLXGraphicsConfiguration.glXGetFBConfig(display, fbcfg, GLX.GLX_FBCONFIG_ID, tmpID, 0); + + xvis = GLX.glXGetVisualFromFBConfigCopied(display, fbcfg); + if (xvis==null) { + throw new GLException("Error: Choosen FBConfig has no visual"); + } + caps = capFB; + } catch (Throwable t) { + } finally { + NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); } + return new X11GLXGraphicsConfiguration(x11Screen, caps, xvis, fbcfg, fbid); + } + + protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationStatic(Capabilities capabilities, + CapabilitiesChooser chooser, + AbstractGraphicsScreen absScreen, boolean usePBuffer) { + if (absScreen == null) { + throw new IllegalArgumentException("AbstractGraphicsScreen is null"); + } + if (!(absScreen instanceof X11GraphicsScreen)) { + throw new IllegalArgumentException("Only X11GraphicsScreen are allowed here"); + } + X11GraphicsScreen x11Screen = (X11GraphicsScreen)absScreen; + + if (capabilities != null && !(capabilities instanceof GLCapabilities)) { throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects"); @@ -75,44 +132,123 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); } - int screen = 0; - if (absDevice != null) { - screen = ((X11GraphicsDevice) absDevice).getScreen(); + if (capabilities == null) { + capabilities = new GLCapabilities(); } - long visualID = chooseGraphicsConfigurationImpl((GLCapabilities) capabilities, - (GLCapabilitiesChooser) chooser, - screen); - return new X11GraphicsConfiguration(visualID); + + X11GLXGraphicsConfiguration res; + res = chooseGraphicsConfigurationFBConfig((GLCapabilities) capabilities, + (GLCapabilitiesChooser) chooser, + x11Screen, usePBuffer); + if(null==res) { + if(usePBuffer) { + throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig"); + } + res = chooseGraphicsConfigurationXVisual((GLCapabilities) capabilities, + (GLCapabilitiesChooser) chooser, + x11Screen); + } + if(null==res) { + throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration"); + } + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationStatic("+x11Screen+","+capabilities+", pbuffer "+usePBuffer+"): "+res); + } + return res; } - /** Returns the visual ID of the chosen GraphicsConfiguration. */ - protected long chooseGraphicsConfigurationImpl(GLCapabilities capabilities, - GLCapabilitiesChooser chooser, - int screen) { - if (capabilities == null) { - capabilities = new GLCapabilities(); + protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + X11GraphicsScreen x11Screen, + boolean usePBuffer) { + int screen = x11Screen.getIndex(); + AbstractGraphicsDevice absDevice = x11Screen.getDevice(); + long display = absDevice.getHandle(); + + int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, true, GLXUtil.isMultisampleAvailable(), usePBuffer, 0, 0); + int[] count = { -1 }; + int recommendedIndex = -1; + GLCapabilities[] caps = null; + java.nio.LongBuffer fbcfgsL = null; + int chosen=-1; + int retFBID=-1; + XVisualInfo retXVisualInfo = null; + + // Utilizing FBConfig + // + NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); + try { + fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0); + if (fbcfgsL == null || fbcfgsL.limit()<1) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: glXChooseFBConfig ("+x11Screen+","+capabilities+"): "+fbcfgsL+", "+count[0]); + } + return null; + } + recommendedIndex = 0; // 1st match is always recommended .. + caps = new GLCapabilities[fbcfgsL.limit()]; + for (int i = 0; i < fbcfgsL.limit(); i++) { + caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(display, fbcfgsL.get(i)); + } + + if(null==chooser) { + chosen = recommendedIndex; + } else { + try { + chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); + } catch (NativeWindowException e) { + throw new GLException(e); + } + } + + if (chosen < 0 || chosen >= caps.length) { + throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); + } + + int[] tmpID = new int[1]; + retFBID = X11GLXGraphicsConfiguration.glXGetFBConfig(display, fbcfgsL.get(chosen), GLX.GLX_FBCONFIG_ID, tmpID, 0); + + retXVisualInfo = GLX.glXGetVisualFromFBConfigCopied(display, fbcfgsL.get(chosen)); + if (retXVisualInfo==null) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: glXGetVisualFromFBConfig ("+x11Screen+", "+fbcfgsL.get(chosen) +": "+fbcfgsL); + } + return null; + } + } finally { + NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); } + + return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], retXVisualInfo, fbcfgsL.get(chosen), retFBID); + } + + protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + X11GraphicsScreen x11Screen) { + if (chooser == null) { chooser = new DefaultGLCapabilitiesChooser(); } - if (X11Util.isXineramaEnabled()) { - screen = 0; - } + int screen = x11Screen.getIndex(); + AbstractGraphicsDevice absDevice = x11Screen.getDevice(); + long display = absDevice.getHandle(); // 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 - int[] attribs = X11GLXDrawableFactory.glCapabilities2AttribList(capabilities, GLXUtil.isMultisampleAvailable(), false, 0, 0); + int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, false, GLXUtil.isMultisampleAvailable(), false, 0, 0); XVisualInfo[] infos = null; GLCapabilities[] caps = null; int recommendedIndex = -1; + XVisualInfo retXVisualInfo = null; + int chosen; + NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); try { - long display = X11Util.getDisplayConnection(); - XVisualInfo recommendedVis = GLX.glXChooseVisual(display, screen, attribs, 0); + XVisualInfo recommendedVis = GLX.glXChooseVisualCopied(display, screen, attribs, 0); if (DEBUG) { System.err.print("!!! glXChooseVisual recommended "); if (recommendedVis == null) { @@ -124,37 +260,34 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac int[] count = new int[1]; XVisualInfo template = XVisualInfo.create(); template.screen(screen); - infos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); - if (infos == null) { + infos = X11Lib.XGetVisualInfoCopied(display, X11Lib.VisualScreenMask, template, count, 0); + if (infos == null || infos.length<1) { throw new GLException("Error while enumerating available XVisualInfos"); } caps = new GLCapabilities[infos.length]; for (int i = 0; i < infos.length; i++) { - caps[i] = ((X11GLXDrawableFactory) GLDrawableFactory.getFactory()).xvi2GLCapabilities(display, infos[i]); + caps[i] = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(display, infos[i]); // Attempt to find the visual chosen by glXChooseVisual if (recommendedVis != null && recommendedVis.visualid() == infos[i].visualid()) { recommendedIndex = i; } } + try { + chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); + } catch (NativeWindowException e) { + throw new GLException(e); + } + if (chosen < 0 || chosen >= caps.length) { + throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); + } + if (infos[chosen] == null) { + throw new GLException("GLCapabilitiesChooser chose an invalid visual"); + } + retXVisualInfo = XVisualInfo.create(infos[chosen]); } finally { NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); } - // Store these away for later - ((X11GLXDrawableFactory) GLDrawableFactory.getFactory()). - initializeVisualToGLCapabilitiesMap(screen, infos, caps); - int chosen; - try { - chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); - } catch (NativeWindowException e) { - throw new GLException(e); - } - if (chosen < 0 || chosen >= caps.length) { - throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); - } - XVisualInfo vis = infos[chosen]; - if (vis == null) { - throw new GLException("GLCapabilitiesChooser chose an invalid visual"); - } - return vis.visualid(); + return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], retXVisualInfo, 0, -1); } } + diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java index 63dcca80e..69ecc34d2 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java @@ -49,12 +49,12 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { private long pixmap; private boolean isDoubleBuffered; - protected X11OffscreenGLXDrawable(GLDrawableFactory factory, - GLCapabilities requestedCapabilities, + protected X11OffscreenGLXDrawable(GLDrawableFactory factory, AbstractGraphicsScreen screen, + GLCapabilities caps, GLCapabilitiesChooser chooser, int width, int height) { - super(factory, new NullWindow(), true, requestedCapabilities, chooser); + super(factory, new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(caps, chooser, screen, false)), true); ((NullWindow) getNativeWindow()).setSize(width, height); create(); } @@ -65,17 +65,18 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { private void create() { NullWindow nw = (NullWindow) getNativeWindow(); - long dpy = X11Util.getDisplayConnection(); - nw.setDisplayHandle(dpy); - XVisualInfo vis = chooseVisual(false); + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) nw.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + XVisualInfo vis = config.getXVisualInfo(); int bitsPerPixel = vis.depth(); + AbstractGraphicsScreen aScreen = config.getScreen(); + AbstractGraphicsDevice aDevice = aScreen.getDevice(); + long dpy = aDevice.getHandle(); + int screen = aScreen.getIndex(); getFactoryImpl().lockToolkit(); try { - int screen = X11Lib.DefaultScreen(dpy); - nw.setScreenIndex(screen); pixmap = X11Lib.XCreatePixmap(dpy, (int) X11Lib.RootWindow(dpy, screen), - component.getWidth(), component.getHeight(), bitsPerPixel); + component.getWidth(), component.getHeight(), bitsPerPixel); if (pixmap == 0) { throw new GLException("XCreatePixmap failed"); } @@ -86,13 +87,12 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { throw new GLException("glXCreateGLXPixmap failed"); } nw.setSurfaceHandle(drawable); - isDoubleBuffered = (X11GLXDrawableFactory.glXGetConfig(dpy, vis, GLX.GLX_DOUBLEBUFFER, new int[1], 0) != 0); + isDoubleBuffered = (X11GLXGraphicsConfiguration.glXGetConfig(dpy, vis, GLX.GLX_DOUBLEBUFFER, new int[1], 0) != 0); if (DEBUG) { System.err.println("Created pixmap " + toHexString(pixmap) + ", GLXPixmap " + toHexString(drawable) + ", display " + toHexString(dpy)); } - setChosenGLCapabilities(((X11GLXDrawableFactory)getFactory()).xvi2GLCapabilities(dpy, vis)); } finally { getFactoryImpl().unlockToolkit(); } @@ -131,7 +131,6 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { drawable = 0; pixmap = 0; display = 0; - setChosenGLCapabilities(null); } finally { getFactoryImpl().unlockToolkit(); } diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OnscreenGLXContext.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OnscreenGLXContext.java index b4370e142..7113e8640 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OnscreenGLXContext.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OnscreenGLXContext.java @@ -61,12 +61,6 @@ public class X11OnscreenGLXContext extends X11GLXContext { protected int makeCurrentImpl() throws GLException { int lockRes = drawable.lockSurface(); - if (drawable.getChosenGLCapabilities() == null) { - X11GLXDrawableFactory factory = (X11GLXDrawableFactory) drawable.getFactory(); - NativeWindow window = drawable.getNativeWindow(); - drawable.setChosenGLCapabilities(factory.lookupCapabilitiesByScreenAndConfig(window.getScreenIndex(), - window.getGraphicsConfiguration())); - } boolean exceptionOccurred = false; try { if (lockRes == NativeWindow.LOCK_SURFACE_NOT_READY) { diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java index 4a22940b6..6a42a53c4 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java @@ -46,7 +46,7 @@ import com.sun.opengl.impl.x11.*; public class X11OnscreenGLXDrawable extends X11GLXDrawable { protected X11OnscreenGLXDrawable(GLDrawableFactory factory, NativeWindow component) { - super(factory, component, false, null, null); + super(factory, component, false); } public GLContext createContext(GLContext shareWith) { @@ -77,19 +77,4 @@ public class X11OnscreenGLXDrawable extends X11GLXDrawable { getFactoryImpl().unlockToolkit(); } } - - // This is public to allow access from the DrawableFactory - protected void setChosenGLCapabilities(GLCapabilities caps) { - super.setChosenGLCapabilities(caps); - } - - public void setRealized(boolean realized) { - if (realized) { - X11GLXDrawableFactory factory = (X11GLXDrawableFactory) getFactory(); - NativeWindow window = getNativeWindow(); - setChosenGLCapabilities(factory.lookupCapabilitiesByScreenAndConfig(window.getScreenIndex(), - window.getGraphicsConfiguration())); - } - super.setRealized(realized); - } } diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11PbufferGLXDrawable.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11PbufferGLXDrawable.java index 4ab31ddb0..f89a27365 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11PbufferGLXDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11PbufferGLXDrawable.java @@ -40,6 +40,7 @@ package com.sun.opengl.impl.x11.glx; import javax.media.opengl.*; +import javax.media.nativewindow.*; import com.sun.opengl.impl.*; import com.sun.opengl.impl.x11.glx.*; import com.sun.nativewindow.impl.NullWindow; @@ -54,10 +55,11 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { protected static final int MAX_PFORMATS = 256; protected static final int MAX_ATTRIBS = 256; - protected X11PbufferGLXDrawable(GLDrawableFactory factory, - GLCapabilities requestedCapabilities, + protected X11PbufferGLXDrawable(GLDrawableFactory factory, AbstractGraphicsScreen screen, + GLCapabilities caps, + GLCapabilitiesChooser chooser, int width, int height) { - super(factory, new NullWindow(), true, requestedCapabilities, null); + super(factory, new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(caps, chooser, screen, true)), true); if (width <= 0 || height <= 0) { throw new GLException("Width and height of pbuffer must be positive (were (" + width + ", " + height + "))"); @@ -66,13 +68,10 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { nw.setSize(width, height); if (DEBUG) { - System.out.println("Pbuffer caps on init: " + requestedCapabilities + - (requestedCapabilities.getPbufferRenderToTexture() ? " [rtt]" : "") + - (requestedCapabilities.getPbufferRenderToTextureRectangle() ? " [rect]" : "") + - (requestedCapabilities.getPbufferFloatingPointBuffers() ? " [float]" : "")); + caps = (GLCapabilities) getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration().getCapabilities(); + System.out.println("Pbuffer config: " + getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration()); } - nw.setDisplayHandle(X11Util.getDisplayConnection()); createPbuffer(); } @@ -86,9 +85,8 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { NullWindow nw = (NullWindow) getNativeWindow(); if (nw.getSurfaceHandle() != 0) { GLX.glXDestroyPbuffer(nw.getDisplayHandle(), nw.getSurfaceHandle()); - nw.setSurfaceHandle(0); } - nw.setDisplayHandle(0); + nw.invalidate(); } finally { getFactoryImpl().unlockToolkit(); } @@ -97,15 +95,19 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { private void createPbuffer() { getFactoryImpl().lockToolkit(); try { - NullWindow nw = (NullWindow) getNativeWindow(); - long display = nw.getDisplayHandle(); - if (nw.getDisplayHandle()== 0) { + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsScreen aScreen = config.getScreen(); + AbstractGraphicsDevice aDevice = aScreen.getDevice(); + long display = aDevice.getHandle(); + int screen = aScreen.getIndex(); + + if (display==0) { throw new GLException("Null display"); } - int screen = X11Lib.DefaultScreen(display); - nw.setScreenIndex(screen); + + NullWindow nw = (NullWindow) getNativeWindow(); - GLCapabilities capabilities = getRequestedGLCapabilities(); + GLCapabilities capabilities = (GLCapabilities)config.getCapabilities(); if (capabilities.getPbufferRenderToTexture()) { throw new GLException("Render-to-texture pbuffers not supported yet on X11"); @@ -115,47 +117,16 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { throw new GLException("Render-to-texture-rectangle pbuffers not supported yet on X11"); } - int[] iattributes = X11GLXDrawableFactory.glCapabilities2AttribList(capabilities, - GLXUtil.isMultisampleAvailable(), - true, display, screen); - - int[] nelementsTmp = new int[1]; - // FIXME: we inherently leak the memory from the underlying call - // to glXChooseFBConfig because a copy of the original Buffer is - // made to expand each pointer from 32 to 64 bits - LongBuffer fbConfigs = GLX.glXChooseFBConfig(display, screen, iattributes, 0, nelementsTmp, 0); - if (fbConfigs == null || fbConfigs.limit() == 0 || fbConfigs.get(0) == 0) { - throw new GLException("pbuffer creation error: glXChooseFBConfig() failed"); - } - int nelements = nelementsTmp[0]; - if (nelements <= 0) { - throw new GLException("pbuffer creation error: couldn't find a suitable frame buffer configuration"); - } - // Note that we currently don't allow selection of anything but - // the first GLXFBConfig in the returned list - long fbConfig = fbConfigs.get(0); - - if (DEBUG) { - System.err.println("Found " + fbConfigs.limit() + " matching GLXFBConfigs"); - System.err.println("Parameters of default one:"); - System.err.println("render type: 0x" + Integer.toHexString(queryFBConfig(display, fbConfig, GLX.GLX_RENDER_TYPE))); - System.err.println("rgba: " + ((queryFBConfig(display, fbConfig, GLX.GLX_RENDER_TYPE) & GLX.GLX_RGBA_BIT) != 0)); - System.err.println("r: " + queryFBConfig(display, fbConfig, GLX.GLX_RED_SIZE)); - System.err.println("g: " + queryFBConfig(display, fbConfig, GLX.GLX_GREEN_SIZE)); - System.err.println("b: " + queryFBConfig(display, fbConfig, GLX.GLX_BLUE_SIZE)); - System.err.println("a: " + queryFBConfig(display, fbConfig, GLX.GLX_ALPHA_SIZE)); - System.err.println("depth: " + queryFBConfig(display, fbConfig, GLX.GLX_DEPTH_SIZE)); - System.err.println("double buffered: " + queryFBConfig(display, fbConfig, GLX.GLX_DOUBLEBUFFER)); - } + fbConfig = config.getFBConfig(); // Create the p-buffer. int niattribs = 0; + int[] iattributes = new int[5]; iattributes[niattribs++] = GLX.GLX_PBUFFER_WIDTH; iattributes[niattribs++] = nw.getWidth(); iattributes[niattribs++] = GLX.GLX_PBUFFER_HEIGHT; iattributes[niattribs++] = nw.getHeight(); - iattributes[niattribs++] = 0; long drawable = GLX.glXCreatePbuffer(display, fbConfig, iattributes, 0); @@ -166,36 +137,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { // Set up instance variables nw.setSurfaceHandle(drawable); - this.fbConfig = fbConfig; - // Pick innocent query values if multisampling or floating point buffers not available - int sbAttrib = GLXUtil.isMultisampleAvailable() ? GLX.GLX_SAMPLE_BUFFERS: GLX.GLX_RED_SIZE; - int samplesAttrib = GLXUtil.isMultisampleAvailable() ? GLX.GLX_SAMPLES: GLX.GLX_RED_SIZE; - int floatNV = capabilities.getPbufferFloatingPointBuffers() ? GLXExt.GLX_FLOAT_COMPONENTS_NV : GLX.GLX_RED_SIZE; - - // Query the fbconfig to determine its GLCapabilities - int[] iattribs = { - GLX.GLX_DOUBLEBUFFER, - GLX.GLX_STEREO, - GLX.GLX_RED_SIZE, - GLX.GLX_GREEN_SIZE, - GLX.GLX_BLUE_SIZE, - GLX.GLX_ALPHA_SIZE, - GLX.GLX_DEPTH_SIZE, - GLX.GLX_STENCIL_SIZE, - GLX.GLX_ACCUM_RED_SIZE, - GLX.GLX_ACCUM_GREEN_SIZE, - GLX.GLX_ACCUM_BLUE_SIZE, - GLX.GLX_ACCUM_ALPHA_SIZE, - sbAttrib, - samplesAttrib, - floatNV - }; - - int[] ivalues = new int[iattribs.length]; - queryFBConfig(display, fbConfig, iattribs, iattribs.length, ivalues); - setChosenGLCapabilities(X11GLXDrawableFactory.attribList2GLCapabilities(iattribs, iattribs.length, ivalues, true)); - // Determine the actual width and height we were able to create. int[] tmp = new int[1]; GLX.glXQueryDrawable(display, drawable, GLX.GLX_WIDTH, tmp, 0); @@ -221,21 +163,4 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { return fbConfig; } - private int queryFBConfig(long display, long fbConfig, int attrib) { - int[] tmp = new int[1]; - if (GLX.glXGetFBConfigAttrib(display, fbConfig, attrib, tmp, 0) != 0) { - throw new GLException("glXGetFBConfigAttrib failed"); - } - return tmp[0]; - } - - private void queryFBConfig(long display, long fbConfig, int[] attribs, int nattribs, int[] values) { - int[] tmp = new int[1]; - for (int i = 0; i < nattribs; i++) { - if (GLX.glXGetFBConfigAttrib(display, fbConfig, attribs[i], tmp, 0) != 0) { - throw new GLException("glXGetFBConfigAttrib failed"); - } - values[i] = tmp[0]; - } - } } diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java index 0d75056c4..08ae19e17 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java @@ -36,20 +36,21 @@ import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import javax.media.nativewindow.*; -import javax.media.nativewindow.x11.X11GraphicsConfiguration; -import javax.media.nativewindow.x11.X11GraphicsDevice; -import javax.media.nativewindow.awt.AWTGraphicsConfiguration; -import javax.media.nativewindow.awt.AWTGraphicsDevice; +import javax.media.nativewindow.x11.*; +import javax.media.nativewindow.awt.*; import javax.media.opengl.*; import javax.media.opengl.awt.*; import com.sun.opengl.impl.*; import com.sun.nativewindow.impl.jawt.*; import com.sun.nativewindow.impl.jawt.x11.*; +import com.sun.nativewindow.impl.x11.*; import com.sun.opengl.impl.x11.*; import com.sun.opengl.impl.x11.glx.*; public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfigurationFactory { + protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); + public X11AWTGLXGraphicsConfigurationFactory() { GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, this); @@ -57,19 +58,18 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfiguration public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, CapabilitiesChooser chooser, - AbstractGraphicsDevice absDevice) { + AbstractGraphicsScreen absScreen) { GraphicsDevice device = null; - if (absDevice != null && - !(absDevice instanceof AWTGraphicsDevice)) { - throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only AWTGraphicsDevice objects"); + if (absScreen != null && + !(absScreen instanceof AWTGraphicsScreen)) { + throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only AWTGraphicsScreen objects"); } - if ((absDevice == null) || - (((AWTGraphicsDevice) absDevice).getGraphicsDevice() == null)) { - device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); - } else { - device = ((AWTGraphicsDevice) absDevice).getGraphicsDevice(); + if(null==absScreen) { + absScreen = AWTGraphicsScreen.createScreenDevice(-1); } + AWTGraphicsScreen awtScreen = (AWTGraphicsScreen) absScreen; + device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice(); if (capabilities != null && !(capabilities instanceof GLCapabilities)) { @@ -81,15 +81,35 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfiguration throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilitiesChooser objects"); } - // Fabricate an X11GraphicsDevice and delegate to the GraphicsConfigurationFactory for those - // - // Note that we could derive from X11GLXGraphicsConfigurationFactory, but that would - // limit the ability of third parties to plug in new visual selection algorithms - X11GraphicsDevice x11Device = new X11GraphicsDevice(X11SunJDKReflection.graphicsDeviceGetScreen(device)); + if(DEBUG) { + Exception e = new Exception("X11AWTGLXGraphicsConfigurationFactory: got "+absScreen); + e.printStackTrace(); + } + long displayHandle = 0; + NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); + try { + displayHandle = X11SunJDKReflection.graphicsDeviceGetScreen(device); + if(0==displayHandle) { + displayHandle = X11Util.getDefaultDisplay(); + ((AWTGraphicsDevice)awtScreen.getDevice()).setHandle(displayHandle); + if(DEBUG) { + System.err.println("X11AWTGLXGraphicsConfigurationFactory: using default X11 display"); + } + } + } catch (Throwable t) { + } finally { + NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); + } + X11GraphicsDevice x11Device = new X11GraphicsDevice(displayHandle); + X11GraphicsScreen x11Screen = new X11GraphicsScreen(x11Device, awtScreen.getIndex()); + if(DEBUG) { + System.err.println("X11AWTGLXGraphicsConfigurationFactory: made "+x11Screen); + } + X11GraphicsConfiguration x11Config = (X11GraphicsConfiguration) GraphicsConfigurationFactory.getFactory(x11Device).chooseGraphicsConfiguration(capabilities, chooser, - x11Device); + x11Screen); if (x11Config != null) { long visualID = x11Config.getVisualID(); // Now figure out which GraphicsConfiguration corresponds to this @@ -99,7 +119,7 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfiguration GraphicsConfiguration config = configs[i]; if (config != null) { if (X11SunJDKReflection.graphicsConfigurationGetVisualID(config) == visualID) { - return new AWTGraphicsConfiguration(config); + return new AWTGraphicsConfiguration(awtScreen, x11Config.getCapabilities(), config, x11Config); } } } diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java index 9d88bae58..dcbd3e4cf 100644 --- a/src/jogl/classes/javax/media/opengl/GLBase.java +++ b/src/jogl/classes/javax/media/opengl/GLBase.java @@ -20,7 +20,15 @@ public interface GLBase { public boolean isGL(); /** + * Indicates whether this GL object conforms to the GL3 profile. + * The GL3 profile reflects OpenGL versions greater or equal 3.1 + * @return whether this GL object conforms to the GL3 profile + */ + public boolean isGL3(); + + /** * Indicates whether this GL object conforms to the GL2 profile. + * The GL2 profile reflects OpenGL versions greater or equal 1.5 * @return whether this GL object conforms to the GL2 profile */ public boolean isGL2(); @@ -38,19 +46,19 @@ public interface GLBase { public boolean isGLES2(); /** - * Indicates whether this GL object conforms to one of the OpenGL ES profiles. + * Indicates whether this GL object conforms to one of the OpenGL ES compatible profiles. * @return whether this GL object conforms to one of the OpenGL ES profiles */ public boolean isGLES(); /** - * Indicates whether this GL object conforms to the GL2ES1 profile. + * Indicates whether this GL object conforms to the GL2ES1 compatible profile. * @return whether this GL object conforms to the GL2ES1 profile */ public boolean isGL2ES1(); /** - * Indicates whether this GL object conforms to the GL2ES2 profile. + * Indicates whether this GL object conforms to the GL2ES2 compatible profile. * @return whether this GL object conforms to the GL2ES2 profile */ public boolean isGL2ES2(); @@ -63,6 +71,13 @@ public interface GLBase { public GL getGL() throws GLException; /** + * Casts this object to the GL3 interface. + * @return this object cast to the GL3 interface + * @throws GLException if this GLObject is not a GL3 implementation + */ + public GL3 getGL3() throws GLException; + + /** * Casts this object to the GL2 interface. * @return this object cast to the GL2 interface * @throws GLException if this GLObject is not a GL2 implementation diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilities.java b/src/jogl/classes/javax/media/opengl/GLCapabilities.java index 35b04d5f6..0a73856c0 100644 --- a/src/jogl/classes/javax/media/opengl/GLCapabilities.java +++ b/src/jogl/classes/javax/media/opengl/GLCapabilities.java @@ -288,23 +288,23 @@ public class GLCapabilities extends Capabilities implements Cloneable { /** Returns a textual representation of this GLCapabilities object. */ public String toString() { - return ("GLCapabilities [" + - "DoubleBuffered: " + doubleBuffered + + return getClass().toString()+"[" + + super.toString()+ + ", DoubleBuffered: " + doubleBuffered + ", Stereo: " + stereo + - ", HardwareAccelerated: " + hardwareAccelerated + + ", HardwareAccelerated: " + hardwareAccelerated + ", DepthBits: " + depthBits + ", StencilBits: " + stencilBits + - ", Red: " + getRedBits() + - ", Green: " + getGreenBits() + - ", Blue: " + getBlueBits() + - ", Alpha: " + getAlphaBits() + ", Red Accum: " + accumRedBits + ", Green Accum: " + accumGreenBits + ", Blue Accum: " + accumBlueBits + ", Alpha Accum: " + accumAlphaBits + - ", Multisample: " + sampleBuffers + - (sampleBuffers ? ", Num samples: " + numSamples : "") + - ", Opaque: " + backgroundOpaque + - " ]"); + ", Multisample: " + sampleBuffers + + ", Num samples: "+(sampleBuffers ? numSamples : 0) + + ", Opaque: " + backgroundOpaque + + ", PBuffer-FloatingPointBuffers: "+pbufferFloatingPointBuffers+ + ", PBuffer-RenderToTexture: "+pbufferRenderToTexture+ + ", PBuffer-RenderToTextureRectangle: "+pbufferRenderToTextureRectangle+ + " ]"; } } diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java index 8c3ca9c5b..c7e5899a7 100644 --- a/src/jogl/classes/javax/media/opengl/GLContext.java +++ b/src/jogl/classes/javax/media/opengl/GLContext.java @@ -56,7 +56,7 @@ import java.util.HashMap; refer to a given context. */ public abstract class GLContext { - protected static final boolean DEBUG = Debug.debug("GLContext"); + protected static final boolean DEBUG = Debug.isPropertyDefined("jogl.debug.GLContext"); // Debug.debug("GLContext"); /** Indicates that the context was not made current during the last call to {@link #makeCurrent makeCurrent}. */ public static final int CONTEXT_NOT_CURRENT = 0; diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java index 7e46b822c..e9208f49e 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java @@ -93,18 +93,18 @@ public abstract class GLDrawableFactory { public static GLDrawableFactory getFactory() throws GLException { if (null == factory) { if (null == GLProfile.getProfile()) { - throw new GLException("GLProfile was not properly initialized"); + GLProfile.setProfileGLAny(); // do it now .. last resort } // See if the user is requesting one of the embedded profiles, // and if so, try to instantiate the EGLDrawableFactory - if (GLProfile.isGLES()) { + if ( GLProfile.usesNativeGLES() ) { try { factory = (GLDrawableFactory) NWReflection.createInstance("com.sun.opengl.impl.egl.EGLDrawableFactory"); } catch (Exception e) { e.printStackTrace(); } - } else if (!GLProfile.isGL2ES1() && !GLProfile.isGL2ES2()) { + } else if ( !GLProfile.isGL2ES1() && !GLProfile.isGL2ES2() ) { // We require that the user passes in one of the known profiles throw new GLException("Unknown or unsupported profile \"" + GLProfile.getProfile() + "\""); } @@ -154,7 +154,9 @@ public abstract class GLDrawableFactory { /** * Returns a GLDrawable that wraps a platform-specific window system - * object, such as an AWT or LCDUI Canvas. On platforms which + * object, such as an AWT or LCDUI Canvas. + * On platforms which support pixel format, the NativeWindow's AbstractGraphicsConfiguration + * is being used. * support it, selects a pixel format compatible with the supplied * GLCapabilities, or if the passed GLCapabilities object is null, * uses a default set of capabilities. On these platforms, uses @@ -165,10 +167,10 @@ public abstract class GLDrawableFactory { * @throws IllegalArgumentException if the passed target is null * @throws GLException if any window system-specific errors caused * the creation of the GLDrawable to fail. + * + * @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen) */ - public abstract GLDrawable createGLDrawable(NativeWindow target, - GLCapabilities capabilities, - GLCapabilitiesChooser chooser) + public abstract GLDrawable createGLDrawable(NativeWindow target) throws IllegalArgumentException, GLException; //---------------------------------------------------------------------- diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java index 8c5d8a3bf..bf0f5bbb5 100644 --- a/src/jogl/classes/javax/media/opengl/GLProfile.java +++ b/src/jogl/classes/javax/media/opengl/GLProfile.java @@ -43,10 +43,15 @@ import com.sun.opengl.impl.*; import com.sun.nativewindow.impl.NWReflection; public class GLProfile { + public static final boolean DEBUG = Debug.debug("GLProfile"); + // // Public (user-visible) profiles // + /** The desktop (OpenGL 3.1) profile */ + public static final String GL3 = "GL3"; + /** The desktop (OpenGL 2.0) profile */ public static final String GL2 = "GL2"; @@ -79,28 +84,30 @@ public class GLProfile { private static final Throwable tryLibrary() { + String clazzName = getGLImplBaseClassName() + "Impl" ; try { - Class clazz = Class.forName(getGLImplBaseClassName()+"Impl"); - if(GL2.equals(realProfile)) { + Class clazz = Class.forName(clazzName); + if(GL3.equals(realProfile) || GL2.equals(realProfile)) { // See DRIHack.java for an explanation of why this is necessary DRIHack.begin(); - NativeLibLoader.loadGL2(); + NativeLibLoader.loadGLDesktop(); DRIHack.end(); } if(GL2ES12.equals(realProfile)) { // See DRIHack.java for an explanation of why this is necessary DRIHack.begin(); NativeLibLoader.loadGL2ES12(); DRIHack.end(); - } else if(GLES1.equals(realProfile) || GLES2.equals(realProfile)) { + } else if(usesNativeGLES()) { Object eGLDrawableFactory = NWReflection.createInstance("com.sun.opengl.impl.egl.EGLDrawableFactory"); if(null==eGLDrawableFactory) { throw new GLException("com.sun.opengl.impl.egl.EGLDrawableFactory not available"); } } - System.out.println("Successfully loaded profile " + profile); + System.out.println("Successfully loaded profile " + profile + " ("+realProfile+"/"+clazzName+")"); return null; } catch (Throwable e) { - if (Debug.debug("GLProfile")) { + if (DEBUG) { + System.err.println("GLProfile.tryLibrary: failed: " + profile + " ("+realProfile+"/"+clazzName+")"); e.printStackTrace(); } profile=null; @@ -109,13 +116,26 @@ public class GLProfile { } } - private static void computeRealProfile() { + private static boolean hasGL2ES12Impl = null!=NWReflection.getClass("com.sun.opengl.impl.gl2es12.GL2ES12Impl"); + private static boolean hasGL2Impl = null!=NWReflection.getClass("com.sun.opengl.impl.gl2.GL2Impl"); + + private static String computeRealProfile() { if (GL2ES1.equals(profile) || GL2ES2.equals(profile)) { - realProfile = GL2ES12; - } else { - realProfile = profile; + if(hasGL2Impl) { + realProfile = GL2; + return realProfile; + } else if(hasGL2ES12Impl) { + realProfile = GL2ES12; + return realProfile; + } } + realProfile = profile; + return realProfile; + } + + private static final void initStatics() { + GLDrawableFactory.getFactory(); } public static synchronized final void setProfile(String profile) @@ -123,11 +143,12 @@ public class GLProfile { { if(null==GLProfile.profile) { GLProfile.profile = profile; - computeRealProfile(); + String rp = computeRealProfile(); Throwable t = tryLibrary(); if (GLProfile.profile == null) { - throw new GLException("Profile " + profile + " not available", t); + throw new GLException("Profile " + profile + " ("+rp+") not available", t); } + initStatics(); } else { if(!GLProfile.profile.equals(profile)) { throw new GLException("Requested profile ("+profile+") doesn't match already chosen one: "+GLProfile.profile); @@ -159,6 +180,7 @@ public class GLProfile { msg.append("]"); throw new GLException("Profiles "+msg.toString()+" not available", t); } + initStatics(); } /** @@ -171,24 +193,28 @@ public class GLProfile { /** * Selects a profile, implementing the interface GL2ES2. - * Order: GL2ES2, GL2, GLES2 + * Order: GL2ES2, GL2, GL3, GLES2 */ public static synchronized final void setProfileGL2ES2() { - setProfile(new String[] { GL2ES2, GL2, GLES2 }); + setProfile(new String[] { GL2ES2, GL2, /*GL3,*/ GLES2 }); } /** * Selects a profile, implementing the interface GL - * Order: GL2, GL2ES2, GL2ES1, GLES2, GLES1 + * Order: GL2, GL2ES2, GL2ES1, GL3, GLES2, GLES1 */ public static synchronized final void setProfileGLAny() { - setProfile(new String[] { GL2, GL2ES2, GL2ES1, GLES2, GLES1 }); + setProfile(new String[] { GL2, GL2ES2, GL2ES1, /*GL3,*/ GLES2, GLES1 }); } public static final String getProfile() { return profile; } + public static final boolean isGL3() { + return GL3.equals(profile); + } + public static final boolean isGL2() { return GL2.equals(profile); } @@ -208,17 +234,31 @@ public class GLProfile { /* Indicates whether a GL2ES2 capable profile is in use, ie GL2ES2, GL2, GLES2 */ public static final boolean isGL2ES2() { - return GL2ES2.equals(profile) || isGL2() || isGLES2() ; + return GL2ES2.equals(profile) || isGL2() || isGL3() || isGLES2() ; } - /** Indicates whether either of the OpenGL ES profiles are in use. */ - public static final boolean isGLES() { - return isGLES2() || isGLES1(); + /** Indicates whether the native OpenGL ES1 profile is in use. + * This requires an EGL interface. + */ + public static final boolean usesNativeGLES1() { + return GLES1.equals(realProfile) || GL2ES1.equals(realProfile) ; + } + + /** Indicates whether the native OpenGL ES2 profile is in use. + * This requires an EGL interface. + */ + public static final boolean usesNativeGLES2() { + return GLES2.equals(realProfile) || GL2ES2.equals(realProfile) ; + } + + /** Indicates whether either of the native OpenGL ES profiles are in use. */ + public static final boolean usesNativeGLES() { + return usesNativeGLES2() || usesNativeGLES1(); } /** Indicates whether a GLSL capable profiles is in use. */ public static final boolean hasGLSL() { - return isGL2ES2(); + return isGL2ES2() ; } public static final boolean matches(String test_profile) { @@ -226,13 +266,15 @@ public class GLProfile { } public static final String getGLImplBaseClassName() { - if(isGL2()) { + if(GL3.equals(realProfile)) { + return "com.sun.opengl.impl.gl3.GL3"; + } else if(GL2.equals(realProfile)) { return "com.sun.opengl.impl.gl2.GL2"; - } else if(isGL2ES1() || isGL2ES2()) { + } else if(GL2ES12.equals(realProfile)) { return "com.sun.opengl.impl.gl2es12.GL2ES12"; - } else if(isGLES1()) { + } else if(GLES1.equals(realProfile) || GL2ES1.equals(realProfile)) { return "com.sun.opengl.impl.es1.GLES1"; - } else if(isGLES2()) { + } else if(GLES2.equals(realProfile) || GL2ES2.equals(realProfile)) { return "com.sun.opengl.impl.es2.GLES2"; } else { throw new GLException("unsupported profile \"" + profile + "\""); @@ -302,6 +344,9 @@ public class GLProfile { return true; } case javax.media.opengl.GL2.GL_DOUBLE: + if( isGL3() ) { + return true; + } case javax.media.opengl.GL2.GL_2_BYTES: case javax.media.opengl.GL2.GL_3_BYTES: case javax.media.opengl.GL2.GL_4_BYTES: @@ -431,7 +476,7 @@ public class GLProfile { } return false; } - } else if(GLProfile.isGL2ES2() || GLProfile.isGL2()) { + } else if( GLProfile.isGL2ES2() ) { if(isVertexAttribPointer) { switch(type) { case GL.GL_UNSIGNED_BYTE: diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index 232299594..727d06b61 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -41,8 +41,7 @@ package javax.media.opengl.awt; import javax.media.opengl.*; import javax.media.nativewindow.*; -import javax.media.nativewindow.awt.AWTGraphicsDevice; -import javax.media.nativewindow.awt.AWTGraphicsConfiguration; +import javax.media.nativewindow.awt.*; import com.sun.opengl.impl.*; @@ -127,15 +126,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { GLCapabilitiesChooser chooser, GLContext shareWith, GraphicsDevice device) { - // The platform-specific GLDrawableFactory will only provide a - // non-null GraphicsConfiguration on platforms where this is - // necessary (currently only X11, as Windows allows the pixel - // format of the window to be set later and Mac OS X seems to - // handle this very differently than all other platforms). On - // other platforms this method returns null; it is the case (at - // least in the Sun AWT implementation) that this will result in - // equivalent behavior to calling the no-arg super() constructor - // for Canvas. /* * Workaround for Xinerama, always pass null so we can detect whether * super.getGraphicsConfiguration() is returning the Canvas' GC (null), @@ -146,22 +136,34 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { /* * Save the chosen capabilities for use in getGraphicsConfiguration(). */ - chosen = chooseGraphicsConfiguration(capabilities, chooser, device); - if (chosen != null) { + AWTGraphicsConfiguration config = chooseGraphicsConfiguration(capabilities, chooser, device); + if(DEBUG) { + Exception e = new Exception("Created Config: "+config); + e.printStackTrace(); + } + if(null!=config) { + // update .. + chosen = config.getGraphicsConfiguration(); + /* * If we are running on a platform that * must select a GraphicsConfiguration now, * save these for later use in getGraphicsConfiguration(). */ this.glCapChooser = chooser; - this.glCaps = capabilities; + this.glCaps = (GLCapabilities)config.getCapabilities(); } if (!Beans.isDesignTime()) { - drawable = GLDrawableFactory.getFactory().createGLDrawable(NativeWindowFactory.getFactory(getClass()).getNativeWindow(this), - capabilities, chooser); + if(null==config) { + throw new GLException("Error: AWTGraphicsConfiguration is null"); + } + drawable = GLDrawableFactory.getFactory().createGLDrawable(NativeWindowFactory.getNativeWindow(this, config)); context = (GLContextImpl) drawable.createContext(shareWith); context.setSynchronized(true); } + if(DEBUG) { + System.err.println("Created Drawable: "+drawable); + } } protected interface DestroyMethod { @@ -243,7 +245,8 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { * block, both devices should have the same visual list, and the * same configuration should be selected here. */ - final GraphicsConfiguration compatible = chooseGraphicsConfiguration(glCaps, glCapChooser, gc.getDevice()); + AWTGraphicsConfiguration config = chooseGraphicsConfiguration(glCaps, glCapChooser, gc.getDevice()); + final GraphicsConfiguration compatible = (null!=config)?config.getGraphicsConfiguration():null; if (compatible != null) { /* @@ -352,6 +355,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { super.addNotify(); if (!Beans.isDesignTime()) { disableBackgroundErase(); + drawable.setRealized(true); } } @@ -609,23 +613,23 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } } - private static GraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities, - GLCapabilitiesChooser chooser, - GraphicsDevice device) { + private static AWTGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + GraphicsDevice device) { // Make GLCanvas behave better in NetBeans GUI builder if (Beans.isDesignTime()) { return null; } - AWTGraphicsDevice awtDevice = new AWTGraphicsDevice(device); + AbstractGraphicsScreen aScreen = AWTGraphicsScreen.createScreenDevice(device); AWTGraphicsConfiguration config = (AWTGraphicsConfiguration) - GraphicsConfigurationFactory.getFactory(awtDevice).chooseGraphicsConfiguration(capabilities, - chooser, - awtDevice); + GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capabilities, + chooser, + aScreen); if (config == null) { - return null; + throw new GLException("Error: Couldn't fetch AWTGraphicsConfiguration"); } - return config.getGraphicsConfiguration(); + return config; } } diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index 86668373d..bf4176a08 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -41,6 +41,7 @@ package javax.media.opengl.awt; import javax.media.opengl.*; import javax.media.nativewindow.*; +import javax.media.nativewindow.awt.*; import java.awt.*; import java.awt.geom.*; @@ -142,8 +143,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { if (Java2D.isOGLPipelineActive() && Java2D.isFBOEnabled()) { Java2D.getShareContext(GraphicsEnvironment. getLocalGraphicsEnvironment(). - getDefaultScreenDevice(). - getDefaultConfiguration()); + getDefaultScreenDevice()); } GLProfile.setProfile(GLProfile.GL2); factory = GLDrawableFactoryImpl.getFactoryImpl(); |