diff options
author | Sven Gothel <[email protected]> | 2010-11-28 03:54:00 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-11-28 03:54:00 +0100 |
commit | 597007fc23fbf86e036629b6c6b157e0e0506715 (patch) | |
tree | 688dd4c70e76dd23df399a3e008e31a7412dc9aa /src/jogl/classes/com/jogamp/opengl/impl | |
parent | 0c9eb947a2ffabba2c10799f6ea50756a2749702 (diff) |
JOGL: Proper handling of Read Drawable Support (if not supported), add query.
Read Drawable feature reflects the make context current API
having a seperate read drawable next to the write drawable (default).
glXMakeContextCurrent(write, read, ..)
On X11 a ready drawable is only supported for GLX >= 1.3,
on Windows only if extension WGL_ARB_make_current_read is available,
on EGL it's always supported, on OSX not at all.
API cleanup GLContext:
changes: setGLDrawableRead(GLDrawable) -> setGLReadDrawable(GLDrawable)
new: isGLReadDrawableAvailable()
new: getGLExtensionsString();
Access qualifier cleanup.
GLContextImpl: GLVersionNumber moved out.
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/impl')
9 files changed, 328 insertions, 340 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java index 4892303e3..cd121979a 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java @@ -62,7 +62,6 @@ import javax.media.opengl.GLProfile; public abstract class GLContextImpl extends GLContext { protected static final boolean DEBUG = Debug.debug("GLContext"); - protected static final boolean VERBOSE = Debug.verbose(); protected GLContextLock lock = new GLContextLock(); @@ -102,7 +101,7 @@ public abstract class GLContextImpl extends GLContext { mappedGLXProcAddress = new HashMap(); } - public GLContextImpl(GLDrawableImpl drawable, GLDrawableImpl drawableRead, GLContext shareWith) { + public GLContextImpl(GLDrawableImpl drawable, GLContext shareWith) { super(); if (shareWith != null) { @@ -111,11 +110,7 @@ public abstract class GLContextImpl extends GLContext { GLContextShareSet.registerForBufferObjectSharing(shareWith, this); this.drawable = drawable; - setGLDrawableRead(drawableRead); - } - - public GLContextImpl(GLDrawableImpl drawable, GLContext shareWith) { - this(drawable, null, shareWith); + this.drawableRead = drawable; } protected void resetStates() { @@ -144,7 +139,10 @@ public abstract class GLContextImpl extends GLContext { super.resetStates(); } - public void setGLDrawableRead(GLDrawable read) { + public final void setGLReadDrawable(GLDrawable read) { + if(null!=read && drawable!=read && !isGLReadDrawableAvailable()) { + throw new GLException("GL Read Drawable not available"); + } boolean lockHeld = lock.isHeld(); if(lockHeld) { release(); @@ -155,15 +153,15 @@ public abstract class GLContextImpl extends GLContext { } } - public GLDrawable getGLDrawable() { - return drawable; + public final GLDrawable getGLReadDrawable() { + return drawableRead; } - public GLDrawable getGLDrawableRead() { - return drawableRead; + public final GLDrawable getGLDrawable() { + return drawable; } - public GLDrawableImpl getDrawableImpl() { + public final GLDrawableImpl getDrawableImpl() { return (GLDrawableImpl) getGLDrawable(); } @@ -685,7 +683,7 @@ public abstract class GLContextImpl extends GLContext { ctxOptions = ctp; // Set version - Version version = new Version(versionStr); + GLVersionNumber version = new GLVersionNumber(versionStr); if (version.isValid()) { ctxMajorVersion = version.getMajor(); ctxMinorVersion = version.getMinor(); @@ -980,14 +978,14 @@ public abstract class GLContextImpl extends GLContext { return null; } - public String getGLExtensions() { + public String getGLExtensionsString() { if(null!=extensionAvailability) { - return extensionAvailability.getGLExtensions(); + return extensionAvailability.getGLExtensionsString(); } return null; } - public boolean isExtensionCacheInitialized() { + public final boolean isExtensionCacheInitialized() { if(null!=extensionAvailability) { return extensionAvailability.isInitialized(); } @@ -1038,187 +1036,4 @@ public abstract class GLContextImpl extends GLContext { return lock.hasWaiters(); } - /* FIXME: needed only by the Java 2D / JOGL bridge; refactor - - public GLContextImpl(GLContext shareWith) { - this(shareWith, false); - } - - public GLContextImpl(GLContext shareWith, boolean dontShareWithJava2D) { - extensionAvailability = new ExtensionAvailabilityCache(this); - GLContext shareContext = shareWith; - if (!dontShareWithJava2D) { - shareContext = Java2D.filterShareContext(shareWith); - } - if (shareContext != null) { - GLContextShareSet.registerSharing(this, shareContext); - } - // Always indicate real behind-the-scenes sharing to track deleted objects - if (shareContext == null) { - shareContext = Java2D.filterShareContext(shareWith); - } - GLContextShareSet.registerForObjectTracking(shareWith, this, shareContext); - GLContextShareSet.registerForBufferObjectSharing(shareWith, this); - // This must occur after the above calls into the - // GLContextShareSet, which set up state needed by the GL object - setGL(createGL()); - } - - //--------------------------------------------------------------------------- - // Helpers for integration with Java2D/OpenGL pipeline when FBOs are - // being used - // - - public void setObjectTracker(GLObjectTracker tracker) { - this.tracker = tracker; - } - - public GLObjectTracker getObjectTracker() { - return tracker; - } - - public void setDeletedObjectTracker(GLObjectTracker deletedObjectTracker) { - this.deletedObjectTracker = deletedObjectTracker; - } - - public GLObjectTracker getDeletedObjectTracker() { - return deletedObjectTracker; - } - - // Tracks creation and deletion of server-side OpenGL objects when - // the Java2D/OpenGL pipeline is active and using FBOs to render - private GLObjectTracker tracker; - // Supports deletion of these objects when no other context is - // current which can support immediate deletion of them - private GLObjectTracker deletedObjectTracker; - - */ - - /** - * A class for storing and comparing OpenGL version numbers. - * This only works for desktop OpenGL at the moment. - */ - private static class Version implements Comparable - { - private boolean valid; - private int major, minor, sub; - public Version(int majorRev, int minorRev, int subMinorRev) - { - major = majorRev; - minor = minorRev; - sub = subMinorRev; - } - - /** - * @param versionString must be of the form "GL_VERSION_X" or - * "GL_VERSION_X_Y" or "GL_VERSION_X_Y_Z" or "X.Y", where X, Y, - * and Z are integers. - * - * @exception IllegalArgumentException if the argument is not a valid - * OpenGL version identifier - */ - public Version(String versionString) - { - try - { - if (versionString.startsWith("GL_VERSION_")) - { - StringTokenizer tok = new StringTokenizer(versionString, "_"); - - tok.nextToken(); // GL_ - tok.nextToken(); // VERSION_ - if (!tok.hasMoreTokens()) { major = 0; return; } - major = Integer.valueOf(tok.nextToken()).intValue(); - if (!tok.hasMoreTokens()) { minor = 0; return; } - minor = Integer.valueOf(tok.nextToken()).intValue(); - if (!tok.hasMoreTokens()) { sub = 0; return; } - sub = Integer.valueOf(tok.nextToken()).intValue(); - } - else - { - int radix = 10; - if (versionString.length() > 2) { - if (Character.isDigit(versionString.charAt(0)) && - versionString.charAt(1) == '.' && - Character.isDigit(versionString.charAt(2))) { - major = Character.digit(versionString.charAt(0), radix); - minor = Character.digit(versionString.charAt(2), radix); - - // See if there's version-specific information which might - // imply a more recent OpenGL version - StringTokenizer tok = new StringTokenizer(versionString, " "); - if (tok.hasMoreTokens()) { - tok.nextToken(); - if (tok.hasMoreTokens()) { - String token = tok.nextToken(); - int i = 0; - while (i < token.length() && !Character.isDigit(token.charAt(i))) { - i++; - } - if (i < token.length() - 2 && - Character.isDigit(token.charAt(i)) && - token.charAt(i+1) == '.' && - Character.isDigit(token.charAt(i+2))) { - int altMajor = Character.digit(token.charAt(i), radix); - int altMinor = Character.digit(token.charAt(i+2), radix); - // Avoid possibly confusing situations by putting some - // constraints on the upgrades we do to the major and - // minor versions - if ((altMajor == major && altMinor > minor) || - altMajor == major + 1) { - major = altMajor; - minor = altMinor; - } - } - } - } - } - } - } - valid = true; - } - catch (Exception e) - { - e.printStackTrace(); - // FIXME: refactor desktop OpenGL dependencies and make this - // class work properly for OpenGL ES - System.err.println("Info: ExtensionAvailabilityCache: FunctionAvailabilityCache.Version.<init>: "+e); - major = 1; - minor = 0; - /* - throw (IllegalArgumentException) - new IllegalArgumentException( - "Illegally formatted version identifier: \"" + versionString + "\"") - .initCause(e); - */ - } - } - - public boolean isValid() { - return valid; - } - - public int compareTo(Object o) - { - Version vo = (Version)o; - if (major > vo.major) return 1; - else if (major < vo.major) return -1; - else if (minor > vo.minor) return 1; - else if (minor < vo.minor) return -1; - else if (sub > vo.sub) return 1; - else if (sub < vo.sub) return -1; - - return 0; // they are equal - } - - public int getMajor() { - return major; - } - - public int getMinor() { - return minor; - } - - } // end class Version - } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLVersionNumber.java b/src/jogl/classes/com/jogamp/opengl/impl/GLVersionNumber.java new file mode 100644 index 000000000..fa1c5c0c4 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLVersionNumber.java @@ -0,0 +1,123 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.impl; + +import java.util.StringTokenizer; +import com.jogamp.common.util.VersionNumber; + +/** + * A class for storing and comparing OpenGL version numbers. + * This only works for desktop OpenGL at the moment. + */ +class GLVersionNumber extends VersionNumber { + + protected boolean valid; + + public GLVersionNumber(int majorRev, int minorRev, int subMinorRev) { + super(majorRev, minorRev, subMinorRev); + valid = true; + } + + public GLVersionNumber(String versionString) { + super(); + valid = false; + try { + if (versionString.startsWith("GL_VERSION_")) { + StringTokenizer tok = new StringTokenizer(versionString, "_"); + tok.nextToken(); // GL_ + tok.nextToken(); // VERSION_ + if (!tok.hasMoreTokens()) { + major = 0; + return; + } + major = Integer.valueOf(tok.nextToken()).intValue(); + if (!tok.hasMoreTokens()) { + minor = 0; + return; + } + minor = Integer.valueOf(tok.nextToken()).intValue(); + if (!tok.hasMoreTokens()) { + sub = 0; + return; + } + sub = Integer.valueOf(tok.nextToken()).intValue(); + } else { + int radix = 10; + if (versionString.length() > 2) { + if (Character.isDigit(versionString.charAt(0)) && versionString.charAt(1) == '.' && Character.isDigit(versionString.charAt(2))) { + major = Character.digit(versionString.charAt(0), radix); + minor = Character.digit(versionString.charAt(2), radix); + // See if there's version-specific information which might + // imply a more recent OpenGL version + StringTokenizer tok = new StringTokenizer(versionString, " "); + if (tok.hasMoreTokens()) { + tok.nextToken(); + if (tok.hasMoreTokens()) { + String token = tok.nextToken(); + int i = 0; + while (i < token.length() && !Character.isDigit(token.charAt(i))) { + i++; + } + if (i < token.length() - 2 && Character.isDigit(token.charAt(i)) && token.charAt(i + 1) == '.' && Character.isDigit(token.charAt(i + 2))) { + int altMajor = Character.digit(token.charAt(i), radix); + int altMinor = Character.digit(token.charAt(i + 2), radix); + // Avoid possibly confusing situations by putting some + // constraints on the upgrades we do to the major and + // minor versions + if ((altMajor == major && altMinor > minor) || altMajor == major + 1) { + major = altMajor; + minor = altMinor; + } + } + } + } + } + } + } + valid = true; + } catch (Exception e) { + e.printStackTrace(); + // FIXME: refactor desktop OpenGL dependencies and make this + // class work properly for OpenGL ES + System.err.println("Info: ExtensionAvailabilityCache: FunctionAvailabilityCache.Version.<init>: " + e); + major = 1; + minor = 0; + /* + throw (IllegalArgumentException) + new IllegalArgumentException( + "Illegally formatted version identifier: \"" + versionString + "\"") + .initCause(e); + */ + } + } + + public final boolean isValid() { + return valid; + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java index d95a9e3ff..246814537 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java @@ -50,14 +50,9 @@ public abstract class EGLContext extends GLContextImpl { // EGL extension functions. private EGLExtProcAddressTable eglExtProcAddressTable; - public EGLContext(GLDrawableImpl drawable, GLDrawableImpl drawableRead, - GLContext shareWith) { - super(drawable, drawableRead, shareWith); - } - - public EGLContext(GLDrawableImpl drawable, - GLContext shareWith) { - this(drawable, null, shareWith); + EGLContext(GLDrawableImpl drawable, + GLContext shareWith) { + super(drawable, shareWith); } public Object getPlatformGLExtensions() { @@ -83,6 +78,10 @@ public abstract class EGLContext extends GLContextImpl { protected Map/*<String, String>*/ getExtensionNameMap() { return null; } + public final boolean isGLReadDrawableAvailable() { + return true; + } + protected void makeCurrentImpl(boolean newCreated) throws GLException { if(EGL.EGL_NO_DISPLAY==((EGLDrawable)drawable).getDisplay() ) { throw new GLException("drawable not properly initialized, NO DISPLAY: "+drawable); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java index 3cd2aa650..6a916765a 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java @@ -56,14 +56,9 @@ public abstract class MacOSXCGLContext extends GLContextImpl // CGL extension functions. private CGLExtProcAddressTable cglExtProcAddressTable; - public MacOSXCGLContext(GLDrawableImpl drawable, GLDrawableImpl drawableRead, - GLContext shareWith) { - super(drawable, drawableRead, shareWith); - } - - public MacOSXCGLContext(GLDrawableImpl drawable, - GLContext shareWith) { - this(drawable, null, shareWith); + protected MacOSXCGLContext(GLDrawableImpl drawable, + GLContext shareWith) { + super(drawable, shareWith); } public Object getPlatformGLExtensions() { @@ -99,6 +94,10 @@ public abstract class MacOSXCGLContext extends GLContextImpl // FIXME } + public final boolean isGLReadDrawableAvailable() { + return false; + } + /** * Creates and initializes an appropriate OpenGl Context (NS). Should only be * called by {@link makeCurrentImpl()}. @@ -292,11 +291,6 @@ public abstract class MacOSXCGLContext extends GLContextImpl throw new GLException("Not yet implemented"); } - public boolean isFunctionAvailable(String glFunctionName) - { - return super.isFunctionAvailable(glFunctionName); - } - public boolean isExtensionAvailable(String glExtensionName) { if (glExtensionName.equals("GL_ARB_pbuffer") || glExtensionName.equals("GL_ARB_pixel_format")) { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java index b42f1132c..f19fbcf6b 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java @@ -62,7 +62,7 @@ public class MacOSXJava2DCGLContext extends MacOSXCGLContext implements Java2DGL // rethink this in particular if using FBOs to implement the // Java2D/OpenGL pipeline on Mac OS X - public MacOSXJava2DCGLContext(GLContext shareWith) { + MacOSXJava2DCGLContext(GLContext shareWith) { super(null, shareWith); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java index 2735389e8..53badb25e 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java @@ -59,8 +59,8 @@ import javax.media.opengl.GLCapabilitiesImmutable; public class WindowsWGLContext extends GLContextImpl { - private static final Map/*<String, String>*/ functionNameMap; - private static final Map/*<String, String>*/ extensionNameMap; + static final Map/*<String, String>*/ functionNameMap; + static final Map/*<String, String>*/ extensionNameMap; private boolean wglGetExtensionsStringEXTInitialized; private boolean wglGetExtensionsStringEXTAvailable; private boolean wglMakeContextCurrentInitialized; @@ -81,14 +81,9 @@ public class WindowsWGLContext extends GLContextImpl { } // FIXME: figure out how to hook back in the Java 2D / JOGL bridge - public WindowsWGLContext(GLDrawableImpl drawable, GLDrawableImpl drawableRead, - GLContext shareWith) { - super(drawable, drawableRead, shareWith); - } - - public WindowsWGLContext(GLDrawableImpl drawable, - GLContext shareWith) { - this(drawable, null, shareWith); + WindowsWGLContext(GLDrawableImpl drawable, + GLContext shareWith) { + super(drawable, shareWith); } protected void resetState() { @@ -111,20 +106,30 @@ public class WindowsWGLContext extends GLContextImpl { return wglExt; } + public final boolean isGLReadDrawableAvailable() { + if(!wglMakeContextCurrentInitialized && null != getWGLExtProcAddressTable()) { + WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl(); + AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice device = config.getScreen().getDevice(); + WindowsWGLDrawableFactory.SharedResource sr = factory.getOrCreateShared(device); + if(null != sr) { + wglMakeContextCurrentAvailable = factory.isReadDrawableAvailable(device); + wglMakeContextCurrentInitialized=true; + } + } + return wglMakeContextCurrentAvailable; + } + private final boolean wglMakeContextCurrent(long hDrawDC, long hReadDC, long ctx) { boolean ok = false; - WGLExt _wglExt = getWGLExt(); - if (!wglMakeContextCurrentInitialized) { - wglMakeContextCurrentAvailable = isFunctionAvailable("wglMakeContextCurrent"); - wglMakeContextCurrentInitialized = true; - if(DEBUG) { - System.err.println("WindowsWGLContext.wglMakeContextCurrent: "+wglMakeContextCurrentAvailable); - } - } if(wglMakeContextCurrentAvailable) { - ok = _wglExt.wglMakeContextCurrent(hDrawDC, hReadDC, ctx); - } else { + // needs initilized WGL ProcAddress table + ok = getWGLExt().wglMakeContextCurrent(hDrawDC, hReadDC, ctx); + } else if ( hDrawDC == hReadDC ) { ok = WGL.wglMakeCurrent(hDrawDC, ctx); + } else { + // should not happen due to 'isGLReadDrawableAvailable()' query in GLContextImpl + throw new InternalError("Given readDrawable but no driver support"); } if(!ok && 0==hDrawDC && 0==hReadDC) { // Some GPU's falsely fails with a zero error code (success), @@ -147,7 +152,7 @@ public class WindowsWGLContext extends GLContextImpl { protected Map/*<String, String>*/ getExtensionNameMap() { return extensionNameMap; } protected void destroyContextARBImpl(long context) { - wglMakeContextCurrent(0, 0, 0); + WGL.wglMakeCurrent(0, 0); WGL.wglDeleteContext(context); } @@ -156,11 +161,11 @@ public class WindowsWGLContext extends GLContextImpl { AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); AbstractGraphicsDevice device = config.getScreen().getDevice(); WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device); - WGLExt wglExt; + WGLExt _wglExt; if(null==sharedContext) { - wglExt = getWGLExt(); + _wglExt = getWGLExt(); } else { - wglExt = sharedContext.getWGLExt(); + _wglExt = sharedContext.getWGLExt(); } boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ; @@ -202,7 +207,7 @@ public class WindowsWGLContext extends GLContextImpl { } try { - ctx = wglExt.wglCreateContextAttribsARB(drawable.getHandle(), share, attribs, 0); + ctx = _wglExt.wglCreateContextAttribsARB(drawable.getHandle(), share, attribs, 0); } catch (RuntimeException re) { if(DEBUG) { Throwable t = new Throwable("Info: WindowWGLContext.createContextARBImpl wglCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re); @@ -211,7 +216,8 @@ public class WindowsWGLContext extends GLContextImpl { } if(0!=ctx) { - if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), ctx)) { + // cannot use wglMakeContextCurrent since WGLExt ProcAddressTable is not ready yet. + if( !WGL.wglMakeCurrent(drawable.getHandle(), ctx) ) { if(DEBUG) { System.err.println("WindowsWGLContext.createContextARB couldn't make current "+getGLVersion(major, minor, ctp, "@creation")); } @@ -242,6 +248,8 @@ public class WindowsWGLContext extends GLContextImpl { WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device); GLCapabilitiesImmutable glCaps = drawable.getChosenGLCapabilities(); + isGLReadDrawableAvailable(); // trigger setup wglMakeContextCurrentAvailable + // Windows can set up sharing of display lists after creation time WindowsWGLContext other = (WindowsWGLContext) GLContextShareSet.getShareContext(this); long share = 0; @@ -302,12 +310,12 @@ public class WindowsWGLContext extends GLContextImpl { if(0!=contextHandle) { share = 0; // mark as shared thx to the ARB create method - if(0!=temp_ctx) { - WGL.wglMakeCurrent(0, 0); + WGL.wglMakeCurrent(0, 0); // the ARB create method used WGL.wglMakeCurrent(0, 0) + if(0!=temp_ctx) { WGL.wglDeleteContext(temp_ctx); - if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { - throw new GLException("Cannot make previous verified context current: 0x" + toHexString(contextHandle) + ", werr: " + GDI.GetLastError()); - } + } + if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { + throw new GLException("Cannot make previous verified context current: 0x" + toHexString(contextHandle) + ", werr: " + GDI.GetLastError()); } } else { if(glCaps.getGLProfile().isGL3()) { @@ -345,7 +353,7 @@ public class WindowsWGLContext extends GLContextImpl { if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { throw new GLException("Error making context current: 0x" + toHexString(contextHandle) + ", werr: " + GDI.GetLastError() + ", " + this); } else { - if (DEBUG && (VERBOSE || newCreated)) { + if (DEBUG && newCreated) { System.err.println(getThreadName() + ": wglMakeCurrent(hdc " + toHexString(drawable.getHandle()) + ", contextHandle " + toHexString(contextHandle) + ") succeeded"); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java index 0180b6c87..99e78b184 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java @@ -113,12 +113,18 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { private WindowsDummyWGLDrawable drawable; private WindowsWGLContext context; private boolean canCreateGLPbuffer; + private boolean readDrawableAvailable; - SharedResource(WindowsDummyWGLDrawable draw, WindowsWGLContext ctx, boolean canPbuffer) { + SharedResource(WindowsDummyWGLDrawable draw, WindowsWGLContext ctx, boolean readBufferAvail, boolean canPbuffer) { drawable = draw; context = ctx; canCreateGLPbuffer = canPbuffer; + readDrawableAvailable = readBufferAvail; } + WindowsWGLContext getContext() { return context; } + boolean canCreateGLPbuffer() { return canCreateGLPbuffer; } + boolean isReadDrawableAvailable() { return readDrawableAvailable; } + } HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap(); WindowsGraphicsDevice defaultDevice; @@ -146,7 +152,11 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } } - private final SharedResource getOrCreateShared(AbstractGraphicsDevice device) { + final static String GL_ARB_pbuffer = "GL_ARB_pbuffer"; + final static String WGL_ARB_make_current_read = "WGL_ARB_make_current_read"; + final static String wglMakeContextCurrent = "wglMakeContextCurrent"; + + protected final SharedResource getOrCreateShared(AbstractGraphicsDevice device) { String connection = device.getConnection(); SharedResource sr; synchronized(sharedMap) { @@ -159,14 +169,17 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { WindowsDummyWGLDrawable sharedDrawable = WindowsDummyWGLDrawable.create(this, null); WindowsWGLContext ctx = (WindowsWGLContext) sharedDrawable.createContext(null); ctx.makeCurrent(); - boolean canCreateGLPbuffer = ctx.getGL().isExtensionAvailable("GL_ARB_pbuffer"); + boolean canCreateGLPbuffer = ctx.getGL().isExtensionAvailable(GL_ARB_pbuffer); + boolean readDrawableAvailable = ctx.isExtensionAvailable(WGL_ARB_make_current_read) && + ctx.isFunctionAvailable(wglMakeContextCurrent); ctx.release(); - sr = new SharedResource(sharedDrawable, ctx, canCreateGLPbuffer); + sr = new SharedResource(sharedDrawable, ctx, readDrawableAvailable, canCreateGLPbuffer); synchronized(sharedMap) { sharedMap.put(device.getConnection(), sr); } if (DEBUG) { - System.err.println("!!! SharedContext: "+ctx+", pbuffer supported "+canCreateGLPbuffer); + System.err.println("!!! SharedContext: "+ctx+", pbuffer supported "+canCreateGLPbuffer+ + ", readDrawable supported "+readDrawableAvailable); } } catch (Throwable t) { @@ -181,7 +194,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) { SharedResource sr = getOrCreateShared(device); if(null!=sr) { - return sr.context; + return sr.getContext(); } return null; } @@ -232,10 +245,18 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return new WindowsOffscreenWGLDrawable(this, target); } + public final boolean isReadDrawableAvailable(AbstractGraphicsDevice device) { + SharedResource sr = getOrCreateShared((null!=device)?device:defaultDevice); + if(null!=sr) { + return sr.isReadDrawableAvailable(); + } + return false; + } + public final boolean canCreateGLPbuffer(AbstractGraphicsDevice device) { SharedResource sr = getOrCreateShared((null!=device)?device:defaultDevice); if(null!=sr) { - return sr.canCreateGLPbuffer; + return sr.canCreateGLPbuffer(); } return false; } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java index 1dadc2edf..fddfb4cd1 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java @@ -40,6 +40,7 @@ package com.jogamp.opengl.impl.x11.glx; +import com.jogamp.common.util.VersionNumber; import java.nio.*; import java.util.*; import javax.media.opengl.*; @@ -48,13 +49,14 @@ import com.jogamp.opengl.impl.*; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; import com.jogamp.nativewindow.impl.x11.X11Util; -import javax.media.nativewindow.x11.X11GraphicsDevice; public abstract class X11GLXContext extends GLContextImpl { protected static final boolean TRACE_CONTEXT_CURRENT = false; // true; private static final Map/*<String, String>*/ functionNameMap; private static final Map/*<String, String>*/ extensionNameMap; + private VersionNumber glXVersion; + private boolean glXVersionOneThreeCapable; private boolean glXQueryExtensionsStringInitialized; private boolean glXQueryExtensionsStringAvailable; private GLXExt glXExt; @@ -78,17 +80,14 @@ public abstract class X11GLXContext extends GLContextImpl { extensionNameMap.put("GL_ARB_pixel_format", "GLX_SGIX_pbuffer"); // good enough } - public X11GLXContext(GLDrawableImpl drawable, GLDrawableImpl drawableRead, - GLContext shareWith) { - super(drawable, drawableRead, shareWith); - } - - public X11GLXContext(GLDrawableImpl drawable, - GLContext shareWith) { - this(drawable, null, shareWith); + X11GLXContext(GLDrawableImpl drawable, + GLContext shareWith) { + super(drawable, shareWith); } protected void resetState() { + glXVersion = null; + glXVersionOneThreeCapable = false; glXQueryExtensionsStringInitialized=false; glXQueryExtensionsStringAvailable=false; // no inner state glXExt=null; @@ -120,16 +119,38 @@ public abstract class X11GLXContext extends GLContextImpl { protected Map/*<String, String>*/ getExtensionNameMap() { return extensionNameMap; } - protected boolean glXMakeContextCurrent(long dpy, long writeDrawable, long readDrawable, long ctx) { + public final boolean isGLReadDrawableAvailable() { + if(null == glXVersion) { + X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl(); + + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice device = config.getScreen().getDevice(); + + glXVersion = factory.getGLXVersion(device); + if( null != glXVersion ) { + glXVersionOneThreeCapable = glXVersion.compareTo(factory.versionOneThree)>=0; + } + } + return glXVersionOneThreeCapable; + } + + private final boolean glXMakeContextCurrent(long dpy, long writeDrawable, long readDrawable, long ctx) { boolean res = false; try { if(TRACE_CONTEXT_CURRENT) { Throwable t = new Throwable(Thread.currentThread()+" - glXMakeContextCurrent("+toHexString(dpy)+", "+ - toHexString(writeDrawable)+", "+toHexString(readDrawable)+", "+toHexString(ctx)+")"); + toHexString(writeDrawable)+", "+toHexString(readDrawable)+", "+toHexString(ctx)+") - GLX >= 1.3 "+ glXVersionOneThreeCapable); t.printStackTrace(); } - res = GLX.glXMakeContextCurrent(dpy, writeDrawable, readDrawable, ctx); + if ( glXVersionOneThreeCapable ) { + res = GLX.glXMakeContextCurrent(dpy, writeDrawable, readDrawable, ctx); + } else if ( writeDrawable == readDrawable ) { + res = GLX.glXMakeCurrent(dpy, writeDrawable, ctx); + } else { + // should not happen due to 'isGLReadDrawableAvailable()' query in GLContextImpl + throw new InternalError("Given readDrawable but no driver support"); + } } catch (RuntimeException re) { if(DEBUG) { System.err.println("Warning: X11GLXContext.glXMakeContextCurrent failed: "+re+", with "+ @@ -258,6 +279,8 @@ public abstract class X11GLXContext extends GLContextImpl { X11GLXContext sharedContext = (X11GLXContext) factory.getOrCreateSharedContextImpl(device); long display = device.getHandle(); + isGLReadDrawableAvailable(); // trigger setup glXVersionOneThreeCapable + X11GLXContext other = (X11GLXContext) GLContextShareSet.getShareContext(this); long share = 0; if (other != null) { @@ -270,7 +293,7 @@ public abstract class X11GLXContext extends GLContextImpl { GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); GLProfile glp = glCaps.getGLProfile(); - isVendorATI = factory.isVendorATI(device); + isVendorATI = factory.isGLXVendorATI(device); if(config.getFBConfigID()<0) { // not able to use FBConfig @@ -388,7 +411,7 @@ public abstract class X11GLXContext extends GLContextImpl { } finally { X11Util.setX11ErrorHandler(false, false); } - if (DEBUG && (VERBOSE || newCreated)) { + if (DEBUG && newCreated) { System.err.println(getThreadName() + ": glXMakeCurrent(display " + toHexString(dpy)+ ", drawable " + toHexString(drawable.getHandle()) + diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java index 4412a7a1c..c8b656e9f 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java @@ -55,6 +55,7 @@ import java.util.Iterator; public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { private static final DesktopGLDynamicLookupHelper x11GLXDynamicLookupHelper; + static final VersionNumber versionOneThree = new VersionNumber(1, 3, 0); static { DesktopGLDynamicLookupHelper tmp = null; @@ -208,7 +209,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { sharedDevice.setCloseDisplay(true); X11Util.lockDefaultToolkit(sharedDevice.getHandle()); // OK try { - String vendorName = GLXUtil.getVendorName(sharedDevice.getHandle()); + String glXVendorName = GLXUtil.getVendorName(sharedDevice.getHandle()); X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, 0); X11DummyGLXDrawable sharedDrawable = X11DummyGLXDrawable.create(sharedScreen, X11GLXDrawableFactory.this, GLProfile.getDefault(sharedDevice)); @@ -216,9 +217,16 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { throw new GLException("Couldn't init shared screen(" + sharedScreen + ")/drawable(" + sharedDrawable + ")"); } X11GLXContext sharedContext; + VersionNumber glXVersion; try { X11GLXContext ctx = (X11GLXContext) sharedDrawable.createContext(null); ctx.makeCurrent(); + { + int[] major = new int[1]; + int[] minor = new int[1]; + GLXUtil.getGLXVersion(sharedDevice.getHandle(), major, minor); + glXVersion = new VersionNumber(major[0], minor[0], 0); + } ctx.release(); sharedContext = ctx; } catch (Throwable t) { @@ -228,12 +236,14 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { throw new GLException("X11GLXDrawableFactory - Shared Context is null"); } if (DEBUG) { - System.err.println("!!! SharedDevice: "+sharedDevice); - System.err.println("!!! SharedScreen: "+sharedScreen); + System.err.println("!!! SharedDevice: "+sharedDevice); + System.err.println("!!! SharedScreen: "+sharedScreen); System.err.println("!!! SharedContext: "+sharedContext); - System.err.println("!!! Vendor: "+vendorName); + System.err.println("!!! GLX Vendor: "+glXVendorName); + System.err.println("!!! GLX Version: "+glXVersion + + " >= 1.3: " + ( glXVersion.compareTo(versionOneThree) >= 0 ) ); } - return new SharedResource(sharedDevice, sharedScreen, sharedDrawable, sharedContext, vendorName); + return new SharedResource(sharedDevice, sharedScreen, sharedDrawable, sharedContext, glXVersion, glXVendorName); } finally { X11Util.unlockDefaultToolkit(sharedDevice.getHandle()); // OK } @@ -246,10 +256,10 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { if (DEBUG) { System.err.println("!!! Shutdown Shared:"); - System.err.println("!!! Device : "+sr.device); - System.err.println("!!! Screen : "+sr.screen); - System.err.println("!!! Drawable: "+sr.drawable); - System.err.println("!!! CTX : "+sr.context); + System.err.println("!!! Device : "+sr.device); + System.err.println("!!! Screen : "+sr.screen); + System.err.println("!!! Drawable: "+sr.drawable); + System.err.println("!!! CTX : "+sr.context); } if (null != sr.context) { @@ -278,23 +288,34 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { SharedResourcesRunner sharedResourcesRunner=null; static class SharedResource { - private X11GraphicsDevice device; - private X11GraphicsScreen screen; - private X11DummyGLXDrawable drawable; - private X11GLXContext context; - private String vendorName; - private boolean isVendorATI; - private boolean isVendorNVIDIA; - - SharedResource(X11GraphicsDevice dev, X11GraphicsScreen scrn, X11DummyGLXDrawable draw, X11GLXContext ctx, String vendor) { + X11GraphicsDevice device; + X11GraphicsScreen screen; + X11DummyGLXDrawable drawable; + X11GLXContext context; + String glXVendorName; + boolean isGLXVendorATI; + boolean isGLXVendorNVIDIA; + VersionNumber glXVersion; + + SharedResource(X11GraphicsDevice dev, X11GraphicsScreen scrn, + X11DummyGLXDrawable draw, X11GLXContext ctx, + VersionNumber glXVer, String glXVendor) { device = dev; screen = scrn; drawable = draw; context = ctx; - vendorName = vendor; - isVendorATI = GLXUtil.isVendorATI(vendorName); - isVendorNVIDIA = GLXUtil.isVendorNVIDIA(vendorName); + glXVersion = glXVer; + glXVendorName = glXVendor; + isGLXVendorATI = GLXUtil.isVendorATI(glXVendorName); + isGLXVendorNVIDIA = GLXUtil.isVendorNVIDIA(glXVendorName); } + X11GraphicsDevice getDevice() { return device; } + X11GraphicsScreen getScreen() { return screen; } + X11GLXContext getContext() { return context; } + String getGLXVendorName() { return glXVendorName; } + boolean isGLXVendorATI() { return isGLXVendorATI; } + boolean isGLXVendorNVIDIA() { return isGLXVendorNVIDIA; } + VersionNumber getGLXVersion() { return glXVersion; } } HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap(); X11GraphicsDevice defaultDevice; @@ -354,7 +375,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) { SharedResource sr = getOrCreateShared(device); if(null!=sr) { - return sr.context; + return sr.getContext(); } return null; } @@ -362,31 +383,39 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { protected final long getOrCreateSharedDpy(AbstractGraphicsDevice device) { SharedResource sr = getOrCreateShared(device); if(null!=sr) { - return sr.device.getHandle(); + return sr.getDevice().getHandle(); } return 0; } - protected final String getVendorName(AbstractGraphicsDevice device) { + protected final VersionNumber getGLXVersion(AbstractGraphicsDevice device) { SharedResource sr = getOrCreateShared(device); if(null!=sr) { - return sr.vendorName; + return sr.getGLXVersion(); + } + return null; + } + + protected final String getGLXVendorName(AbstractGraphicsDevice device) { + SharedResource sr = getOrCreateShared(device); + if(null!=sr) { + return sr.getGLXVendorName(); } return GLXUtil.getVendorName(device.getHandle()); } - protected final boolean isVendorATI(AbstractGraphicsDevice device) { + protected final boolean isGLXVendorATI(AbstractGraphicsDevice device) { SharedResource sr = getOrCreateShared(device); if(null!=sr) { - return sr.isVendorATI; + return sr.isGLXVendorATI(); } return GLXUtil.isVendorATI(device.getHandle()); } - protected final boolean isVendorNVIDIA(AbstractGraphicsDevice device) { + protected final boolean isGLXVendorNVIDIA(AbstractGraphicsDevice device) { SharedResource sr = getOrCreateShared(device); if(null!=sr) { - return sr.isVendorNVIDIA; + return sr.isGLXVendorNVIDIA(); } return GLXUtil.isVendorNVIDIA(device.getHandle()); } @@ -413,43 +442,19 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return new X11OffscreenGLXDrawable(this, target); } - public final boolean canCreateGLPbuffer(AbstractGraphicsDevice device) { - return glxVersionGreaterEqualThan(device, 1, 3); + public final boolean glXVersionGreaterEqualOneThree(AbstractGraphicsDevice device) { + VersionNumber glXVersion = getGLXVersion(device); + return ( null != glXVersion ) ? glXVersion.compareTo(versionOneThree) >= 0 : false ; } - private boolean glxVersionsQueried = false; - private int glxVersionMajor=0, glxVersionMinor=0; - protected final boolean glxVersionGreaterEqualThan(AbstractGraphicsDevice device, int majorReq, int minorReq) { - if (!glxVersionsQueried) { - if(null == device) { - SharedResource sr = getOrCreateShared(defaultDevice); - if(null!=sr) { - device = sr.device; - } - } - if(null == device) { - throw new GLException("FIXME: No AbstractGraphicsDevice (passed or shared-device"); - } - device.lock(); // OK - try { - long display = device.getHandle(); - int[] major = new int[1]; - int[] minor = new int[1]; - - GLXUtil.getGLXVersion(display, major, minor); - if (DEBUG) { - System.err.println("!!! GLX version: major " + major[0] + - ", minor " + minor[0]); - } - - glxVersionMajor = major[0]; - glxVersionMinor = minor[0]; - glxVersionsQueried = true; - } finally { - device.unlock(); // OK + public final boolean canCreateGLPbuffer(AbstractGraphicsDevice device) { + if(null == device) { + SharedResource sr = getOrCreateShared(defaultDevice); + if(null!=sr) { + device = sr.getDevice(); } - } - return ( glxVersionMajor > majorReq ) || ( glxVersionMajor == majorReq && glxVersionMinor >= minorReq ) ; + } + return glXVersionGreaterEqualOneThree(device); } protected final GLDrawableImpl createGLPbufferDrawableImpl(final NativeSurface target) { @@ -469,7 +474,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { * since switching Display in this regard is another ATI bug. */ SharedResource sr = getOrCreateShared(device); - if( null!=sr && sr.isVendorATI && null == GLContext.getCurrent() ) { + if( null!=sr && sr.isGLXVendorATI() && null == GLContext.getCurrent() ) { synchronized(sr.context) { sr.context.makeCurrent(); try { @@ -490,7 +495,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { X11GraphicsScreen screen = null; SharedResource sr = getOrCreateShared(defaultDevice); if(null!=sr) { - screen = sr.screen; + screen = sr.getScreen(); } if(null==screen) { return null; |