diff options
Diffstat (limited to 'src/jogl/classes/jogamp/opengl')
16 files changed, 340 insertions, 235 deletions
diff --git a/src/jogl/classes/jogamp/opengl/Debug.java b/src/jogl/classes/jogamp/opengl/Debug.java index 4287c1960..f87f1bb3f 100644 --- a/src/jogl/classes/jogamp/opengl/Debug.java +++ b/src/jogl/classes/jogamp/opengl/Debug.java @@ -1,5 +1,6 @@ /* - * Copyright (c) 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -39,6 +40,9 @@ package jogamp.opengl; +import java.security.AccessController; +import java.security.PrivilegedAction; + import com.jogamp.common.util.PropertyAccess; /** Helper routines for logging and debugging. */ @@ -49,7 +53,12 @@ public class Debug extends PropertyAccess { private static final boolean debugAll; static { - PropertyAccess.addTrustedPrefix("jogl.", Debug.class); + AccessController.doPrivileged(new PrivilegedAction<Object>() { + public Object run() { + PropertyAccess.addTrustedPrefix("jogl."); + return null; + } } ); + verbose = isPropertyDefined("jogl.verbose", true); debugAll = isPropertyDefined("jogl.debug", true); if (verbose) { @@ -60,18 +69,6 @@ public class Debug extends PropertyAccess { } } - public static final boolean isPropertyDefined(final String property, final boolean jnlpAlias) { - return PropertyAccess.isPropertyDefined(property, jnlpAlias, null); - } - - public static String getProperty(final String property, final boolean jnlpAlias) { - return PropertyAccess.getProperty(property, jnlpAlias, null); - } - - public static final boolean getBooleanProperty(final String property, final boolean jnlpAlias) { - return PropertyAccess.getBooleanProperty(property, jnlpAlias, null); - } - public static boolean verbose() { return verbose; } diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java index f16834d28..cab629c3a 100644 --- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java @@ -1048,17 +1048,15 @@ public abstract class GLContextImpl extends GLContext { if(useGL) { ctxGLSLVersion = VersionNumber.zeroVersion; if( hasGLSL() ) { // >= ES2 || GL2.0 - final String glslVersion = gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION); + final String glslVersion = isGLES() ? null : gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) ; // Use static GLSL version for ES to be safe! if( null != glslVersion ) { - ctxGLSLVersion = new VersionNumber(glslVersion, "."); + ctxGLSLVersion = new VersionNumber(glslVersion); if( ctxGLSLVersion.getMajor() < 1 ) { ctxGLSLVersion = VersionNumber.zeroVersion; // failed .. } } if( ctxGLSLVersion.isZero() ) { - final int[] sver = new int[2]; - getStaticGLSLVersionNumber(major, minor, ctxOptions, sver); - ctxGLSLVersion = new VersionNumber(sver[0], sver[1], 0); + ctxGLSLVersion = getStaticGLSLVersionNumber(major, minor, ctxOptions); } } } @@ -1506,7 +1504,7 @@ public abstract class GLContextImpl extends GLContext { } private final void setRendererQuirks(final AbstractGraphicsDevice adevice, int major, int minor, int ctp, final VersionNumberString vendorVersion) { - int[] quirks = new int[GLRendererQuirks.COUNT]; + int[] quirks = new int[GLRendererQuirks.COUNT + 1]; // + 1 ( NoFullFBOSupport ) int i = 0; final String MesaSP = "Mesa "; @@ -1515,6 +1513,7 @@ public abstract class GLContextImpl extends GLContext { final boolean isDriverMesa = glRenderer.contains(MesaSP) || glRenderer.contains("Gallium "); final boolean isDriverATICatalyst = !isDriverMesa && ( glVendor.contains("ATI Technologies") || glRenderer.startsWith("ATI ") ); final boolean isDriverNVIDIAGeForce = !isDriverMesa && ( glVendor.contains("NVIDIA Corporation") || glRenderer.contains("NVIDIA ") ); + // // OS related quirks // @@ -1585,6 +1584,44 @@ public abstract class GLContextImpl extends GLContext { } // + // Windowing Toolkit related quirks + // + if( NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true) ) { + // + // X11 + // + { + // + // Quirk: DontCloseX11Display + // + final int quirk = GLRendererQuirks.DontCloseX11Display; + if( glRenderer.contains(MesaSP) ) { + if ( glRenderer.contains("X11") && vendorVersion.compareTo(Version80) < 0 ) { + if(DEBUG) { + System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: X11 Renderer=" + glRenderer + ", Version=[vendor " + vendorVersion + ", GL " + glVersion+"]"); + } + quirks[i++] = quirk; + } + } else if( isDriverATICatalyst ) { + { + if(DEBUG) { + System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: X11 Renderer=" + glRenderer); + } + quirks[i++] = quirk; + } + } else if( jogamp.nativewindow.x11.X11Util.getMarkAllDisplaysUnclosable() ) { + { + if(DEBUG) { + System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: X11Util Downstream"); + } + quirks[i++] = quirk; + } + } + } + } + + + // // RENDERER related quirks // if( isDriverMesa ) { @@ -1603,7 +1640,7 @@ public abstract class GLContextImpl extends GLContext { } quirks[i++] = quirk; } - if( glRenderer.contains("Intel(R)") && compatCtx && ( major>3 || major==3 && minor>=1 ) ) + if( glRenderer.contains("Intel(R)") && compatCtx && ( major > 3 || major == 3 && minor >= 1 ) ) { // FIXME: Apply vendor version constraints! final int quirk = GLRendererQuirks.GLNonCompliant; @@ -1612,37 +1649,30 @@ public abstract class GLContextImpl extends GLContext { } quirks[i++] = quirk; } - } - - // - // Quirk: DontCloseX11Display - // - if( NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true) ) { - final int quirk = GLRendererQuirks.DontCloseX11Display; - if( glRenderer.contains(MesaSP) ) { - if ( glRenderer.contains("X11") && vendorVersion.compareTo(Version80) < 0 ) { - if(DEBUG) { - System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: X11 Renderer=" + glRenderer + ", Version=[vendor " + vendorVersion + ", GL " + glVersion+"]"); - } - quirks[i++] = quirk; - } - } else if( isDriverATICatalyst ) { - { - if(DEBUG) { - System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: X11 Renderer=" + glRenderer); - } - quirks[i++] = quirk; - } - } else if( jogamp.nativewindow.x11.X11Util.getMarkAllDisplaysUnclosable() ) { - { + if( Platform.getOSType() == Platform.OSType.WINDOWS && glRenderer.contains("SVGA3D") ) + { + final VersionNumber mesaSafeFBOVersion = new VersionNumber(8, 0, 0); + if ( vendorVersion.compareTo(mesaSafeFBOVersion) < 0 ) { // includes: vendorVersion.isZero() + final int quirk = GLRendererQuirks.NoFullFBOSupport; if(DEBUG) { - System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: X11Util Downstream"); + System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType() + " / Renderer " + glRenderer + " / Mesa-Version "+vendorVersion); } quirks[i++] = quirk; } } } + // + // Property related quirks + // + if( FORCE_MIN_FBO_SUPPORT ) { + final int quirk = GLRendererQuirks.NoFullFBOSupport; + if(DEBUG) { + System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: property"); + } + quirks[i++] = quirk; + } + glRendererQuirks = new GLRendererQuirks(quirks, 0, i); } diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java index 177c465da..8be910c1a 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java @@ -531,10 +531,10 @@ public class GLDrawableHelper { } } - private final void init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape) { + private final void init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape, boolean setViewport) { l.init(drawable); if(sendReshape) { - reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), true /* setViewport */, false /* checkInit */); + reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), setViewport, false /* checkInit */); } } @@ -545,33 +545,40 @@ public class GLDrawableHelper { public final void init(GLAutoDrawable drawable, boolean sendReshape) { synchronized(listenersLock) { final ArrayList<GLEventListener> _listeners = listeners; - for (int i=0; i < _listeners.size(); i++) { - final GLEventListener listener = _listeners.get(i) ; - - // If make ctx current, invoked by invokGL(..), results in a new ctx, init gets called. - // This may happen not just for initial setup, but for ctx recreation due to resource change (drawable/window), - // hence it must be called unconditional, always. - listenersToBeInit.remove(listener); // remove if exist, avoiding dbl init - init( listener, drawable, sendReshape); + final int listenerCount = _listeners.size(); + if( listenerCount > 0 ) { + for (int i=0; i < listenerCount; i++) { + final GLEventListener listener = _listeners.get(i) ; + + // If make ctx current, invoked by invokGL(..), results in a new ctx, init gets called. + // This may happen not just for initial setup, but for ctx recreation due to resource change (drawable/window), + // hence it must be called unconditional, always. + listenersToBeInit.remove(listener); // remove if exist, avoiding dbl init + init( listener, drawable, sendReshape, 0==i /* setViewport */); + } + } else { + // Expose same GL initialization if not using GLEventListener + drawable.getGL().glViewport(0, 0, drawable.getWidth(), drawable.getHeight()); } } } public final void display(GLAutoDrawable drawable) { displayImpl(drawable); - if(!execGLRunnables(drawable)) { + if( glRunnables.size()>0 && !execGLRunnables(drawable) ) { // glRunnables volatile OK; execGL.. only executed if size > 0 displayImpl(drawable); } } private final void displayImpl(GLAutoDrawable drawable) { synchronized(listenersLock) { final ArrayList<GLEventListener> _listeners = listeners; - for (int i=0; i < _listeners.size(); i++) { + final int listenerCount = _listeners.size(); + for (int i=0; i < listenerCount; i++) { final GLEventListener listener = _listeners.get(i) ; // GLEventListener may need to be init, // in case this one is added after the realization of the GLAutoDrawable if( listenersToBeInit.remove(listener) ) { - init( listener, drawable, true /* sendReshape */) ; + init( listener, drawable, true /* sendReshape */, listenersToBeInit.size() + 1 == listenerCount /* setViewport if 1st init */ ); } listener.display(drawable); } @@ -585,7 +592,7 @@ public class GLDrawableHelper { // in case this one is added after the realization of the GLAutoDrawable synchronized(listenersLock) { if( listenersToBeInit.remove(listener) ) { - init( listener, drawable, false /* sendReshape */) ; + listener.init(drawable); } } } @@ -598,29 +605,27 @@ public class GLDrawableHelper { public final void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { synchronized(listenersLock) { for (int i=0; i < listeners.size(); i++) { - reshape((GLEventListener) listeners.get(i), drawable, x, y, width, height, 0==i, true); + reshape((GLEventListener) listeners.get(i), drawable, x, y, width, height, 0==i /* setViewport */, true /* checkInit */); } } } - private final boolean execGLRunnables(GLAutoDrawable drawable) { + private final boolean execGLRunnables(GLAutoDrawable drawable) { // glRunnables.size()>0 boolean res = true; - if(glRunnables.size()>0) { // volatile OK - // swap one-shot list asap - final ArrayList<GLRunnableTask> _glRunnables; - synchronized(glRunnablesLock) { - if(glRunnables.size()>0) { - _glRunnables = glRunnables; - glRunnables = new ArrayList<GLRunnableTask>(); - } else { - _glRunnables = null; - } + // swap one-shot list asap + final ArrayList<GLRunnableTask> _glRunnables; + synchronized(glRunnablesLock) { + if(glRunnables.size()>0) { + _glRunnables = glRunnables; + glRunnables = new ArrayList<GLRunnableTask>(); + } else { + _glRunnables = null; } - - if(null!=_glRunnables) { - for (int i=0; i < _glRunnables.size(); i++) { - res = _glRunnables.get(i).run(drawable) && res; - } + } + + if(null!=_glRunnables) { + for (int i=0; i < _glRunnables.size(); i++) { + res = _glRunnables.get(i).run(drawable) && res; } } return res; diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java index 877e7b60b..e1088da29 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java @@ -116,6 +116,7 @@ public abstract class GLDrawableImpl implements GLDrawable { * {@link GL#glFlush()} has been called already and * the implementation may execute implementation specific code. * </p> + * @param doubleBuffered indicates whether double buffering is enabled, see above. */ protected abstract void swapBuffersImpl(boolean doubleBuffered); diff --git a/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java index 4c82fc2b3..a2e3b3175 100644 --- a/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java +++ b/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java @@ -36,11 +36,21 @@ public abstract class GLDynamicLibraryBundleInfo implements DynamicLibraryBundle protected GLDynamicLibraryBundleInfo() { } - /** default **/ - @Override - public boolean shallLinkGlobal() { return false; } - - /** default **/ + /** + * Returns <code>true</code>, + * since we might load a desktop GL library and allow symbol access to subsequent libs. + * <p> + * This respects old DRI requirements: + * <pre> + * http://dri.sourceforge.net/doc/DRIuserguide.html + * </pre> + * </p> + */ + public boolean shallLinkGlobal() { return true; } + + /** + * Default value: <code>false</code>. + */ @Override public boolean shallLookupGlobal() { return false; } diff --git a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java index 85f63b52c..27024d4e1 100644 --- a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java @@ -52,7 +52,10 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable { private int fboIBack; // points to GL_BACK buffer private int fboIFront; // points to GL_FRONT buffer private int pendingFBOReset = -1; + /** Indicated whether the FBO is bound. */ private boolean fboBound; + /** Indicated whether the FBO is swapped, resets to false after makeCurrent -> contextMadeCurrent. */ + private boolean fboSwapped; /** dump fboResetQuirk info only once pre ClassLoader and only in DEBUG mode */ private static volatile boolean resetQuirkInfoDumped = false; @@ -139,21 +142,20 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable { } } fbos[fboIFront].resetSamplingSink(gl); - fboBound = false; + fbos[0].formatToGLCapabilities(chosenFBOCaps); chosenFBOCaps.setDoubleBuffered( chosenFBOCaps.getDoubleBuffered() || samples > 0 ); - - initialized = true; } else { - initialized = false; - for(int i=0; i<fbos.length; i++) { fbos[i].destroy(gl); } fbos=null; - fboBound = false; - pendingFBOReset = -1; } + fboBound = false; + fboSwapped = false; + pendingFBOReset = -1; + initialized = realize; + if(DEBUG) { System.err.println("GLFBODrawableImpl.initialize("+realize+"): "+this); Thread.dumpStack(); @@ -230,6 +232,7 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable { ourContext.makeCurrent(); gl.glFinish(); // sync GL command stream fboBound = false; // clear bound-flag immediatly, caused by contextMadeCurrent(..) - otherwise we would swap @ release + fboSwapped = false; try { final int maxSamples = gl.getMaxRenderbufferSamples(); newSamples = newSamples <= maxSamples ? newSamples : maxSamples; @@ -340,10 +343,12 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable { } fbos[fboIBack].bind(gl); fboBound = true; - } else if( fboBound ) { + fboSwapped = false; + } else if( fboBound && !fboSwapped ) { swapFBOImpl(glc); swapFBOImplPost(glc); fboBound=false; + fboSwapped=true; if(DEBUG_SWAP) { System.err.println("Post FBO swap(@release): done"); } @@ -353,14 +358,16 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable { @Override protected void swapBuffersImpl(boolean doubleBuffered) { final GLContext ctx = GLContext.getCurrent(); - boolean doPostSwap = false; + boolean doPostSwap; if( null != ctx && ctx.getGLDrawable() == this && fboBound ) { swapFBOImpl(ctx); doPostSwap = true; - fboBound=false; + fboSwapped = true; if(DEBUG_SWAP) { System.err.println("Post FBO swap(@swap): done"); } + } else { + doPostSwap = false; } if( null != swapBufferContext ) { swapBufferContext.swapBuffers(doubleBuffered); diff --git a/src/jogl/classes/jogamp/opengl/GLVersionNumber.java b/src/jogl/classes/jogamp/opengl/GLVersionNumber.java index 990698667..cea3ac4ab 100644 --- a/src/jogl/classes/jogamp/opengl/GLVersionNumber.java +++ b/src/jogl/classes/jogamp/opengl/GLVersionNumber.java @@ -28,98 +28,62 @@ package jogamp.opengl; -import java.util.StringTokenizer; - -import javax.media.opengl.GLContext; - +import com.jogamp.common.util.VersionNumber; import com.jogamp.common.util.VersionNumberString; /** * A class for storing and comparing OpenGL version numbers. * This only works for desktop OpenGL at the moment. */ -class GLVersionNumber extends VersionNumberString { +public class GLVersionNumber extends VersionNumberString { private final boolean valid; - private GLVersionNumber(int[] val, String versionString, boolean valid) { - super(val[0], val[1], val[2], versionString); + private GLVersionNumber(int[] val, int strEnd, short state, String versionString, boolean valid) { + super(val[0], val[1], val[2], strEnd, state, versionString); this.valid = valid; } - public static GLVersionNumber create(String versionString) { + private static java.util.regex.Pattern getUnderscorePattern() { + if( null == _Pattern ) { // volatile dbl-checked-locking OK + synchronized( VersionNumber.class ) { + if( null == _Pattern ) { + _Pattern = getVersionNumberPattern("_"); + } + } + } + return _Pattern; + } + private static volatile java.util.regex.Pattern _Pattern = null; + + public static final GLVersionNumber create(String versionString) { int[] val = new int[] { 0, 0, 0 }; - try { - if (versionString.startsWith("GL_VERSION_")) { - StringTokenizer tok = new StringTokenizer(versionString, "_"); - tok.nextToken(); // GL_ - tok.nextToken(); // VERSION_ - if (!tok.hasMoreTokens()) { - val[0] = 0; + int strEnd = 0; + short state = 0; + boolean valid = false; + if (versionString != null && versionString.length() > 0) { + try { + final java.util.regex.Pattern versionPattern; + if (versionString.startsWith("GL_VERSION_")) { + versionPattern = getUnderscorePattern(); } else { - val[0] = Integer.valueOf(tok.nextToken()).intValue(); - if (!tok.hasMoreTokens()) { - val[1] = 0; - } else { - val[1] = Integer.valueOf(tok.nextToken()).intValue(); - if (!tok.hasMoreTokens()) { - val[2] = 0; - } else { - val[2] = 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))) { - val[0] = Character.digit(versionString.charAt(0), radix); - val[1] = 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 == val[0] && altMinor > val[1]) || altMajor == val[0] + 1 ) { - if( GLContext.isValidGLVersion(altMajor, altMinor) ) { - val[0] = altMajor; - val[1] = altMinor; - } - } - } - } - } - } + versionPattern = VersionNumberString.getDefaultVersionNumberPattern(); } + final VersionNumberString version = new VersionNumberString(versionString, versionPattern); + strEnd = version.endOfStringMatch(); + val[0] = version.getMajor(); + val[1] = version.getMinor(); + state = (short) ( ( version.hasMajor() ? VersionNumber.HAS_MAJOR : (short)0 ) | + ( version.hasMinor() ? VersionNumber.HAS_MINOR : (short)0 ) ); + valid = version.hasMajor() && version.hasMinor(); // Requires at least a defined major and minor version component! + } catch (Exception e) { + e.printStackTrace(); + System.err.println("Info: ExtensionAvailabilityCache: FunctionAvailabilityCache.Version.<init>: " + e); + val[0] = 1; + val[1] = 0; } - return new GLVersionNumber(val, versionString, 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); - val[0] = 1; - val[1] = 0; - /* - throw (IllegalArgumentException) - new IllegalArgumentException( - "Illegally formatted version identifier: \"" + versionString + "\"") - .initCause(e); - */ - } - return new GLVersionNumber(val, versionString, false); + } + return new GLVersionNumber(val, strEnd, state, versionString, valid); } public final boolean isValid() { @@ -131,6 +95,7 @@ class GLVersionNumber extends VersionNumberString { * <code>GL_VERSION</code> string if exists, otherwise the {@link VersionNumberString#zeroVersion zero version} instance. * <pre> * 2.1 Mesa 7.0.3-rc2 -> 7.0.3 (7.0.3-rc2) + * 2.1 Mesa 7.12-devel (git-d6c318e) -> 7.12.0 (7.12-devel) * 4.2.12171 Compatibility Profile Context 9.01.8 -> 9.1.8 (9.01.8) * 4.2.12198 Compatibility Profile Context 12.102.3.0 -> 12.102.3 (12.102.3.0) * 4.3.0 NVIDIA 310.32 -> 310.32 (310.32) @@ -139,18 +104,25 @@ class GLVersionNumber extends VersionNumberString { public static final VersionNumberString createVendorVersion(String versionString) { if (versionString == null || versionString.length() <= 0) { return null; - } - final String[] strings = versionString.trim().split("\\s+"); - if ( strings.length <= 0 ) { - return null; } - // Test all segments backwards from [len-1..1], skipping the 1st entry (GL version) - // If a segment represents a valid VersionNumber - use it. - for(int i=strings.length-1; i>=1; i--) { - final String s = strings[i]; - final VersionNumberString version = new VersionNumberString(s, "."); - if( !version.isZero() ) { - return version; + + // Skip the 1st GL version + String str; + { + final GLVersionNumber glv = create(versionString); + str = versionString.substring(glv.endOfStringMatch()); + } + + while ( str.length() > 0 ) { + final VersionNumberString version = new VersionNumberString(str, getDefaultVersionNumberPattern()); + final int eosm = version.endOfStringMatch(); + if( 0 < eosm ) { + if( version.hasMajor() && version.hasMinor() ) { // Requires at least a defined major and minor version component! + return version; + } + str = str.substring( eosm ); + } else { + break; // no match } } return VersionNumberString.zeroVersion; diff --git a/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java index cddd142e9..771d16d46 100644 --- a/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java +++ b/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java @@ -47,16 +47,6 @@ public class DesktopES2DynamicLibraryBundleInfo extends GLDynamicLibraryBundleIn super(); } - /** - * Might be a desktop GL library, and might need to allow symbol access to subsequent libs. - * - * This respects old DRI requirements:<br> - * <pre> - * http://dri.sourceforge.net/doc/DRIuserguide.html - * </pre> - */ - public boolean shallLinkGlobal() { return true; } - public final List<String> getToolGetProcAddressFuncNameList() { List<String> res = new ArrayList<String>(); res.add("eglGetProcAddress"); diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java index fe9d7573d..26b199ea2 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java @@ -29,6 +29,7 @@ package jogamp.opengl.egl; import com.jogamp.common.os.AndroidVersion; +import com.jogamp.common.os.Platform; import java.util.*; @@ -52,19 +53,12 @@ public abstract class EGLDynamicLibraryBundleInfo extends GLDynamicLibraryBundle } /** - * Might be a desktop GL library, and might need to allow symbol access to subsequent libs. - * - * This respects old DRI requirements:<br> - * <pre> - * http://dri.sourceforge.net/doc/DRIuserguide.html - * </pre> + * Returns <code>true</code> on <code>Android</code>, + * and <code>false</code> otherwise. */ @Override - public boolean shallLinkGlobal() { return true; } - - @Override public boolean shallLookupGlobal() { - if ( AndroidVersion.isAvailable ) { + if ( Platform.OSType.ANDROID == Platform.OS_TYPE ) { // Android requires global symbol lookup return true; } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java index 666cd30af..6b086ce44 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java @@ -81,7 +81,7 @@ import com.jogamp.opengl.util.glsl.ShaderCode; import com.jogamp.opengl.util.glsl.ShaderProgram; public class MacOSXCGLContext extends GLContextImpl -{ +{ // Abstract interface for implementation of this context (either // NSOpenGL-based or CGL-based) protected interface GLBackendImpl { @@ -149,8 +149,8 @@ public class MacOSXCGLContext extends GLContextImpl "../../shader", "../../shader/bin", shaderBasename, true); final ShaderCode fp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, MacOSXCGLContext.class, "../../shader", "../../shader/bin", shaderBasename, true); - vp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp); - fp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp); + vp.defaultShaderCustomization(gl, true, true); + fp.defaultShaderCustomization(gl, true, true); sp.add(vp); sp.add(fp); if(!sp.link(gl, System.err)) { @@ -939,7 +939,7 @@ public class MacOSXCGLContext extends GLContextImpl if(0 == cglCtx) { throw new InternalError("Null CGLContext for: "+this); } - int err = CGL.CGLLockContext(cglCtx); + final int err = CGL.CGLLockContext(cglCtx); if(CGL.kCGLNoError == err) { validatePBufferConfig(ctx); // required to handle pbuffer change ASAP return CGL.makeCurrentContext(ctx); @@ -1000,6 +1000,8 @@ public class MacOSXCGLContext extends GLContextImpl CGL.setNSOpenGLLayerSwapInterval(l, interval); if( 0 < interval ) { vsyncTimeout = interval * screenVSyncTimeout + 1000; // +1ms + } else { + vsyncTimeout = 1 * screenVSyncTimeout + 1000; // +1ms } if(DEBUG) { System.err.println("NS setSwapInterval: "+interval+" -> "+vsyncTimeout+" micros"); } } @@ -1008,6 +1010,14 @@ public class MacOSXCGLContext extends GLContextImpl } private int skipSync=0; + /** TODO: Remove after discussion + private boolean perfIterReset = false; + private int perfIter = 0; + private long waitGLS = 0; + private long finishGLS = 0; + private long frameXS = 0; + private long lastFrameStart = 0; + */ @Override public boolean swapBuffers() { @@ -1036,6 +1046,45 @@ public class MacOSXCGLContext extends GLContextImpl res = CGL.flushBuffer(contextHandle); if(res) { if(0 == skipSync) { + /** TODO: Remove after discussion + perfIter++; + if( !perfIterReset && 100 == perfIter ) { + perfIterReset = true; + perfIter = 1; + waitGLS = 0; + finishGLS = 0; + frameXS = 0; + } + final long lastFramePeriod0 = TimeUnit.NANOSECONDS.toMicros(System.nanoTime()) - lastFrameStart; + gl.glFinish(); // Require to finish previous GL rendering to give CALayer proper result + final long lastFramePeriod1 = TimeUnit.NANOSECONDS.toMicros(System.nanoTime()) - lastFrameStart; + + // If v-sync is disabled, frames will be drawn as quickly as possible w/o delay, + // while still synchronizing w/ CALayer. + // If v-sync is enabled wait until next swap interval (v-sync). + CGL.waitUntilNSOpenGLLayerIsReady(cmd.nsOpenGLLayer, vsyncTimeout); + final long lastFramePeriodX = TimeUnit.NANOSECONDS.toMicros(System.nanoTime()) - lastFrameStart; + + final long finishGL = lastFramePeriod1 - lastFramePeriod0; + final long waitGL = lastFramePeriodX - lastFramePeriod1; + finishGLS += finishGL; + waitGLS += waitGL; + frameXS += lastFramePeriodX; + + System.err.println("XXX["+perfIter+"] TO "+vsyncTimeout/1000+" ms, "+ + "lFrame0 "+lastFramePeriod0/1000+" ms, "+ + "lFrameX "+lastFramePeriodX/1000+" / "+frameXS/1000+" ~"+(frameXS/perfIter)/1000.0+" ms, "+ + "finishGL "+finishGL/1000+" / "+finishGLS/1000+" ~"+(finishGLS/perfIter)/1000.0+" ms, "+ + "waitGL "+waitGL/1000+" / "+waitGLS/1000+" ~"+(waitGLS/perfIter)/1000.0+" ms"); + */ + // + // Required(?) to finish previous GL rendering to give CALayer proper result, + // i.e. synchronize both threads each w/ their GLContext sharing same resources. + // + // FIXME: IMHO this synchronization should be implicitly performed via 'CGL.flushBuffer(contextHandle)' above, + // in case this will be determined a driver bug - use a QUIRK entry in GLRendererQuirks! + gl.glFinish(); + // If v-sync is disabled, frames will be drawn as quickly as possible w/o delay, // while still synchronizing w/ CALayer. // If v-sync is enabled wait until next swap interval (v-sync). @@ -1050,6 +1099,7 @@ public class MacOSXCGLContext extends GLContextImpl // trigger CALayer to update incl. possible surface change (new pbuffer handle) CGL.setNSOpenGLLayerNeedsDisplayPBuffer(cmd.nsOpenGLLayer, drawable.getHandle()); } + // lastFrameStart = TimeUnit.NANOSECONDS.toMicros(System.nanoTime()); } } else { res = true; diff --git a/src/jogl/classes/jogamp/opengl/openal/av/ALDummyUsage.java b/src/jogl/classes/jogamp/opengl/openal/av/ALDummyUsage.java new file mode 100644 index 000000000..69223d0b9 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/openal/av/ALDummyUsage.java @@ -0,0 +1,19 @@ +package jogamp.opengl.openal.av; + +import jogamp.opengl.util.av.impl.FFMPEGMediaPlayer; + +import com.jogamp.openal.AL; +import com.jogamp.openal.JoalVersion; + +/** + * Demo JOAL usage w/ av dependency, i.e. FFMPEGMediaPlayer .. + */ +public class ALDummyUsage { + static AL al; + static FFMPEGMediaPlayer.PixelFormat pfmt; + + public static void main(String args[]) { + System.err.println("JOGL> Hello JOAL"); + System.err.println("JOAL: "+JoalVersion.getInstance().toString()); + } +} diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java index 35342669f..0971ac78e 100644 --- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java +++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java @@ -28,6 +28,8 @@ package jogamp.opengl.util.av.impl; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -133,7 +135,10 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo { static boolean initSingleton() { return ready; } private static boolean initSymbols() { - final DynamicLibraryBundle dl = new DynamicLibraryBundle(new FFMPEGDynamicLibraryBundleInfo()); + final DynamicLibraryBundle dl = AccessController.doPrivileged(new PrivilegedAction<DynamicLibraryBundle>() { + public DynamicLibraryBundle run() { + return new DynamicLibraryBundle(new FFMPEGDynamicLibraryBundleInfo()); + } } ); final boolean avutilLoaded = dl.isToolLibLoaded(0); final boolean avformatLoaded = dl.isToolLibLoaded(1); final boolean avcodecLoaded = dl.isToolLibLoaded(2); diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLTextureRaster.java b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLTextureRaster.java index 20c251635..eaf8dc30a 100644 --- a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLTextureRaster.java +++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLTextureRaster.java @@ -69,8 +69,8 @@ public class GLSLTextureRaster { shaderSrcPath, shaderBinPath, shaderBasename, true); final ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), shaderSrcPath, shaderBinPath, shaderBasename, true); - rsVp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp); - rsFp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp); + rsVp.defaultShaderCustomization(gl, true, true); + rsFp.defaultShaderCustomization(gl, true, true); // Create & Link the shader program sp = new ShaderProgram(); diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java index cc58f2363..f4f20ac7c 100644 --- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java +++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java @@ -943,8 +943,8 @@ public class FixedFuncPipeline { private static final String constMaxTextures8 = "#define MAX_TEXTURE_UNITS 8\n"; private final void customizeShader(GL2ES2 gl, ShaderCode vp, ShaderCode fp, String maxTextureDefine) { - int rsVpPos = vp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp); - int rsFpPos = fp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp); + int rsVpPos = vp.defaultShaderCustomization(gl, true, true); + int rsFpPos = fp.defaultShaderCustomization(gl, true, true); vp.insertShaderSource(0, rsVpPos, maxTextureDefine); fp.insertShaderSource(0, rsFpPos, maxTextureDefine); } diff --git a/src/jogl/classes/jogamp/opengl/util/jpeg/JPEGDecoder.java b/src/jogl/classes/jogamp/opengl/util/jpeg/JPEGDecoder.java index 251291a14..833771dd1 100644 --- a/src/jogl/classes/jogamp/opengl/util/jpeg/JPEGDecoder.java +++ b/src/jogl/classes/jogamp/opengl/util/jpeg/JPEGDecoder.java @@ -301,13 +301,15 @@ public class JPEGDecoder { private final ArrayHashSet<Integer> compIDs; private final ComponentIn[] comps; private final int compCount; + /** quantization tables */ + final int[][] qtt; int maxCompID; int maxH; int maxV; int mcusPerLine; int mcusPerColumn; - Frame(boolean progressive, int precision, int scanLines, int samplesPerLine, int componentsCount) { + Frame(boolean progressive, int precision, int scanLines, int samplesPerLine, int componentsCount, int[][] qtt) { this.progressive = progressive; this.precision = precision; this.scanLines = scanLines; @@ -315,6 +317,7 @@ public class JPEGDecoder { compIDs = new ArrayHashSet<Integer>(componentsCount); comps = new ComponentIn[componentsCount]; this.compCount = componentsCount; + this.qtt = qtt; } private final void checkBounds(int idx) { @@ -322,6 +325,17 @@ public class JPEGDecoder { throw new CodecException("Idx out of bounds "+idx+", "+this); } } + public final void validateComponents() { + for(int i=0; i<compCount; i++) { + final ComponentIn c = comps[i]; + if( null == c ) { + throw new CodecException("Component["+i+"] null"); + } + if( null == this.qtt[c.qttIdx] ) { + throw new CodecException("Component["+i+"].qttIdx -> null QTT"); + } + } + } public final int getCompCount() { return compCount; } public final int getMaxCompID() { return maxCompID; } @@ -357,7 +371,8 @@ public class JPEGDecoder { /** The JPEG encoded components */ class ComponentIn { final int h, v; - final int[] quantizationTable; + /** index to frame.qtt[] */ + final int qttIdx; int blocksPerColumn; int blocksPerColumnForMcu; int blocksPerLine; @@ -368,10 +383,10 @@ public class JPEGDecoder { BinObj huffmanTableAC; BinObj huffmanTableDC; - ComponentIn(int h, int v, int[] quantizationTable) { + ComponentIn(int h, int v, int qttIdx) { this.h = h; this.v = v; - this.quantizationTable = quantizationTable; + this.qttIdx = qttIdx; } public final void allocateBlocks(int blocksPerColumn, int blocksPerColumnForMcu, int blocksPerLine, int blocksPerLineForMcu) { @@ -389,7 +404,7 @@ public class JPEGDecoder { } public final String toString() { - return "CompIn[h "+h+", v "+v+", blocks["+blocksPerColumn+", mcu "+blocksPerColumnForMcu+"]["+blocksPerLine+", mcu "+blocksPerLineForMcu+"][64]]"; + return "CompIn[h "+h+", v "+v+", qttIdx "+qttIdx+", blocks["+blocksPerColumn+", mcu "+blocksPerColumnForMcu+"]["+blocksPerLine+", mcu "+blocksPerLineForMcu+"][64]]"; } } @@ -526,12 +541,14 @@ public class JPEGDecoder { } public synchronized JPEGDecoder parse(final InputStream inputStream) throws IOException { clear(inputStream); - Frame frame = null; - int resetInterval = 0; - int[][] quantizationTables = new int[0x0F][]; // 4 bits - ArrayList<Frame> frames = new ArrayList<Frame>(); + + final int[][] quantizationTables = new int[0x0F][]; // 4 bits final BinObj[] huffmanTablesAC = new BinObj[0x0F]; // Huffman table spec - 4 bits final BinObj[] huffmanTablesDC = new BinObj[0x0F]; // Huffman table spec - 4 bits + // final ArrayList<Frame> frames = new ArrayList<Frame>(); // JAU: max 1-frame + + Frame frame = null; + int resetInterval = 0; int fileMarker = readUint16(); if ( fileMarker != M_SOI ) { throw new CodecException("SOI not found, but has marker "+toHexString(fileMarker)); @@ -579,6 +596,7 @@ public class JPEGDecoder { while( count < quantizationTablesLength ) { final int quantizationTableSpec = readUint8(); count++; final int precisionID = quantizationTableSpec >> 4; + final int tableIdx = quantizationTableSpec & 0x0F; final int[] tableData = new int[64]; if ( precisionID == 0 ) { // 8 bit values for (int j = 0; j < 64; j++) { @@ -591,12 +609,15 @@ public class JPEGDecoder { tableData[z] = readUint16(); count+=2; } } else { - throw new CodecException("DQT: invalid table precision "+precisionID+", quantizationTableSpec "+quantizationTableSpec); + throw new CodecException("DQT: invalid table precision "+precisionID+", quantizationTableSpec "+quantizationTableSpec+", idx "+tableIdx); } - quantizationTables[quantizationTableSpec & 0x0F] = tableData; + quantizationTables[tableIdx] = tableData; + if( DEBUG ) { + System.err.println("JPEG.parse.QTT["+tableIdx+"]: spec "+quantizationTableSpec+", precision "+precisionID+", data "+count+"/"+quantizationTablesLength); + } } if(count!=quantizationTablesLength){ - throw new CodecException("ERROR: QTT format error [count!=Length]"); + throw new CodecException("ERROR: QTT format error [count!=Length]: "+count+"/"+quantizationTablesLength); } fileMarker = 0; // consumed and get-next } @@ -604,6 +625,9 @@ public class JPEGDecoder { case M_SOF0: case M_SOF2: { + if( null != frame ) { // JAU: max 1-frame + throw new CodecException("only single frame JPEGs supported"); + } int count = 0; final int sofLen = readUint16(); count+=2; // header length; final int componentsCount; @@ -613,7 +637,7 @@ public class JPEGDecoder { final int scanLines = readUint16(); count+=2; final int samplesPerLine = readUint16(); count+=2; componentsCount = readUint8(); count++; - frame = new Frame(progressive, precision, scanLines, samplesPerLine, componentsCount); + frame = new Frame(progressive, precision, scanLines, samplesPerLine, componentsCount, quantizationTables); width = frame.samplesPerLine; height = frame.scanLines; } @@ -622,14 +646,15 @@ public class JPEGDecoder { final int temp = readUint8(); count++; final int h = temp >> 4; final int v = temp & 0x0F; - final int qId = readUint8(); count++; - frame.putOrdered(componentId, new ComponentIn(h, v, quantizationTables[qId])); + final int qttIdx = readUint8(); count++; + final ComponentIn compIn = new ComponentIn(h, v, qttIdx); + frame.putOrdered(componentId, compIn); } if(count!=sofLen){ throw new CodecException("ERROR: SOF format error [count!=Length]"); } prepareComponents(frame); - frames.add(frame); + // frames.add(frame); // JAU: max 1-frame if(DEBUG) { System.err.println("JPG.parse.SOF[02]: Got frame "+frame); } fileMarker = 0; // consumed and get-next } @@ -711,14 +736,21 @@ public class JPEGDecoder { } } if(DEBUG) { System.err.println("JPG.parse.2: End of parsing input "+this); } + /** // JAU: max 1-frame if ( frames.size() != 1 ) { - throw new CodecException("only single frame JPEGs supported"); + throw new CodecException("only single frame JPEGs supported "+this); + } */ + if( null == frame ) { + throw new CodecException("no single frame found in stream "+this); } + frame.validateComponents(); final int compCount = frame.getCompCount(); this.components = new ComponentOut[compCount]; for (int i = 0; i < compCount; i++) { final ComponentIn component = frame.getCompByIndex(i); + // System.err.println("JPG.parse.buildComponentData["+i+"]: "+component); // JAU + // System.err.println("JPG.parse.buildComponentData["+i+"]: "+frame); // JAU this.components[i] = new ComponentOut( output.buildComponentData(frame, component), (float)component.h / (float)frame.maxH, (float)component.v / (float)frame.maxV ); @@ -834,12 +866,14 @@ public class JPEGDecoder { final byte[] r = new byte[64]; for (int blockRow = 0; blockRow < blocksPerColumn; blockRow++) { - int scanLine = blockRow << 3; + final int scanLine = blockRow << 3; + // System.err.println("JPG.buildComponentData: row "+blockRow+"/"+blocksPerColumn+" -> scanLine "+scanLine); // JAU for (int i = 0; i < 8; i++) { lines.add(new byte[samplesPerLine]); } for (int blockCol = 0; blockCol < blocksPerLine; blockCol++) { - quantizeAndInverse(component.getBlock(blockRow, blockCol), r, R, component.quantizationTable); + // System.err.println("JPG.buildComponentData: col "+blockCol+"/"+blocksPerLine+", comp.qttIdx "+component.qttIdx+", qtt "+frame.qtt[component.qttIdx]); // JAU + quantizeAndInverse(component.getBlock(blockRow, blockCol), r, R, frame.qtt[component.qttIdx]); final int sample = blockCol << 3; int offset = 0; diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDynamicLibraryBundleInfo.java index 108c157a8..6083f209c 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDynamicLibraryBundleInfo.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDynamicLibraryBundleInfo.java @@ -60,15 +60,6 @@ public class X11GLXDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBundl return libsList; } - /** - * This respects old DRI requirements:<br> - * <pre> - * http://dri.sourceforge.net/doc/DRIuserguide.html - * </pre> - */ - @Override - public boolean shallLinkGlobal() { return true; } - @Override public final List<String> getToolGetProcAddressFuncNameList() { List<String> res = new ArrayList<String>(); |