diff options
author | Sven Gothel <[email protected]> | 2009-05-29 01:47:02 +0000 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2009-05-29 01:47:02 +0000 |
commit | 4c32ea23370336b99eba4c1ebd1f07c409219a15 (patch) | |
tree | 7d97e763a81f86650c2085eeeaeaf04ffaddf6bd /src/jogl | |
parent | a7b402128a2cd00c099acde944f793455d8856a5 (diff) |
JOGL
Added OpenGL 3.0 and 3.1 support
3.0 as part of GL2 (extensions only)
3.1 forward compatible as GL3,
ie doesn't contain the GL2 fixed function stuff etc
Added code to retrieve a 3.0/3.1 context: X11/GLX and Windows/WGL
TODO: MacOSX !!
Updated GL and GLX extensions
Fixing auto GLProfile selection, determine if GL2ES[1] uses GL2 or ES
Usage of the unified GraphicsConfiguration of NativeWindow
for all platforms. Sure, the broken OS (Win32/MacOSX) have
a update mechanism for theit queried Capabilities after drawable creation.
Adding X11/GLX GLXFBConfig usage and fixing it's attribute mapping
Fixing GLX/X11 FBConfig/XVisual query function's memory leak,
using a manual implementation, which copies the data and calls XFree.
Added WGL extension WGL_ARB_create_context
Tested: Linux x86 and x86_64 GL2, ES2 and ES1
Note: Nvidia driver couldn't make the succesfully created 3.1
context current.
TODO: Verify Windows and MacOSX !!
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JOGL_2_SANDBOX@1919 232f8b59-042b-4e1e-8c03-345bb8c30851
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(); |