summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/jogamp
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/jogamp')
-rw-r--r--src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java12
-rw-r--r--src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java11
-rw-r--r--src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java39
-rw-r--r--src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java14
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java826
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java82
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java18
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableHelper.java106
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableImpl.java8
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java10
-rw-r--r--src/jogl/classes/jogamp/opengl/GLRunnableTask.java5
-rw-r--r--src/jogl/classes/jogamp/opengl/GLWorkerThread.java26
-rw-r--r--src/jogl/classes/jogamp/opengl/GLXExtensions.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/SharedResourceRunner.java136
-rw-r--r--src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java11
-rw-r--r--src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java5
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLContext.java104
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java32
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java698
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java8
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java18
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLSurface.java12
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java42
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java29
-rw-r--r--src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java22
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java193
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/VideoPixelFormat.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java22
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java59
-rw-r--r--src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.fp6
-rw-r--r--src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorTexture.fp12
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java99
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java65
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java19
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java5
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java125
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java63
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java15
41 files changed, 1933 insertions, 1042 deletions
diff --git a/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java b/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java
index e4b0cb2a8..78140df6f 100644
--- a/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java
+++ b/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java
@@ -52,7 +52,6 @@ public class UbuntuFontLoader implements FontSet {
private static final Uri.Encoded jarSubDir = Uri.Encoded.cast("atomic/");
private static final Uri.Encoded jarName = Uri.Encoded.cast("jogl-fonts-p0.jar");
- private static final String relFontPath = "fonts/ubuntu/" ;
private static final String absFontPath = "jogamp/graph/font/fonts/ubuntu/" ;
private static final FontSet fontLoader = new UbuntuFontLoader();
@@ -137,7 +136,7 @@ public class UbuntuFontLoader implements FontSet {
if( !attemptedJARLoading ) {
attemptedJARLoading = true;
Platform.initSingleton();
- if( TempJarCache.isInitialized() ) {
+ if( TempJarCache.isInitialized(false) ) {
try {
final Uri uri = JarUtil.getRelativeOf(UbuntuFontLoader.class, jarSubDir, jarName);
final Exception e0 = AccessController.doPrivileged(new PrivilegedAction<Exception>() {
@@ -160,15 +159,14 @@ public class UbuntuFontLoader implements FontSet {
}
}
}
- final String path = useTempJARCache ? absFontPath : relFontPath;
try {
- final Font f = abspathImpl(path+fname, family, style);
+ final Font f = abspathImpl(absFontPath+fname, family, style);
if( null != f ) {
return f;
}
- throw new IOException(String.format("Problem loading font %s, stream %s%s", fname, path, fname));
+ throw new IOException(String.format("Problem loading font %s, stream %s%s", fname, absFontPath, fname));
} catch(final Exception e) {
- throw new IOException(String.format("Problem loading font %s, stream %s%s", fname, path, fname), e);
+ throw new IOException(String.format("Problem loading font %s, stream %s%s", fname, absFontPath, fname), e);
}
}
private Font abspathImpl(final String fname, final int family, final int style) throws IOException {
@@ -190,7 +188,7 @@ public class UbuntuFontLoader implements FontSet {
throw new IOException(privErr[0]);
}
} else {
- final URLConnection urlConn = IOUtil.getResource(UbuntuFontLoader.class, fname);
+ final URLConnection urlConn = IOUtil.getResource(fname, getClass().getClassLoader(), null);
stream = null != urlConn ? urlConn.getInputStream() : null;
}
if(null != stream) {
diff --git a/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java b/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java
index 6025b45ff..5eb429774 100644
--- a/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java
+++ b/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java
@@ -48,7 +48,7 @@ public class DesktopGLDynamicLookupHelper extends GLDynamicLookupHelper {
gluLibNames.add("libGLU.so"); // unix
gluLibNames.add("GLU32"); // windows
gluLibNames.add("GLU"); // generic
- gluLib = loadFirstAvailable(gluLibNames, null, true);
+ gluLib = loadFirstAvailable(gluLibNames, true, true, null, true);
if(null != gluLib) {
nativeLibraries.add(gluLib);
}
diff --git a/src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java b/src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java
index 331414869..b28b79418 100644
--- a/src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java
+++ b/src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java
@@ -45,7 +45,6 @@ import java.util.StringTokenizer;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2ES3;
-import com.jogamp.opengl.GL2GL3;
import com.jogamp.opengl.GLContext;
import com.jogamp.common.util.VersionNumber;
@@ -138,9 +137,9 @@ final class ExtensionAvailabilityCache {
boolean useGetStringi = false;
- // Use 'glGetStringi' only for ARB GL3 context,
+ // Use 'glGetStringi' only for ARB GL3 and ES3 context,
// on GL2 platforms the function might be available, but not working.
- if ( context.isGL3() ) {
+ if ( context.isGL3() || context.isGLES3() ) {
if ( ! context.isFunctionAvailable("glGetStringi") ) {
if(DEBUG) {
System.err.println("GLContext: GL >= 3.1 usage, but no glGetStringi");
@@ -156,16 +155,16 @@ final class ExtensionAvailabilityCache {
}
if(useGetStringi) {
- final GL2GL3 gl2gl3 = gl.getGL2GL3();
+ final GL2ES3 gl2es3 = (GL2ES3)gl; // validated via context - OK!
final int count;
{
final int[] val = { 0 } ;
- gl2gl3.glGetIntegerv(GL2ES3.GL_NUM_EXTENSIONS, val, 0);
+ gl2es3.glGetIntegerv(GL2ES3.GL_NUM_EXTENSIONS, val, 0);
count = val[0];
}
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; i++) {
- final String ext = gl2gl3.glGetStringi(GL.GL_EXTENSIONS, i);
+ final String ext = gl2es3.glGetStringi(GL.GL_EXTENSIONS, i);
if( null == availableExtensionCache.put(ext, ext) ) {
// new one
if( 0 < i ) {
diff --git a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
index 19fd6c7e1..9d1490300 100644
--- a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
+++ b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
@@ -51,6 +51,7 @@ import com.jogamp.opengl.GLRunnable;
import com.jogamp.opengl.GLSharedContextSetter;
import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.RunnableTask;
import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.opengl.GLAutoDrawableDelegate;
import com.jogamp.opengl.GLEventListenerState;
@@ -598,6 +599,44 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, GLStateKeepe
return helper.getExclusiveContextThread();
}
+ /**
+ * Invokes given {@code runnable} on current thread outside of a probable claimed exclusive thread,
+ * i.e. releases the exclusive thread, executes the runnable and reclaims it.
+ * FIXME: Promote to GLAutoDrawable!
+ *
+ * @param runnable the {@link Runnable} to execute on the new thread.
+ * The runnable <b>must exit</b>, i.e. not loop forever.
+ *
+ * @see #setExclusiveContextThread(Thread, GLContext)
+ *
+ * @since 2.3.2
+ */
+ public final void invokeOnCurrentThread(final Runnable runnable) {
+ helper.runOutsideOfExclusiveContextThread(context, runnable);
+ }
+ /**
+ * Invokes given {@code runnable} on current thread outside of a probable claimed exclusive thread,
+ * i.e. releases the exclusive thread, executes the runnable and reclaims it.
+ * FIXME: Promote to GLAutoDrawable!
+ *
+ * @param tg the {@link ThreadGroup} for the new thread, maybe <code>null</code>
+ * @param waitUntilDone if <code>true</code>, waits until <code>runnable</code> execution is completed, otherwise returns immediately.
+ * @param runnable the {@link Runnable} to execute on the new thread.
+ * The runnable <b>must exit</b>, i.e. not loop forever.
+ * @return {@link RunnableTask} instance with execution details
+ *
+ * @see #setExclusiveContextThread(Thread, GLContext)
+ *
+ * @since 2.3.2
+ */
+ public final RunnableTask invokeOnNewThread(final ThreadGroup tg, final boolean waitUntilDone, final Runnable runnable) {
+ return RunnableTask.invokeOnNewThread(tg, null, waitUntilDone,
+ new Runnable() {
+ public final void run() {
+ helper.runOutsideOfExclusiveContextThread(context, runnable);
+ } });
+ }
+
@Override
public final boolean invoke(final boolean wait, final GLRunnable glRunnable) throws IllegalStateException {
return helper.invoke(this, wait, glRunnable);
diff --git a/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java b/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
index 2aa4c4297..a5bd85eb1 100644
--- a/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
+++ b/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
@@ -40,9 +40,13 @@
package jogamp.opengl;
-import com.jogamp.opengl.*;
import com.jogamp.common.util.IntIntHashMap;
import com.jogamp.common.util.PropertyAccess;
+import com.jogamp.opengl.GL;
+import com.jogamp.opengl.GL2ES3;
+import com.jogamp.opengl.GL3ES3;
+import com.jogamp.opengl.GL4;
+import com.jogamp.opengl.GLException;
/**
* Tracks as closely as possible which OpenGL buffer object is bound
@@ -119,6 +123,8 @@ public class GLBufferStateTracker {
* GL_ELEMENT_ARRAY_BUFFER​,
* GL_PIXEL_PACK_BUFFER​,
* GL_PIXEL_UNPACK_BUFFER​,
+ * GL_QUERY_BUFFER,
+ * GL_PARAMETER_BUFFER_ARB,
* GL_SHADER_STORAGE_BUFFER​,
* GL_TEXTURE_BUFFER​,
* GL_TRANSFORM_FEEDBACK_BUFFER​ or
@@ -139,8 +145,9 @@ public class GLBufferStateTracker {
case GL2ES3.GL_PIXEL_PACK_BUFFER: return GL2ES3.GL_PIXEL_PACK_BUFFER_BINDING;
case GL2ES3.GL_PIXEL_UNPACK_BUFFER: return GL2ES3.GL_PIXEL_UNPACK_BUFFER_BINDING;
case GL4.GL_QUERY_BUFFER: return GL4.GL_QUERY_BUFFER_BINDING;
+ case GL4.GL_PARAMETER_BUFFER_ARB: return GL4.GL_PARAMETER_BUFFER_BINDING_ARB; // ARB_indirect_parameters
case GL3ES3.GL_SHADER_STORAGE_BUFFER: return GL3ES3.GL_SHADER_STORAGE_BUFFER_BINDING;
- case GL2GL3.GL_TEXTURE_BUFFER: return GL2GL3.GL_TEXTURE_BINDING_BUFFER;
+ case GL2ES3.GL_TEXTURE_BUFFER: return GL2ES3.GL_TEXTURE_BINDING_BUFFER;
case GL2ES3.GL_TRANSFORM_FEEDBACK_BUFFER: return GL2ES3.GL_TRANSFORM_FEEDBACK_BUFFER_BINDING;
case GL2ES3.GL_UNIFORM_BUFFER: return GL2ES3.GL_UNIFORM_BUFFER_BINDING;
@@ -162,8 +169,9 @@ public class GLBufferStateTracker {
case GL2ES3.GL_PIXEL_PACK_BUFFER:
case GL2ES3.GL_PIXEL_UNPACK_BUFFER:
case GL4.GL_QUERY_BUFFER:
+ case GL4.GL_PARAMETER_BUFFER_ARB: // ARB_indirect_parameters
case GL3ES3.GL_SHADER_STORAGE_BUFFER:
- case GL2GL3.GL_TEXTURE_BUFFER:
+ case GL2ES3.GL_TEXTURE_BUFFER:
case GL2ES3.GL_TRANSFORM_FEEDBACK_BUFFER:
case GL2ES3.GL_UNIFORM_BUFFER:
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index 8f4105f98..6866374bc 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -45,7 +45,10 @@ import java.nio.IntBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.os.DynamicLookupHelper;
@@ -59,12 +62,12 @@ import com.jogamp.gluegen.runtime.opengl.GLNameResolver;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
import com.jogamp.opengl.GLExtensions;
import com.jogamp.opengl.GLRendererQuirks;
-
import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
import com.jogamp.nativewindow.AbstractGraphicsDevice;
import com.jogamp.nativewindow.NativeSurface;
import com.jogamp.nativewindow.NativeWindowFactory;
import com.jogamp.nativewindow.ProxySurface;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2ES2;
import com.jogamp.opengl.GL2ES3;
@@ -126,11 +129,13 @@ public abstract class GLContextImpl extends GLContext {
* If GL >= 3.0 (ES or desktop) and not having {@link GLRendererQuirks#NoSurfacelessCtx},
* being evaluated if not surface-handle is null and not yet set at makeCurrent(..).
*/
- private boolean surfacelessOK = false;
+ private boolean isSurfaceless = false;
private boolean pixelDataEvaluated;
private int /* pixelDataInternalFormat, */ pixelDataFormat, pixelDataType;
+ private int currentSwapInterval;
+
protected GL gl;
protected static final Object mappedContextTypeObjectLock;
@@ -207,8 +212,9 @@ public abstract class GLContextImpl extends GLContext {
boundFBOTarget[1] = 0; // read
}
- surfacelessOK = false;
+ isSurfaceless = false;
pixelDataEvaluated = false;
+ currentSwapInterval = 0;
super.resetStates(isInit);
}
@@ -536,7 +542,7 @@ public abstract class GLContextImpl extends GLContext {
//----------------------------------------------------------------------
//
- protected final boolean isSurfacelessOK() { return surfacelessOK; }
+ protected final boolean isSurfaceless() { return isSurfaceless; }
/**
* {@inheritDoc}
@@ -607,7 +613,7 @@ public abstract class GLContextImpl extends GLContext {
if ( drawable.isRealized() ) {
lock.lock();
try {
- if ( 0 == drawable.getHandle() && !surfacelessOK ) {
+ if ( 0 == drawable.getHandle() && !isSurfaceless ) {
if( DEBUG ) {
System.err.println(getThreadName() +": GLContext.makeCurrent: Surfaceless evaluate");
}
@@ -671,7 +677,7 @@ public abstract class GLContextImpl extends GLContext {
}
if ( CONTEXT_NOT_CURRENT != res ) { // still locked!
- if( 0 == drawable.getHandle() && !surfacelessOK ) {
+ if( 0 == drawable.getHandle() && !isSurfaceless ) {
if( hasRendererQuirk(GLRendererQuirks.NoSurfacelessCtx) ) {
throw new GLException(String.format("Surfaceless not supported due to quirk %s: %s",
GLRendererQuirks.toString(GLRendererQuirks.NoSurfacelessCtx), toString()));
@@ -679,15 +685,15 @@ public abstract class GLContextImpl extends GLContext {
if( DEBUG ) {
System.err.println(getThreadName() +": GLContext.makeCurrent: Surfaceless OK - validated");
}
- surfacelessOK = true;
+ isSurfaceless = true;
}
setCurrent(this);
if( CONTEXT_CURRENT_NEW == res ) {
// check if the drawable's and the GL's GLProfile are equal
// throws an GLException if not
- drawable.getGLProfile().verifyEquality(gl.getGLProfile());
+ // FIXME: drawable.getGLProfile().verifyEquality(gl.getGLProfile());
- glDebugHandler.init( isGL2GL3() && isGLDebugEnabled() );
+ glDebugHandler.init( isGLDebugEnabled() );
if(DEBUG_GL) {
setGL( GLPipelineFactory.create("com.jogamp.opengl.Debug", null, gl, null) );
@@ -802,28 +808,28 @@ public abstract class GLContextImpl extends GLContext {
reqProfile = GLContext.CTX_PROFILE_COMPAT;
isCompat = true;
}
- GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ final MappedGLVersion me = mapAvailableGLVersion(device, reqMajor, reqProfile, ctxVersion, ctxOptions, glRendererQuirks);
// Perform all required profile mappings
if( isCompat ) {
// COMPAT via non ARB
- GLContext.mapAvailableGLVersion(device, reqMajor, GLContext.CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ mapAvailableGLVersion(device, reqMajor, GLContext.CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks);
if( reqMajor >= 4 ) {
- GLContext.mapAvailableGLVersion(device, 3, reqProfile, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
- GLContext.mapAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ mapAvailableGLVersion(device, 3, reqProfile, ctxVersion, ctxOptions, glRendererQuirks);
+ mapAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks);
}
if( reqMajor >= 3 ) {
- GLContext.mapAvailableGLVersion(device, 2, reqProfile, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ mapAvailableGLVersion(device, 2, reqProfile, ctxVersion, ctxOptions, glRendererQuirks);
}
} else {
// CORE via non ARB, unlikely, however ..
if( reqMajor >= 4 ) {
- GLContext.mapAvailableGLVersion(device, 3, reqProfile, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ mapAvailableGLVersion(device, 3, reqProfile, ctxVersion, ctxOptions, glRendererQuirks);
}
}
GLContext.setAvailableGLVersionsSet(device, true);
if (DEBUG) {
- System.err.println(getThreadName() + ": createContextOLD-MapVersionsAvailable HAVE: " + device+" -> "+reqMajor+"."+reqProfile+ " -> "+getGLVersion());
+ System.err.println(getThreadName() + ": createContextOLD-MapGLVersions HAVE: " + me);
}
}
}
@@ -947,13 +953,13 @@ public abstract class GLContextImpl extends GLContext {
{
final AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice device = config.getScreen().getDevice();
- if (DEBUG) {
- System.err.println(getThreadName() + ": createContextARB: mappedVersionsAvailableSet("+device.getConnection()+"): "+
- GLContext.getAvailableGLVersionsSet(device));
- }
final GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
final GLProfile glp = glCaps.getGLProfile();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions is SET ("+device.getConnection()+"): "+
+ GLContext.getAvailableGLVersionsSet(device));
+ }
if ( !GLContext.getAvailableGLVersionsSet(device) ) {
if( !mapGLVersions(device) ) {
// none of the ARB context creation calls was successful, bail out
@@ -965,7 +971,7 @@ public abstract class GLContextImpl extends GLContext {
GLContext.getRequestMajorAndCompat(glp, reqMajorCTP);
if(DEBUG) {
- System.err.println(getThreadName() + ": createContextARB: Requested "+glp+" -> "+GLContext.getGLVersion(reqMajorCTP[0], 0, reqMajorCTP[1], null));
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions Requested "+glp+" -> "+GLContext.getGLVersion(reqMajorCTP[0], 0, reqMajorCTP[1], null));
}
final int _major[] = { 0 };
final int _minor[] = { 0 };
@@ -975,7 +981,7 @@ public abstract class GLContextImpl extends GLContext {
_major, _minor, _ctp)) {
_ctp[0] |= additionalCtxCreationFlags;
if(DEBUG) {
- System.err.println(getThreadName() + ": createContextARB: Mapped "+GLContext.getGLVersion(_major[0], _minor[0], _ctp[0], null));
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions Mapped "+GLContext.getGLVersion(_major[0], _minor[0], _ctp[0], null));
}
_ctx = createContextARBImpl(share, direct, _ctp[0], _major[0], _minor[0]);
if(0!=_ctx) {
@@ -987,8 +993,156 @@ public abstract class GLContextImpl extends GLContext {
return _ctx;
}
+ //----------------------------------------------------------------------
+ //
+
+ public static class MappedGLVersion {
+ public final AbstractGraphicsDevice device;
+ public final int reqMajorVersion;
+ public final int reqProfile;
+ public final VersionNumber ctxVersion;
+ public final int ctxOptions;
+ public final GLRendererQuirks quirks;
+ public final VersionNumber preCtxVersion;
+ public final int preCtxOptions;
+ public MappedGLVersion(final AbstractGraphicsDevice device, final int reqMajorVersion, final int reqProfile,
+ final VersionNumber ctxVersion, final int ctxOptions, final GLRendererQuirks quirks,
+ final VersionNumber preCtxVersion, final int preCtxOptions) {
+ this.device = device;
+ this.reqMajorVersion = reqMajorVersion;
+ this.reqProfile = reqProfile;
+ this.ctxVersion = ctxVersion;
+ this.ctxOptions = ctxOptions;
+ this.quirks = quirks;
+ this.preCtxVersion = preCtxVersion;
+ this.preCtxOptions = preCtxOptions;
+ }
+ public final String toString() {
+ return toString(new StringBuilder(), -1, -1, -1, -1).toString();
+ }
+ public final StringBuilder toString(final StringBuilder sb, final int minMajor, final int minMinor, final int maxMajor, final int maxMinor) {
+ sb.append(device.toString()).append(" ").append(reqMajorVersion).append(" (");
+ GLContext.getGLProfile(sb, reqProfile).append(")");
+ if( minMajor >=0 && minMinor >=0 && maxMajor >= 0 && maxMinor >= 0) {
+ sb.append("[").append(minMajor).append(".").append(minMinor).append(" .. ").append(maxMajor).append(".").append(maxMinor).append("]");
+ }
+ sb.append(": [");
+ if( null != preCtxVersion ) {
+ GLContext.getGLVersion(sb, preCtxVersion, preCtxOptions, null);
+ } else {
+ sb.append("None");
+ }
+ sb.append("] -> [");
+ GLContext.getGLVersion(sb, ctxVersion, ctxOptions, null).append("]");
+ return sb;
+ }
+ }
+ public static interface MappedGLVersionListener {
+ void glVersionMapped(final MappedGLVersion e);
+ }
+ private static MappedGLVersionListener mapGLVersionListener = null;
+ protected static synchronized void setMappedGLVersionListener(final MappedGLVersionListener mvl) {
+ mapGLVersionListener = mvl;
+ }
+
+ /**
+ * Called by {@link jogamp.opengl.GLContextImpl#createContextARBMapVersionsAvailable(int,int)} not intended to be used by
+ * implementations. However, if {@link jogamp.opengl.GLContextImpl#createContextARB(long, boolean)} is not being used within
+ * {@link com.jogamp.opengl.GLDrawableFactory#getOrCreateSharedContext(com.jogamp.nativewindow.AbstractGraphicsDevice)},
+ * GLProfile has to map the available versions.
+ *
+ * @param reqMajor Key Value either 1, 2, 3 or 4
+ * @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
+ * @param resVersion the resulting version number
+ * @param resCtp the resulting context options
+ * @return the old mapped value
+ *
+ * @see #createContextARBMapVersionsAvailable
+ */
+ protected static MappedGLVersion mapAvailableGLVersion(final AbstractGraphicsDevice device,
+ final int reqMajor, final int profile,
+ final VersionNumber resVersion, final int resCtp,
+ final GLRendererQuirks resQuirks)
+ {
+ final Integer preVal = mapAvailableGLVersion(device, reqMajor, profile, resVersion, resCtp);
+ final int[] preCtp = { 0 };
+ final VersionNumber preVersion = null != preVal ? decomposeBits(preVal.intValue(), preCtp) : null;
+ final MappedGLVersion res = new MappedGLVersion(device, reqMajor, profile, resVersion, resCtp, resQuirks, preVersion, preCtp[0]);
+ if( null != mapGLVersionListener ) {
+ mapGLVersionListener.glVersionMapped(res);
+ }
+ return res;
+ }
+ private static Integer mapAvailableGLVersion(final AbstractGraphicsDevice device,
+ final int reqMajor, final int profile, final VersionNumber resVersion, int resCtp)
+ {
+ validateProfileBits(profile, "profile");
+ validateProfileBits(resCtp, "resCtp");
+
+ if(FORCE_NO_FBO_SUPPORT) {
+ resCtp &= ~CTX_IMPL_FBO ;
+ }
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions MAP "+device+": "+reqMajor+" ("+GLContext.getGLProfile(new StringBuilder(), profile).toString()+ ") -> "+
+ getGLVersion(resVersion.getMajor(), resVersion.getMinor(), resCtp, null));
+ }
+ final String objectKey = getDeviceVersionAvailableKey(device, reqMajor, profile);
+ final Integer val = Integer.valueOf(composeBits(resVersion.getMajor(), resVersion.getMinor(), resCtp));
+ synchronized(deviceVersionAvailable) {
+ return deviceVersionAvailable.put( objectKey, val );
+ }
+ }
+
+
+ protected static void remapAvailableGLVersions(final AbstractGraphicsDevice fromDevice, final AbstractGraphicsDevice toDevice) {
+ if( fromDevice == toDevice || fromDevice.getUniqueID() == toDevice.getUniqueID() ) {
+ return; // NOP
+ }
+ synchronized(deviceVersionAvailable) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions REMAP "+fromDevice+" -> "+toDevice);
+ }
+ final IdentityHashMap<String, Integer> newDeviceVersionAvailable = new IdentityHashMap<String, Integer>();
+ final Set<String> keys = deviceVersionAvailable.keySet();
+ for(final Iterator<String> keyI = keys.iterator(); keyI.hasNext(); ) {
+ final String origKey = keyI.next();
+ final Integer valI = deviceVersionAvailable.get(origKey);
+ if( null != valI ) {
+ if(DEBUG) {
+ final int[] ctp = { 0 };
+ final VersionNumber version = decomposeBits(valI.intValue(), ctp);
+ System.err.println(" MapGLVersions REMAP OLD "+origKey+" -> "+GLContext.getGLVersion(new StringBuilder(), version, ctp[0], null).toString());
+ }
+ newDeviceVersionAvailable.put(origKey, valI);
+ final int devSepIdx = origKey.lastIndexOf('-');
+ if( 0 >= devSepIdx ) {
+ throw new InternalError("device-separator '-' at "+devSepIdx+" of "+origKey);
+ }
+ final String devUniqueID = origKey.substring(0, devSepIdx);
+ if( fromDevice.getUniqueID().equals(devUniqueID) ) {
+ final String profileReq = origKey.substring(devSepIdx);
+ final String newKey = (toDevice.getUniqueID()+profileReq).intern();
+ if(DEBUG) {
+ System.err.println(" MapGLVersions REMAP NEW "+newKey+" -> (ditto)");
+ }
+ newDeviceVersionAvailable.put(newKey, valI);
+ }
+ }
+ }
+ deviceVersionAvailable.clear();
+ deviceVersionAvailable.putAll(newDeviceVersionAvailable);
+ GLContext.setAvailableGLVersionsSet(toDevice, true);
+ }
+ }
+
private final boolean mapGLVersions(final AbstractGraphicsDevice device) {
synchronized (GLContext.deviceVersionAvailable) {
+ final boolean hasOpenGLESSupport = drawable.getFactory().hasOpenGLESSupport();
+ final boolean hasOpenGLDesktopSupport = drawable.getFactory().hasOpenGLDesktopSupport();
+ final boolean hasMinorVersionSupport = drawable.getFactoryImpl().hasMajorMinorCreateContextARB();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions START (GLDesktop "+hasOpenGLDesktopSupport+", GLES "+hasOpenGLESSupport+", minorVersion "+hasMinorVersionSupport+") on "+device);
+ }
final long t0 = ( DEBUG ) ? System.nanoTime() : 0;
boolean success = false;
// Following GLProfile.GL_PROFILE_LIST_ALL order of profile detection { GL4bc, GL3bc, GL2, GL4, GL3, GL2GL3, GLES2, GL2ES2, GLES1, GL2ES1 }
@@ -997,6 +1151,43 @@ public abstract class GLContextImpl extends GLContext {
boolean hasGL2 = false;
boolean hasGL4 = false;
boolean hasGL3 = false;
+ boolean hasES3 = false;
+ boolean hasES2 = false;
+ boolean hasES1 = false;
+
+ if( hasOpenGLESSupport && !GLProfile.disableOpenGLES ) {
+ if( !hasES3) {
+ hasES3 = createContextARBMapVersionsAvailable(device, 3, CTX_PROFILE_ES, hasMinorVersionSupport); // ES3
+ success |= hasES3;
+ if( hasES3 ) {
+ if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ) ) {
+ // Map hw-accel ES3 to all lower core profiles: ES2
+ mapAvailableGLVersion(device, 2, CTX_PROFILE_ES, ctxVersion, ctxOptions, glRendererQuirks);
+ if( PROFILE_ALIASING ) {
+ hasES2 = true;
+ }
+ }
+ resetStates(false); // clean context states, since creation was temporary
+ }
+ }
+ if( !hasES2) {
+ hasES2 = createContextARBMapVersionsAvailable(device, 2, CTX_PROFILE_ES, hasMinorVersionSupport); // ES2
+ success |= hasES2;
+ if( hasES2 ) {
+ if( ctxVersion.getMajor() >= 3 && hasRendererQuirk(GLRendererQuirks.GLES3ViaEGLES2Config)) {
+ mapAvailableGLVersion(device, 3, CTX_PROFILE_ES, ctxVersion, ctxOptions, glRendererQuirks);
+ }
+ resetStates(false); // clean context states, since creation was temporary
+ }
+ }
+ if( !hasES1) {
+ hasES1 = createContextARBMapVersionsAvailable(device, 1, CTX_PROFILE_ES, hasMinorVersionSupport); // ES1
+ success |= hasES1;
+ if( hasES1 ) {
+ resetStates(false); // clean context states, since creation was temporary
+ }
+ }
+ }
// Even w/ PROFILE_ALIASING, try to use true core GL profiles
// ensuring proper user behavior across platforms due to different feature sets!
@@ -1006,31 +1197,31 @@ public abstract class GLContextImpl extends GLContext {
/**
* OSX 10.9 GLRendererQuirks.GL4NeedsGL3Request, quirk is added as usual @ setRendererQuirks(..)
*/
- if( !GLProfile.disableOpenGLCore && !hasGL4 && !hasGL3 ) {
- hasGL3 = createContextARBMapVersionsAvailable(3, CTX_PROFILE_CORE); // GL3
+ if( hasOpenGLDesktopSupport && !GLProfile.disableOpenGLDesktop && !GLProfile.disableOpenGLCore && !hasGL4 && !hasGL3 ) {
+ hasGL3 = createContextARBMapVersionsAvailable(device, 3, CTX_PROFILE_CORE, hasMinorVersionSupport); // GL3
success |= hasGL3;
if( hasGL3 ) {
final boolean isHWAccel = 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions );
if( isHWAccel && ctxVersion.getMajor() >= 4 ) {
// Gotcha: Creating a '3.2' ctx delivers a >= 4 ctx.
- GLContext.mapAvailableGLVersion(device, 4, CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ mapAvailableGLVersion(device, 4, CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks);
hasGL4 = true;
if(DEBUG) {
- System.err.println("Quirk Triggerd: "+GLRendererQuirks.toString(GLRendererQuirks.GL4NeedsGL3Request)+": cause: OS "+Platform.getOSType()+", OS Version "+Platform.getOSVersionNumber());
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions: Quirk Triggerd: "+GLRendererQuirks.toString(GLRendererQuirks.GL4NeedsGL3Request)+": cause: OS "+Platform.getOSType()+", OS Version "+Platform.getOSVersionNumber());
}
}
resetStates(false); // clean the context states, since creation was temporary
}
}
}
- if( !GLProfile.disableOpenGLCore ) {
+ if( hasOpenGLDesktopSupport && !GLProfile.disableOpenGLDesktop && !GLProfile.disableOpenGLCore ) {
if( !hasGL4 ) {
- hasGL4 = createContextARBMapVersionsAvailable(4, CTX_PROFILE_CORE); // GL4
+ hasGL4 = createContextARBMapVersionsAvailable(device, 4, CTX_PROFILE_CORE, hasMinorVersionSupport); // GL4
success |= hasGL4;
if( hasGL4 ) {
if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ) ) {
// Map hw-accel GL4 to all lower core profiles: GL3
- GLContext.mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks);
if( PROFILE_ALIASING ) {
hasGL3 = true;
}
@@ -1039,72 +1230,74 @@ public abstract class GLContextImpl extends GLContext {
}
}
if( !hasGL3 ) {
- hasGL3 = createContextARBMapVersionsAvailable(3, CTX_PROFILE_CORE); // GL3
+ hasGL3 = createContextARBMapVersionsAvailable(device, 3, CTX_PROFILE_CORE, hasMinorVersionSupport); // GL3
success |= hasGL3;
if( hasGL3 ) {
resetStates(false); // clean this context states, since creation was temporary
}
}
}
- if( !hasGL4bc ) {
- hasGL4bc = createContextARBMapVersionsAvailable(4, CTX_PROFILE_COMPAT); // GL4bc
- success |= hasGL4bc;
- if( hasGL4bc ) {
- if( !hasGL4 ) { // last chance .. ignore hw-accel
- GLContext.mapAvailableGLVersion(device, 4, CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
- hasGL4 = true;
- }
- if( !hasGL3 ) { // last chance .. ignore hw-accel
- GLContext.mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
- hasGL3 = true;
- }
- if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ) ) {
- // Map hw-accel GL4bc to all lower compatible profiles: GL3bc, GL2
- GLContext.mapAvailableGLVersion(device, 3, CTX_PROFILE_COMPAT, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
- GLContext.mapAvailableGLVersion(device, 2, CTX_PROFILE_COMPAT, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
- if(PROFILE_ALIASING) {
- hasGL3bc = true;
- hasGL2 = true;
+ if( hasOpenGLDesktopSupport && !GLProfile.disableOpenGLDesktop ) {
+ if( !hasGL4bc ) {
+ hasGL4bc = createContextARBMapVersionsAvailable(device, 4, CTX_PROFILE_COMPAT, hasMinorVersionSupport); // GL4bc
+ success |= hasGL4bc;
+ if( hasGL4bc ) {
+ if( !hasGL4 ) { // last chance .. ignore hw-accel
+ mapAvailableGLVersion(device, 4, CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks);
+ hasGL4 = true;
+ }
+ if( !hasGL3 ) { // last chance .. ignore hw-accel
+ mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks);
+ hasGL3 = true;
+ }
+ if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ) ) {
+ // Map hw-accel GL4bc to all lower compatible profiles: GL3bc, GL2
+ mapAvailableGLVersion(device, 3, CTX_PROFILE_COMPAT, ctxVersion, ctxOptions, glRendererQuirks);
+ mapAvailableGLVersion(device, 2, CTX_PROFILE_COMPAT, ctxVersion, ctxOptions, glRendererQuirks);
+ if(PROFILE_ALIASING) {
+ hasGL3bc = true;
+ hasGL2 = true;
+ }
}
+ resetStates(false); // clean this context states, since creation was temporary
}
- resetStates(false); // clean this context states, since creation was temporary
}
- }
- if( !hasGL3bc ) {
- hasGL3bc = createContextARBMapVersionsAvailable(3, CTX_PROFILE_COMPAT); // GL3bc
- success |= hasGL3bc;
- if( hasGL3bc ) {
- if(!hasGL3) { // last chance .. ignore hw-accel
- GLContext.mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
- hasGL3 = true;
- }
- if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ) ) {
- // Map hw-accel GL3bc to all lower compatible profiles: GL2
- GLContext.mapAvailableGLVersion(device, 2, CTX_PROFILE_COMPAT, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
- if(PROFILE_ALIASING) {
- hasGL2 = true;
+ if( !hasGL3bc ) {
+ hasGL3bc = createContextARBMapVersionsAvailable(device, 3, CTX_PROFILE_COMPAT, hasMinorVersionSupport); // GL3bc
+ success |= hasGL3bc;
+ if( hasGL3bc ) {
+ if(!hasGL3) { // last chance .. ignore hw-accel
+ mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks);
+ hasGL3 = true;
}
+ if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ) ) {
+ // Map hw-accel GL3bc to all lower compatible profiles: GL2
+ mapAvailableGLVersion(device, 2, CTX_PROFILE_COMPAT, ctxVersion, ctxOptions, glRendererQuirks);
+ if(PROFILE_ALIASING) {
+ hasGL2 = true;
+ }
+ }
+ resetStates(false); // clean this context states, since creation was temporary
}
- resetStates(false); // clean this context states, since creation was temporary
}
- }
- if( !hasGL2 ) {
- hasGL2 = createContextARBMapVersionsAvailable(2, CTX_PROFILE_COMPAT); // GL2
- success |= hasGL2;
- if( hasGL2 ) {
- resetStates(false); // clean this context states, since creation was temporary
+ if( !hasGL2 ) {
+ hasGL2 = createContextARBMapVersionsAvailable(device, 2, CTX_PROFILE_COMPAT, hasMinorVersionSupport); // GL2
+ success |= hasGL2;
+ if( hasGL2 ) {
+ resetStates(false); // clean this context states, since creation was temporary
+ }
}
}
if(success) {
// only claim GL versions set [and hence detected] if ARB context creation was successful
GLContext.setAvailableGLVersionsSet(device, true);
- if(DEBUG) {
- final long t1 = System.nanoTime();
- System.err.println("GLContextImpl.mapGLVersions: "+device+", profileAliasing: "+PROFILE_ALIASING+", total "+(t1-t0)/1e6 +"ms");
+ }
+ if(DEBUG) {
+ final long t1 = System.nanoTime();
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions END (success "+success+") on "+device+", profileAliasing: "+PROFILE_ALIASING+", total "+(t1-t0)/1e6 +"ms");
+ if( success ) {
System.err.println(GLContext.dumpAvailableGLVersions(null).toString());
}
- } else if (DEBUG) {
- System.err.println(getThreadName() + ": createContextARB-MapVersions NONE for :"+device);
}
return success;
}
@@ -1114,38 +1307,61 @@ public abstract class GLContextImpl extends GLContext {
* Note: Since context creation is temporary, caller need to issue {@link #resetStates(boolean)}, if creation was successful, i.e. returns true.
* This method does not reset the states, allowing the caller to utilize the state variables.
**/
- private final boolean createContextARBMapVersionsAvailable(final int reqMajor, final int reqProfile) {
+ private final boolean createContextARBMapVersionsAvailable(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile,
+ final boolean hasMinorVersionSupport) {
long _context;
int ctp = CTX_IS_ARB_CREATED | reqProfile;
// To ensure GL profile compatibility within the JOGL application
// we always try to map against the highest GL version,
// so the user can always cast to the highest available one.
- int majorMax, minorMax;
- int majorMin, minorMin;
+ int maxMajor, maxMinor;
+ int minMajor, minMinor;
final int major[] = new int[1];
final int minor[] = new int[1];
- if( CTX_PROFILE_ES == reqProfile ) {
- majorMax=reqMajor; minorMax=GLContext.getMaxMinor(ctp, majorMax);
- majorMin=reqMajor; minorMin=0;
+ if( hasMinorVersionSupport ) {
+ if( CTX_PROFILE_ES == reqProfile ) {
+ // ES3, ES2 or ES1
+ maxMajor=reqMajor; maxMinor=GLContext.getMaxMinor(ctp, maxMajor);
+ minMajor=reqMajor; minMinor=0;
+ } else {
+ if( 4 == reqMajor ) {
+ maxMajor=4; maxMinor=GLContext.getMaxMinor(ctp, maxMajor);
+ minMajor=4; minMinor=0;
+ } else if( 3 == reqMajor ) {
+ maxMajor=3; maxMinor=GLContext.getMaxMinor(ctp, maxMajor);
+ minMajor=3; minMinor=1;
+ } else /* if( glp.isGL2() ) */ {
+ // our minimum desktop OpenGL runtime requirements are 1.1,
+ // nevertheless we restrict ARB context creation to 2.0 to spare us futile attempts
+ maxMajor=3; maxMinor=0;
+ minMajor=2; minMinor=0;
+ }
+ }
} else {
- if( 4 == reqMajor ) {
- majorMax=4; minorMax=GLContext.getMaxMinor(ctp, majorMax);
- majorMin=4; minorMin=0;
- } else if( 3 == reqMajor ) {
- majorMax=3; minorMax=GLContext.getMaxMinor(ctp, majorMax);
- majorMin=3; minorMin=1;
- } else /* if( glp.isGL2() ) */ {
- // our minimum desktop OpenGL runtime requirements are 1.1,
- // nevertheless we restrict ARB context creation to 2.0 to spare us futile attempts
- majorMax=3; minorMax=0;
- majorMin=2; minorMin=0;
+ if( CTX_PROFILE_ES == reqProfile ) {
+ // ES3, ES2 or ES1
+ maxMajor=reqMajor; maxMinor=0;
+ minMajor=reqMajor; minMinor=0;
+ } else {
+ if( 4 == reqMajor ) {
+ maxMajor=4; maxMinor=0;
+ minMajor=4; minMinor=0;
+ } else if( 3 == reqMajor ) {
+ maxMajor=3; maxMinor=1;
+ minMajor=3; minMinor=1;
+ } else /* if( glp.isGL2() ) */ {
+ // our minimum desktop OpenGL runtime requirements are 1.1,
+ // nevertheless we restrict ARB context creation to 2.0 to spare us futile attempts
+ maxMajor=2; maxMinor=0;
+ minMajor=2; minMinor=0;
+ }
}
}
_context = createContextARBVersions(0, true, ctp,
- /* max */ majorMax, minorMax,
- /* min */ majorMin, minorMin,
+ /* max */ maxMajor, maxMinor,
+ /* min */ minMajor, minMinor,
/* res */ major, minor);
if( 0 == _context && CTX_PROFILE_CORE == reqProfile && !PROFILE_ALIASING ) {
@@ -1153,8 +1369,8 @@ public abstract class GLContextImpl extends GLContext {
ctp &= ~CTX_PROFILE_CORE ;
ctp |= CTX_OPTION_FORWARD ;
_context = createContextARBVersions(0, true, ctp,
- /* max */ majorMax, minorMax,
- /* min */ majorMin, minorMin,
+ /* max */ maxMajor, maxMinor,
+ /* min */ minMajor, minMinor,
/* res */ major, minor);
if( 0 == _context ) {
// Try a compatible one .. even though not requested .. last resort
@@ -1162,25 +1378,24 @@ public abstract class GLContextImpl extends GLContext {
ctp &= ~CTX_OPTION_FORWARD ;
ctp |= CTX_PROFILE_COMPAT ;
_context = createContextARBVersions(0, true, ctp,
- /* max */ majorMax, minorMax,
- /* min */ majorMin, minorMin,
+ /* max */ maxMajor, maxMinor,
+ /* min */ minMajor, minMinor,
/* res */ major, minor);
}
}
final boolean res;
if( 0 != _context ) {
- final AbstractGraphicsDevice device = drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
// ctxMajorVersion, ctxMinorVersion, ctxOptions is being set by
// createContextARBVersions(..) -> setGLFunctionAvailbility(..) -> setContextVersion(..)
- GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ final MappedGLVersion me = mapAvailableGLVersion(device, reqMajor, reqProfile, ctxVersion, ctxOptions, glRendererQuirks);
destroyContextARBImpl(_context);
if (DEBUG) {
- System.err.println(getThreadName() + ": createContextARB-MapVersionsAvailable HAVE: " +reqMajor+"."+reqProfile+ " -> "+getGLVersion());
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions HAVE "+me.toString(new StringBuilder(), minMajor, minMinor, maxMajor, maxMinor).toString());
}
res = true;
} else {
if (DEBUG) {
- System.err.println(getThreadName() + ": createContextARB-MapVersionsAvailable NOPE: "+reqMajor+"."+reqProfile);
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions NOPE "+device+", "+reqMajor+" ("+GLContext.getGLProfile(new StringBuilder(), reqProfile).toString()+ ") ["+maxMajor+"."+maxMinor+" .. "+minMajor+"."+minMinor+"]");
}
res = false;
}
@@ -1188,11 +1403,11 @@ public abstract class GLContextImpl extends GLContext {
}
private final long createContextARBVersions(final long share, final boolean direct, final int ctxOptionFlags,
- final int majorMax, final int minorMax,
- final int majorMin, final int minorMin,
+ final int maxMajor, final int maxMinor,
+ final int minMajor, final int minMinor,
final int major[], final int minor[]) {
- major[0]=majorMax;
- minor[0]=minorMax;
+ major[0]=maxMajor;
+ minor[0]=maxMinor;
long _context=0;
int i=0;
@@ -1200,7 +1415,7 @@ public abstract class GLContextImpl extends GLContext {
if (DEBUG) {
i++;
System.err.println(getThreadName() + ": createContextARBVersions."+i+": share "+share+", direct "+direct+
- ", version "+major[0]+"."+minor[0]+", major["+majorMin+".."+majorMax+"], minor["+minorMin+".."+minorMax+"]");
+ ", version "+major[0]+"."+minor[0]+" ["+maxMajor+"."+maxMinor+" .. "+minMajor+"."+minMinor+"]");
}
_context = createContextARBImpl(share, direct, ctxOptionFlags, major[0], minor[0]);
@@ -1213,12 +1428,12 @@ public abstract class GLContextImpl extends GLContext {
}
}
- } while ( ( major[0]>majorMin || major[0]==majorMin && minor[0] >minorMin ) && // #1 check whether version is above lower limit
+ } while ( ( major[0]>minMajor || major[0]==minMajor && minor[0] >minMinor ) && // #1 check whether version is above lower limit
GLContext.decrementGLVersion(ctxOptionFlags, major, minor) // #2 decrement version
);
if (DEBUG) {
System.err.println(getThreadName() + ": createContextARBVersions.X: ctx "+toHexString(_context)+", share "+share+", direct "+direct+
- ", version "+major[0]+"."+minor[0]+", major["+majorMin+".."+majorMax+"], minor["+minorMin+".."+minorMax+"]");
+ ", version "+major[0]+"."+minor[0]+" ["+maxMajor+"."+maxMinor+" .. "+minMajor+"."+minMinor+"]");
}
return _context;
}
@@ -1261,11 +1476,19 @@ public abstract class GLContextImpl extends GLContext {
// Helpers for various context implementations
//
- private final Object createInstance(final GLProfile glp, final boolean glObject, final Object[] cstrArgs) {
+ private final boolean verifyInstance(final GLProfile glp, final String suffix, final Object instance) {
+ return ReflectionUtil.instanceOf(instance, glp.getGLImplBaseClassName()+suffix);
+ }
+ private final Object createInstance(final AbstractGraphicsDevice adevice, final int majorVersion, final int minorVersion, final int contextOption,
+ final boolean glObject, final Object[] cstrArgs) {
+ final String profileString = GLContext.getGLProfile(majorVersion, minorVersion, contextOption);
+ final GLProfile glp = GLProfile.get(adevice, profileString) ;
return ReflectionUtil.createInstance(glp.getGLCtor(glObject), cstrArgs);
}
-
- private final boolean verifyInstance(final GLProfile glp, final String suffix, final Object instance) {
+ private final boolean verifyInstance(final AbstractGraphicsDevice adevice, final int majorVersion, final int minorVersion, final int contextOption,
+ final String suffix, final Object instance) {
+ final String profileString = GLContext.getGLProfile(majorVersion, minorVersion, contextOption);
+ final GLProfile glp = GLProfile.get(adevice, profileString) ;
return ReflectionUtil.instanceOf(instance, glp.getGLImplBaseClassName()+suffix);
}
@@ -1273,8 +1496,11 @@ public abstract class GLContextImpl extends GLContext {
* Create the GL instance for this context,
* requires valid {@link #getGLProcAddressTable()} result!
*/
- private final GL createGL(final GLProfile glp) {
- final GL gl = (GL) createInstance(glp, true, new Object[] { glp, this } );
+ private final GL createGL(final AbstractGraphicsDevice adevice, final int majorVersion, final int minorVersion, final int contextOption) {
+ final String profileString = GLContext.getGLProfile(majorVersion, minorVersion, contextOption);
+ final GLProfile glp = GLProfile.get(adevice, profileString);
+ final GL gl = (GL) ReflectionUtil.createInstance(glp.getGLCtor(true), new Object[] { glp, this });
+ //nal GL gl = (GL) createInstance(glp, true, new Object[] { glp, this } );
/* FIXME: refactor dependence on Java 2D / JOGL bridge
if (tracker != null) {
@@ -1348,34 +1574,53 @@ public abstract class GLContextImpl extends GLContext {
}
protected abstract Map<String, String> getExtensionNameMap() ;
+ /**
+ * Returns the DynamicLookupHelper
+ */
+ public final GLDynamicLookupHelper getGLDynamicLookupHelper() {
+ return drawable.getFactoryImpl().getGLDynamicLookupHelper( ctxVersion.getMajor(), ctxOptions );
+ }
+ public final GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions) {
+ return drawable.getFactoryImpl().getGLDynamicLookupHelper( majorVersion, contextOptions );
+ }
+
/** Helper routine which resets a ProcAddressTable generated by the
- GLEmitter by looking up anew all of its function pointers. */
- protected final void resetProcAddressTable(final ProcAddressTable table) {
+ GLEmitter by looking up anew all of its function pointers
+ using the given {@link GLDynamicLookupHelper}. */
+ protected final void resetProcAddressTable(final ProcAddressTable table, final GLDynamicLookupHelper dlh) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
- table.reset(getDrawableImpl().getGLDynamicLookupHelper() );
+ table.reset( dlh );
return null;
}
} );
}
- private final PrivilegedAction<Object> privInitGLGetPtrAction = new PrivilegedAction<Object>() {
- @Override
- public Object run() {
- final GLDynamicLookupHelper glDynLookupHelper = getDrawableImpl().getGLDynamicLookupHelper();
- glDynLookupHelper.claimAllLinkPermission();
- try {
- glGetStringPtr = glDynLookupHelper.dynamicLookupFunction("glGetString");
- glGetIntegervPtr = glDynLookupHelper.dynamicLookupFunction("glGetIntegerv");
- } finally {
- glDynLookupHelper.releaseAllLinkPermission();
- }
- return null;
- } };
- private final boolean initGLRendererAndGLVersionStrings() {
+ /**
+ * Updates the platform's 'GLX' function cache
+ * @param contextFQN provides a fully qualified key of the context including device and GL profile
+ * @param dlh {@link GLDynamicLookupHelper} used to {@link #resetProcAddressTable(ProcAddressTable, GLDynamicLookupHelper)} instance.
+ */
+ protected abstract void updateGLXProcAddressTable(final String contextFQN, final GLDynamicLookupHelper dlh);
+
+ private final boolean initGLRendererAndGLVersionStrings(final int majorVersion, final int contextOptions) {
if( !glGetPtrInit ) {
- AccessController.doPrivileged(privInitGLGetPtrAction);
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
+ public Object run() {
+ final GLDynamicLookupHelper glDynLookupHelper = getGLDynamicLookupHelper(majorVersion, contextOptions);
+ if( null != glDynLookupHelper ) {
+ glDynLookupHelper.claimAllLinkPermission();
+ try {
+ glGetStringPtr = glDynLookupHelper.dynamicLookupFunction("glGetString");
+ glGetIntegervPtr = glDynLookupHelper.dynamicLookupFunction("glGetIntegerv");
+ } finally {
+ glDynLookupHelper.releaseAllLinkPermission();
+ }
+ }
+ return null;
+ } } );
glGetPtrInit = true;
}
if( 0 == glGetStringPtr || 0 == glGetIntegervPtr ) {
@@ -1521,7 +1766,7 @@ public abstract class GLContextImpl extends GLContext {
final VersionNumber reqGLVersion = new VersionNumber(major, minor, 0);
final VersionNumber hasGLVersionByString;
{
- final boolean initGLRendererAndGLVersionStringsOK = initGLRendererAndGLVersionStrings();
+ final boolean initGLRendererAndGLVersionStringsOK = initGLRendererAndGLVersionStrings(major, ctxProfileBits);
if( !initGLRendererAndGLVersionStringsOK ) {
final String errMsg = "Intialization of GL renderer strings failed. "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null);
if( strictMatch ) {
@@ -1557,50 +1802,51 @@ public abstract class GLContextImpl extends GLContext {
{
// Validate the requested version w/ the GL-version from an integer query,
// as supported by GL [ES] >= 3.0 implementation.
- final VersionNumber hasGLVersionByInt;
- {
- final int[] glIntMajor = new int[] { 0 }, glIntMinor = new int[] { 0 };
- getGLIntVersion(glIntMajor, glIntMinor);
- hasGLVersionByInt = new VersionNumber(glIntMajor[0], glIntMinor[0], 0);
- }
- if (DEBUG) {
- System.err.println(getThreadName() + ": GLContext.setGLFuncAvail: Version verification (Int): String "+glVersion+", Number(Int) "+hasGLVersionByInt);
- }
-
+ //
// Only validate integer based version if:
// - ctx >= 3.0 is requested _or_ string-version >= 3.0
// - _and_ a valid int version was fetched,
// otherwise cont. w/ version-string method -> 3.0 > Version || Version > MAX!
//
- if ( ( major >= 3 || hasGLVersionByString.compareTo(Version3_0) >= 0 ) &&
- GLContext.isValidGLVersion(ctxProfileBits, hasGLVersionByInt.getMajor(), hasGLVersionByInt.getMinor()) ) {
- // Strict Match (GLVersionMapping):
- // Relaxed match for versions ( !isES && major < 3 ) requests, last resort!
- // Otherwise:
- // - fail if hasVersion < reqVersion (desktop and ES)
- // - fail if ES major-version mismatch:
- // - request 1, >= 3 must be equal
- // - request 2 must be [2..3]
- //
- final int hasMajor = hasGLVersionByInt.getMajor();
- if( strictMatch &&
- ( ( ( isES || major >= 3 ) && hasGLVersionByInt.compareTo(reqGLVersion) < 0 ) ||
- ( isES &&
- (
- ( 2 == major && ( 2 > hasMajor || hasMajor > 3 ) ) || // 2 -> [2..3]
- ( ( 1 == major || 3 <= major ) && major != hasMajor ) // 1,3,.. -> equal
- )
- )
- ) ) {
- if(DEBUG) {
- System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: FAIL, GL version mismatch (Int): "+GLContext.getGLVersion(major, minor, ctxProfileBits, null)+" -> "+glVersion+", "+hasGLVersionByInt);
+ final VersionNumber hasGLVersionByInt;
+ if ( major >= 3 || hasGLVersionByString.compareTo(Version3_0) >= 0 ) {
+ final int[] glIntMajor = new int[] { 0 }, glIntMinor = new int[] { 0 };
+ getGLIntVersion(glIntMajor, glIntMinor);
+ hasGLVersionByInt = new VersionNumber(glIntMajor[0], glIntMinor[0], 0);
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": GLContext.setGLFuncAvail: Version verification (Int): String "+glVersion+", Number(Int) "+hasGLVersionByInt);
+ }
+ if ( GLContext.isValidGLVersion(ctxProfileBits, hasGLVersionByInt.getMajor(), hasGLVersionByInt.getMinor()) ) {
+ // Strict Match (GLVersionMapping):
+ // Relaxed match for versions ( !isES && major < 3 ) requests, last resort!
+ // Otherwise:
+ // - fail if hasVersion < reqVersion (desktop and ES)
+ // - fail if ES major-version mismatch:
+ // - request 1, >= 3 must be equal
+ // - request 2 must be [2..3]
+ //
+ final int hasMajor = hasGLVersionByInt.getMajor();
+ if( strictMatch &&
+ ( ( ( isES || major >= 3 ) && hasGLVersionByInt.compareTo(reqGLVersion) < 0 ) ||
+ ( isES &&
+ (
+ ( 2 == major && ( 2 > hasMajor || hasMajor > 3 ) ) || // 2 -> [2..3]
+ ( ( 1 == major || 3 <= major ) && major != hasMajor ) // 1,3,.. -> equal
+ )
+ )
+ ) ) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: FAIL, GL version mismatch (Int): "+GLContext.getGLVersion(major, minor, ctxProfileBits, null)+" -> "+glVersion+", "+hasGLVersionByInt);
+ }
+ return false;
}
- return false;
+ // Use returned GL version!
+ major = hasGLVersionByInt.getMajor();
+ minor = hasGLVersionByInt.getMinor();
+ versionGL3IntOK = true;
+ } else {
+ versionGL3IntOK = false;
}
- // Use returned GL version!
- major = hasGLVersionByInt.getMajor();
- minor = hasGLVersionByInt.getMinor();
- versionGL3IntOK = true;
} else {
versionGL3IntOK = false;
}
@@ -1668,7 +1914,8 @@ public abstract class GLContextImpl extends GLContext {
}
if( major < 2 ) { // there is no ES2/3-compat for a profile w/ major < 2
- ctxProfileBits &= ~ ( GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_ES3_COMPAT | GLContext.CTX_IMPL_ES31_COMPAT ) ;
+ ctxProfileBits &= ~ ( GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_ES3_COMPAT |
+ GLContext.CTX_IMPL_ES31_COMPAT | GLContext.CTX_IMPL_ES32_COMPAT ) ;
}
if(!isCurrentContextHardwareRasterizer()) {
@@ -1692,43 +1939,72 @@ public abstract class GLContextImpl extends GLContext {
if (DEBUG) {
System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.0 validated FQN: "+contextFQN+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, glVersion));
}
-
- updateGLXProcAddressTable();
+ final GLDynamicLookupHelper dynamicLookup = getGLDynamicLookupHelper(major, ctxProfileBits);
+ if( null == dynamicLookup ) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: FAIL, No GLDynamicLookupHelper for request: "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
+ }
+ return false;
+ }
+ updateGLXProcAddressTable(contextFQN, dynamicLookup);
//
// UpdateGLProcAddressTable functionality
// _and_ setup GL instance, which ctor requires valid getGLProcAddressTable() result!
//
{
- final GLProfile glp = drawable.getGLProfile();
+ final GLProfile glp = drawable.getGLProfile(); // !withinGLVersionsMapping
ProcAddressTable table = null;
synchronized(mappedContextTypeObjectLock) {
table = mappedGLProcAddress.get( contextFQN );
- if(null != table && !verifyInstance(glp, "ProcAddressTable", table)) {
- throw new GLException("GLContext GL ProcAddressTable mapped key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
- ") -> "+ table.getClass().getName()+" not matching "+glp.getGLImplBaseClassName());
+ if(null != table) {
+ if( !verifyInstance(adevice, major, minor, ctxProfileBits, "ProcAddressTable", table) ) {
+ throw new GLException("GLContext GL ProcAddressTable mapped key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
+ ") -> "+ toHexString(table.hashCode()) +" not matching "+table.getClass().getName());
+ }
+ if( !withinGLVersionsMapping && !verifyInstance(glp, "ProcAddressTable", table) ) {
+ throw new GLException("GLContext GL ProcAddressTable mapped key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
+ ") -> "+ toHexString(table.hashCode()) +": "+table.getClass().getName()+" not matching "+glp.getGLImplBaseClassName()+"/"+glp);
+ }
}
}
if(null != table) {
glProcAddressTable = table;
if(DEBUG) {
- System.err.println(getThreadName() + ": GLContext GL ProcAddressTable reusing key("+contextFQN+") -> "+toHexString(table.hashCode()));
+ if( withinGLVersionsMapping ) {
+ System.err.println(getThreadName() + ": GLContext GL ProcAddressTable reusing key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
+ ") -> "+ toHexString(table.hashCode()) +": "+table.getClass().getName());
+ } else {
+ System.err.println(getThreadName() + ": GLContext GL ProcAddressTable reusing key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
+ ") -> "+ toHexString(table.hashCode()) +": "+table.getClass().getName()+" -> "+glp.getGLImplBaseClassName());
+ }
}
} else {
- glProcAddressTable = (ProcAddressTable) createInstance(glp, false,
+ glProcAddressTable = (ProcAddressTable) createInstance(adevice, major, minor, ctxProfileBits, false,
new Object[] { new GLProcAddressResolver() } );
- resetProcAddressTable( glProcAddressTable );
+ resetProcAddressTable(glProcAddressTable, dynamicLookup);
+
synchronized(mappedContextTypeObjectLock) {
mappedGLProcAddress.put(contextFQN, glProcAddressTable);
if(DEBUG) {
- System.err.println(getThreadName() + ": GLContext GL ProcAddressTable mapping key("+contextFQN+") -> "+toHexString(glProcAddressTable.hashCode()));
+ if( withinGLVersionsMapping ) {
+ System.err.println(getThreadName() + ": GLContext GL ProcAddressTable mapping key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
+ ") -> "+toHexString(glProcAddressTable.hashCode()) +": "+glProcAddressTable.getClass().getName());
+ } else {
+ System.err.println(getThreadName() + ": GLContext GL ProcAddressTable mapping key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
+ ") -> "+toHexString(glProcAddressTable.hashCode()) +": "+glProcAddressTable.getClass().getName()+" -> "+glp.getGLImplBaseClassName());
+ }
}
}
}
- if( null == this.gl || !verifyInstance(glp, "Impl", this.gl) ) {
- setGL( createGL( glp ) );
+ if( null == this.gl || !verifyInstance(adevice, major, minor, ctxProfileBits, "Impl", this.gl) ) {
+ setGL( createGL( adevice, major, minor, ctxProfileBits ) );
+ }
+ if( !withinGLVersionsMapping && !verifyInstance(glp, "Impl", this.gl) ) {
+ throw new GLException("GLContext GL Object mismatch: "+GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
+ ") -> "+": "+this.gl.getClass().getName()+" not matching "+glp.getGLImplBaseClassName()+"/"+glp);
}
}
@@ -1762,7 +2038,9 @@ public abstract class GLContextImpl extends GLContext {
if( major >= 3 ) {
ctxProfileBits |= CTX_IMPL_ES3_COMPAT | CTX_IMPL_ES2_COMPAT ;
ctxProfileBits |= CTX_IMPL_FBO;
- if( minor >= 1 ) {
+ if( minor >= 2 ) {
+ ctxProfileBits |= CTX_IMPL_ES32_COMPAT | CTX_IMPL_ES31_COMPAT;
+ } else if( minor >= 1 ) {
ctxProfileBits |= CTX_IMPL_ES31_COMPAT;
}
} else if( major >= 2 ) {
@@ -1770,10 +2048,15 @@ public abstract class GLContextImpl extends GLContext {
ctxProfileBits |= CTX_IMPL_FBO;
}
} else if( ( major > 4 || major == 4 && minor >= 5 ) ||
- ( ( major > 3 || major == 3 && minor >= 1 ) && isExtensionAvailable( GLExtensions.ARB_ES3_1_compatibility ) ) ) {
- // See GLContext.isGLES31CompatibleAvailable(..)/isGLES31Compatible()
- // Includes [ GL &ge; 4.5, GL &ge; 3.1 w/ GL_ARB_ES3_1_compatibility and GLES &ge; 3.1 ]
- ctxProfileBits |= CTX_IMPL_ES31_COMPAT | CTX_IMPL_ES3_COMPAT | CTX_IMPL_ES2_COMPAT ;
+ ( major > 3 || major == 3 && minor >= 1 ) ) {
+ // See GLContext.isGLES31CompatibleAvailable(..)/isGLES3[12]Compatible()
+ // Includes [ GL &ge; 4.5, GL &ge; 3.1 w/ GL_ARB_ES3_[12]_compatibility and GLES &ge; 3.[12] ]
+ if( isExtensionAvailable( GLExtensions.ARB_ES3_2_compatibility ) ) {
+ ctxProfileBits |= CTX_IMPL_ES32_COMPAT | CTX_IMPL_ES31_COMPAT;
+ } else if( isExtensionAvailable( GLExtensions.ARB_ES3_1_compatibility ) ) {
+ ctxProfileBits |= CTX_IMPL_ES31_COMPAT;
+ }
+ ctxProfileBits |= CTX_IMPL_ES3_COMPAT | CTX_IMPL_ES2_COMPAT;
ctxProfileBits |= CTX_IMPL_FBO;
} else if( ( major > 4 || major == 4 && minor >= 3 ) ||
( ( major > 3 || major == 3 && minor >= 1 ) && isExtensionAvailable( GLExtensions.ARB_ES3_compatibility ) ) ) {
@@ -1813,6 +2096,31 @@ public abstract class GLContextImpl extends GLContext {
return true;
}
+ private static final void addStickyQuirkAlways(final AbstractGraphicsDevice adevice,
+ final GLRendererQuirks quirks,
+ final int quirk,
+ final boolean withinGLVersionsMapping) {
+ quirks.addQuirk( quirk );
+ if( withinGLVersionsMapping ) {
+ // Thread safe due to single threaded initialization!
+ GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
+ } else {
+ // FIXME: Remove when moving EGL/ES to ARB ctx creation
+ synchronized(GLContextImpl.class) {
+ GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
+ }
+ }
+ }
+ private static final void addStickyQuirkAtMapping(final AbstractGraphicsDevice adevice,
+ final GLRendererQuirks quirks,
+ final int quirk,
+ final boolean withinGLVersionsMapping) {
+ quirks.addQuirk( quirk );
+ if( withinGLVersionsMapping ) {
+ // Thread safe due to single threaded initialization!
+ GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
+ }
+ }
private final void setRendererQuirks(final AbstractGraphicsDevice adevice, final GLDrawableFactoryImpl factory,
final int reqMajor, final int reqMinor, final int reqCTP,
final int major, final int minor, final int ctp, final VersionNumberString vendorVersion,
@@ -1822,10 +2130,10 @@ public abstract class GLContextImpl extends GLContext {
final String MesaRendererIntelsp = "Intel(R)";
final boolean hwAccel = 0 == ( ctp & GLContext.CTX_IMPL_ACCEL_SOFT );
final boolean compatCtx = 0 != ( ctp & GLContext.CTX_PROFILE_COMPAT );
- final boolean esCtx = 0 != ( ctp & GLContext.CTX_PROFILE_ES );
+ final boolean isES = 0 != ( ctp & GLContext.CTX_PROFILE_ES );
final boolean isX11 = NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true);
final boolean isWindows = Platform.getOSType() == Platform.OSType.WINDOWS;
- final boolean isDriverMesa = glRenderer.contains(MesaSP) || glRenderer.contains("Gallium ");
+ final boolean isDriverMesa = glRenderer.contains(MesaSP) || glRenderer.contains("Gallium ") || glVersion.contains(MesaSP);
final boolean isDriverATICatalyst;
final boolean isDriverNVIDIAGeForce;
@@ -1845,22 +2153,13 @@ public abstract class GLContextImpl extends GLContext {
//
// General Quirks
//
- if( esCtx ) {
+ if( isES ) {
if( 2 == reqMajor && 2 < major ) {
final int quirk = GLRendererQuirks.GLES3ViaEGLES2Config;
if(DEBUG) {
System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: ES req "+reqMajor+" and 2 < "+major);
}
- quirks.addQuirk( quirk );
- if( withinGLVersionsMapping ) {
- // Thread safe due to single threaded initialization!
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- } else {
- // FIXME: Remove when moving EGL/ES to ARB ctx creation
- synchronized(GLContextImpl.class) {
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- }
- }
+ addStickyQuirkAlways(adevice, quirks, quirk, withinGLVersionsMapping);
}
}
if( GLProfile.disableSurfacelessContext ) {
@@ -1868,32 +2167,14 @@ public abstract class GLContextImpl extends GLContext {
if(DEBUG) {
System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: disabled");
}
- quirks.addQuirk( quirk );
- if( withinGLVersionsMapping ) {
- // Thread safe due to single threaded initialization!
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- } else {
- // FIXME: Remove when moving EGL/ES to ARB ctx creation
- synchronized(GLContextImpl.class) {
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- }
- }
+ addStickyQuirkAlways(adevice, quirks, quirk, withinGLVersionsMapping);
}
if( GLProfile.disableOpenGLARBContext ) {
final int quirk = GLRendererQuirks.NoARBCreateContext;
if(DEBUG) {
System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: disabled");
}
- quirks.addQuirk( quirk );
- if( withinGLVersionsMapping ) {
- // Thread safe due to single threaded initialization!
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- } else {
- // FIXME: Remove when moving EGL/ES to ARB ctx creation
- synchronized(GLContextImpl.class) {
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- }
- }
+ addStickyQuirkAlways(adevice, quirks, quirk, withinGLVersionsMapping);
}
//
@@ -1922,11 +2203,7 @@ public abstract class GLContextImpl extends GLContext {
if(DEBUG) {
System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType()+", OS Version "+Platform.getOSVersionNumber()+", req "+reqMajor+"."+reqMinor);
}
- quirks.addQuirk( quirk );
- if( withinGLVersionsMapping ) {
- // Thread safe due to single threaded initialization!
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- }
+ addStickyQuirkAtMapping(adevice, quirks, quirk, withinGLVersionsMapping);
}
if( isDriverNVIDIAGeForce ) {
final VersionNumber osxVersionNVFlushClean = new VersionNumber(10,7,3); // < OSX 10.7.3 w/ NV needs glFlush
@@ -1984,11 +2261,7 @@ public abstract class GLContextImpl extends GLContext {
if(DEBUG) {
System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType()+", [Vendor "+glVendor+", Renderer "+glRenderer+" and Version "+glVersion+"]");
}
- quirks.addQuirk( quirk );
- if( withinGLVersionsMapping ) {
- // Thread safe due to single threaded initialization!
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- }
+ addStickyQuirkAtMapping(adevice, quirks, quirk, withinGLVersionsMapping);
}
}
} else if( isDriverIntel && glRenderer.equals("Intel Bear Lake B") ) {
@@ -2054,6 +2327,17 @@ public abstract class GLContextImpl extends GLContext {
}
}
}
+ if( isDriverNVIDIAGeForce ) {
+ // Bug 1200: Crash on GNU/Linux x86_64 'NVidia beta driver 355.06' @ probeSurfacelessCtx
+ // final VersionNumber nvSafeVersion = new VersionNumber(356, 0, 0); // FIXME: Add safe version!
+ if( !isES && !(adevice instanceof EGLGraphicsDevice) /* && vendorVersion.compareTo(nvSafeVersion) < 0 */ ) {
+ final int quirk = GLRendererQuirks.NoSurfacelessCtx;
+ if(DEBUG) {
+ System.err.print("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: !ES, !EGL, Vendor " + glVendor +", X11 Renderer " + glRenderer+", Version=[vendor " + vendorVersion + ", GL " + glVersion+"]");
+ }
+ addStickyQuirkAtMapping(adevice, quirks, quirk, withinGLVersionsMapping);
+ }
+ }
}
@@ -2063,8 +2347,10 @@ public abstract class GLContextImpl extends GLContext {
if( isDriverMesa ) {
final VersionNumber mesaSafeFBOVersion = new VersionNumber(8, 0, 0);
final VersionNumber mesaIntelBuggySharedCtx921 = new VersionNumber(9, 2, 1);
+ final VersionNumber mesaSafeDoubleBufferedPBuffer = new VersionNumber(18, 2, 2); // Mesa 18.2.2
+ final VersionNumber mesaSafeSetSwapIntervalPostRetarget = mesaSafeDoubleBufferedPBuffer; // Mesa 18.2.2
- {
+ if( vendorVersion.compareTo(mesaSafeSetSwapIntervalPostRetarget) < 0 ) {
final int quirk = GLRendererQuirks.NoSetSwapIntervalPostRetarget;
if(DEBUG) {
System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Renderer " + glRenderer);
@@ -2073,11 +2359,13 @@ public abstract class GLContextImpl extends GLContext {
}
if( hwAccel ) {
// hardware-acceleration
- final int quirk = GLRendererQuirks.NoDoubleBufferedPBuffer;
- if(DEBUG) {
- System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Renderer " + glRenderer);
+ if( vendorVersion.compareTo(mesaSafeDoubleBufferedPBuffer) < 0 ) {
+ final int quirk = GLRendererQuirks.NoDoubleBufferedPBuffer;
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Renderer " + glRenderer);
+ }
+ quirks.addQuirk( quirk );
}
- quirks.addQuirk( quirk );
} else {
// software
if( vendorVersion.compareTo(mesaSafeFBOVersion) < 0 ) { // FIXME: Is it fixed in >= 8.0.0 ?
@@ -2111,11 +2399,7 @@ public abstract class GLContextImpl extends GLContext {
if(DEBUG) {
System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: X11 / Renderer " + glRenderer + " / Vendor "+glVendor);
}
- quirks.addQuirk( quirk );
- if( withinGLVersionsMapping ) {
- // Thread safe due to single threaded initialization!
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- }
+ addStickyQuirkAtMapping(adevice, quirks, quirk, withinGLVersionsMapping);
}
if( isWindows && glRenderer.contains("SVGA3D") && vendorVersion.compareTo(mesaSafeFBOVersion) < 0 ) {
final int quirk = GLRendererQuirks.NoFullFBOSupport;
@@ -2157,7 +2441,7 @@ public abstract class GLContextImpl extends GLContext {
if( !GLRendererQuirks.areSameStickyDevice(factoryDefaultDevice, adevice) ) {
GLRendererQuirks.pushStickyDeviceQuirks(factoryDefaultDevice, quirks);
}
- if( esCtx ) {
+ if( isES ) {
final AbstractGraphicsDevice eglFactoryDefaultDevice = GLDrawableFactory.getEGLFactory().getDefaultDevice();
if( !GLRendererQuirks.areSameStickyDevice(eglFactoryDefaultDevice, adevice) &&
!GLRendererQuirks.areSameStickyDevice(eglFactoryDefaultDevice, factoryDefaultDevice) ) {
@@ -2233,11 +2517,6 @@ public abstract class GLContextImpl extends GLContext {
return isHardwareRasterizer;
}
- /**
- * Updates the platform's 'GLX' function cache
- */
- protected abstract void updateGLXProcAddressTable();
-
protected abstract StringBuilder getPlatformExtensionsStringImpl();
@Override
@@ -2262,7 +2541,10 @@ public abstract class GLContextImpl extends GLContext {
}
// dynamic function lookup at last incl name aliasing (not cached)
- final DynamicLookupHelper dynLookup = getDrawableImpl().getGLDynamicLookupHelper();
+ final DynamicLookupHelper dynLookup = getGLDynamicLookupHelper(ctxVersion.getMajor(), ctxOptions);
+ if( null == dynLookup ) {
+ throw new GLException("No GLDynamicLookupHelper for "+this);
+ }
final String tmpBase = GLNameResolver.normalizeVEN(GLNameResolver.normalizeARB(glFunctionName, true), true);
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
@@ -2378,6 +2660,40 @@ public abstract class GLContextImpl extends GLContext {
}
//----------------------------------------------------------------------
+ // SwapBuffer
+
+ @Override
+ public final boolean setSwapInterval(final int interval) throws GLException {
+ validateCurrent();
+ return setSwapIntervalNC(interval);
+ }
+ protected final boolean setSwapIntervalNC(final int interval) throws GLException {
+ if( !drawableRetargeted ||
+ !hasRendererQuirk(GLRendererQuirks.NoSetSwapIntervalPostRetarget)
+ )
+ {
+ final Integer usedInterval = setSwapIntervalImpl2(interval);
+ if( null != usedInterval ) {
+ currentSwapInterval = usedInterval.intValue();
+ return true;
+ }
+ }
+ return false;
+ }
+ protected abstract Integer setSwapIntervalImpl2(final int interval);
+
+ @Override
+ public final int getSwapInterval() {
+ return currentSwapInterval;
+ }
+ @Override
+ protected final void setDefaultSwapInterval() {
+ currentSwapInterval = 0;
+ setSwapIntervalNC(1);
+ }
+
+
+ //----------------------------------------------------------------------
// Helpers for buffer object optimizations
public final GLBufferObjectTracker getBufferObjectTracker() {
@@ -2536,8 +2852,8 @@ public abstract class GLContextImpl extends GLContext {
@Override
public final void glDebugMessageControl(final int source, final int type, final int severity, final int count, final IntBuffer ids, final boolean enabled) {
- if(glDebugHandler.isExtensionARB()) {
- gl.getGL2GL3().glDebugMessageControl(source, type, severity, count, ids, enabled);
+ if(glDebugHandler.isExtensionKHRARB()) {
+ gl.getGL2ES2().glDebugMessageControl(source, type, severity, count, ids, enabled);
} else if(glDebugHandler.isExtensionAMD()) {
gl.getGL2GL3().glDebugMessageEnableAMD(GLDebugMessage.translateARB2AMDCategory(source, type), severity, count, ids, enabled);
}
@@ -2545,8 +2861,8 @@ public abstract class GLContextImpl extends GLContext {
@Override
public final void glDebugMessageControl(final int source, final int type, final int severity, final int count, final int[] ids, final int ids_offset, final boolean enabled) {
- if(glDebugHandler.isExtensionARB()) {
- gl.getGL2GL3().glDebugMessageControl(source, type, severity, count, ids, ids_offset, enabled);
+ if(glDebugHandler.isExtensionKHRARB()) {
+ gl.getGL2ES2().glDebugMessageControl(source, type, severity, count, ids, ids_offset, enabled);
} else if(glDebugHandler.isExtensionAMD()) {
gl.getGL2GL3().glDebugMessageEnableAMD(GLDebugMessage.translateARB2AMDCategory(source, type), severity, count, ids, ids_offset, enabled);
}
@@ -2555,8 +2871,8 @@ public abstract class GLContextImpl extends GLContext {
@Override
public final void glDebugMessageInsert(final int source, final int type, final int id, final int severity, final String buf) {
final int len = (null != buf) ? buf.length() : 0;
- if(glDebugHandler.isExtensionARB()) {
- gl.getGL2GL3().glDebugMessageInsert(source, type, id, severity, len, buf);
+ if(glDebugHandler.isExtensionKHRARB()) {
+ gl.getGL2ES2().glDebugMessageInsert(source, type, id, severity, len, buf);
} else if(glDebugHandler.isExtensionAMD()) {
gl.getGL2GL3().glDebugMessageInsertAMD(GLDebugMessage.translateARB2AMDCategory(source, type), severity, id, len, buf);
}
diff --git a/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java b/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
index cd31d02fd..fb4529da4 100644
--- a/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
+++ b/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
@@ -61,8 +61,9 @@ import com.jogamp.opengl.GLExtensions;
public class GLDebugMessageHandler {
private static final boolean DEBUG = Debug.debug("GLDebugMessageHandler");
- private static final int EXT_ARB = 1;
- private static final int EXT_AMD = 2;
+ private static final int EXT_KHR = 1;
+ private static final int EXT_ARB = 2;
+ private static final int EXT_AMD = 3;
static {
if ( !initIDs0() ) {
@@ -75,6 +76,7 @@ public class GLDebugMessageHandler {
// licefycle: init - EOL
private String extName;
+ private String extSuffix;
private int extType;
private long glDebugMessageCallbackProcAddress;
private boolean extAvailable;
@@ -92,6 +94,7 @@ public class GLDebugMessageHandler {
this.listenerImpl = new ListenerSyncedImplStub<GLDebugListener>();
this.glDebugMessageCallbackProcAddress = 0;
this.extName = null;
+ this.extSuffix = null;
this.extType = 0;
this.extAvailable = false;
this.handle = 0;
@@ -143,43 +146,68 @@ public class GLDebugMessageHandler {
}
return;
}
- if( ctx.isExtensionAvailable(GLExtensions.ARB_debug_output) ) {
+ if( ctx.isExtensionAvailable(GLExtensions.GL_KHR_debug) ) {
+ extName = GLExtensions.GL_KHR_debug;
+ extSuffix = ctx.isGLES() ? "KHR" : ""; // See SPEC!
+ extType = EXT_KHR;
+ } else if( ctx.isExtensionAvailable(GLExtensions.ARB_debug_output) ) {
extName = GLExtensions.ARB_debug_output;
+ extSuffix = "ARB";
extType = EXT_ARB;
} else if( ctx.isExtensionAvailable(GLExtensions.AMD_debug_output) ) {
extName = GLExtensions.AMD_debug_output;
+ extSuffix = "AMD";
extType = EXT_AMD;
}
- if(DEBUG) {
- System.err.println("GLDebugMessageHandler: Using extension: <"+extName+">");
+
+ // Validate GL Profile, just to be sure
+ switch(extType) {
+ case EXT_KHR:
+ if( !ctx.isGL2ES2() ) {
+ if(DEBUG) {
+ System.err.println("Non GL2ES2 context not supported, has "+ctx.getGLVersion());
+ }
+ extType = 0;
+ }
+ break;
+ case EXT_ARB:
+ // fall through intended
+ case EXT_AMD:
+ if( !ctx.isGL2GL3() ) {
+ if(DEBUG) {
+ System.err.println("Non GL2GL3 context not supported, has "+ctx.getGLVersion());
+ }
+ extType = 0;
+ }
+ break;
}
if(0 == extType) {
+ extName = null;
+ extSuffix = null;
if(DEBUG) {
System.err.println("GLDebugMessageHandler: No extension available! "+ctx.getGLVersion());
System.err.println("GL_EXTENSIONS "+ctx.getGLExtensionCount());
System.err.println(ctx.getGLExtensionsString());
}
return;
+ } else if(DEBUG) {
+ System.err.println("GLDebugMessageHandler: Using extension: <"+extName+"> with suffix <"+extSuffix+">");
}
final ProcAddressTable procAddressTable = ctx.getGLProcAddressTable();
- if( !ctx.isGLES1() && !ctx.isGLES2() ) {
- switch(extType) {
- case EXT_ARB:
- glDebugMessageCallbackProcAddress = getAddressFor(procAddressTable, "glDebugMessageCallbackARB");
- break;
- case EXT_AMD:
- glDebugMessageCallbackProcAddress = getAddressFor(procAddressTable, "glDebugMessageCallbackAMD");
- break;
- }
- } else {
- glDebugMessageCallbackProcAddress = 0;
- if(DEBUG) {
- System.err.println("Non desktop context not supported");
- }
+ switch(extType) {
+ case EXT_KHR:
+ glDebugMessageCallbackProcAddress = getAddressFor(procAddressTable, "glDebugMessageCallback"+extSuffix);
+ break;
+ case EXT_ARB:
+ glDebugMessageCallbackProcAddress = getAddressFor(procAddressTable, "glDebugMessageCallback"+extSuffix);
+ break;
+ case EXT_AMD:
+ glDebugMessageCallbackProcAddress = getAddressFor(procAddressTable, "glDebugMessageCallback"+extSuffix);
+ break;
}
- extAvailable = 0 < extType && null != extName && 0 != glDebugMessageCallbackProcAddress;
+ extAvailable = 0 < extType && null != extName && null != extSuffix && 0 != glDebugMessageCallbackProcAddress;
if(DEBUG) {
System.err.println("GLDebugMessageHandler: extAvailable: "+extAvailable+", glDebugMessageCallback* : 0x"+Long.toHexString(glDebugMessageCallbackProcAddress));
@@ -203,12 +231,20 @@ public class GLDebugMessageHandler {
return extName;
}
+ public final boolean isExtensionKHRARB() {
+ return EXT_KHR == extType || EXT_ARB == extType;
+ }
+
+ public final boolean isExtensionKHR() {
+ return EXT_KHR == extType;
+ }
+
public final boolean isExtensionARB() {
- return extName == GLExtensions.ARB_debug_output;
+ return EXT_ARB == extType;
}
public final boolean isExtensionAMD() {
- return extName == GLExtensions.AMD_debug_output;
+ return EXT_AMD == extType;
}
/**
@@ -226,7 +262,7 @@ public class GLDebugMessageHandler {
}
}
private final void setSynchronousImpl() {
- if(isExtensionARB()) {
+ if(isExtensionKHRARB()) {
if(synchronous) {
ctx.getGL().glEnable(GL2ES2.GL_DEBUG_OUTPUT_SYNCHRONOUS);
} else {
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
index b7f861e13..dfe6bdd9f 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
@@ -230,6 +230,15 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
}
/**
+ * Method returns {@code true} if underlying {@link #createContextARBImpl(long, boolean, int, int, int) <i>ARB context creation</i>}
+ * supports {@code major} and {@code minor} version number.
+ * <p>
+ * Otherwise only the {@code major} version number is supported for context creation.
+ * </p>
+ */
+ public abstract boolean hasMajorMinorCreateContextARB();
+
+ /**
* Returns the shared device mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()},
* either a preexisting or newly created, or <code>null</code> if creation failed or not supported.<br>
* Creation of the shared context is tried only once.
@@ -245,12 +254,11 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
}
/**
- * Returns the GLDynamicLookupHelper
- * @param profileName if EGL/ES, profile <code>1</code> refers to ES1 and <code>2</code> to ES2,
- * otherwise the profile is ignored.
- * @throws GLException if no DynamicLookupHelper is installed
+ * Returns the GLDynamicLookupHelper if installed, otherwise {@code null}.
+ * @param majorVersion the major OpenGL profile version
+ * @param contextOptions the context profile options
*/
- public abstract GLDynamicLookupHelper getGLDynamicLookupHelper(final String profileName) throws GLException;
+ public abstract GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions);
//---------------------------------------------------------------------------
// Dispatching GLDrawable construction in respect to the NativeSurface Capabilities
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
index e9ee46a51..e4b5eae5c 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
@@ -61,6 +61,7 @@ import com.jogamp.opengl.GLFBODrawable;
import com.jogamp.opengl.GLRunnable;
import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.common.util.PropertyAccess;
/** Encapsulates the implementation of most of the GLAutoDrawable's
@@ -75,6 +76,8 @@ public class GLDrawableHelper {
}
protected static final boolean DEBUG = GLDrawableImpl.DEBUG;
+ private static final boolean DEBUG_SETCLEAR = GLContext.DEBUG_GL || DEBUG;
+
private final Object listenersLock = new Object();
private final ArrayList<GLEventListener> listeners = new ArrayList<GLEventListener>();
private final HashSet<GLEventListener> listenersToBeInit = new HashSet<GLEventListener>();
@@ -637,10 +640,10 @@ public class GLDrawableHelper {
}
}
- private final void init(final GLEventListener l, final GLAutoDrawable drawable, final boolean sendReshape, final boolean setViewport) {
+ private final void init(final GLEventListener l, final GLAutoDrawable drawable, final boolean sendReshape) {
l.init(drawable);
if(sendReshape) {
- reshape(l, drawable, 0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight(), setViewport, false /* checkInit */);
+ l.reshape(drawable, 0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
}
}
@@ -649,6 +652,7 @@ public class GLDrawableHelper {
* @param sendReshape set to true if the subsequent display call won't reshape, otherwise false to avoid double reshape.
**/
public final void init(final GLAutoDrawable drawable, final boolean sendReshape) {
+ setViewportAndClear(drawable, 0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
synchronized(listenersLock) {
final ArrayList<GLEventListener> _listeners = listeners;
final int listenerCount = _listeners.size();
@@ -660,11 +664,8 @@ public class GLDrawableHelper {
// 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 */);
+ init(listener, drawable, sendReshape);
}
- } else {
- // Expose same GL initialization if not using any GLEventListener
- drawable.getGL().glViewport(0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
}
}
}
@@ -686,7 +687,7 @@ public class GLDrawableHelper {
// 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 */, listenersToBeInit.size() + 1 == listenerCount /* setViewport if 1st init */ );
+ init( listener, drawable, true /* sendReshape */ );
}
listener.display(drawable);
}
@@ -711,41 +712,43 @@ public class GLDrawableHelper {
// 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 */, listenersToBeInit.size() + 1 == listenerCount /* setViewport if 1st init */ );
+ init( listener, drawable, true /* sendReshape */ );
}
action.run(drawable, listener);
}
}
}
- private final void reshape(final GLEventListener listener, final GLAutoDrawable drawable,
- final int x, final int y, final int width, final int height, final boolean setViewport, final boolean checkInit) {
- if(checkInit) {
- // GLEventListener may need to be init,
- // in case this one is added after the realization of the GLAutoDrawable
- synchronized(listenersLock) {
- if( listenersToBeInit.remove(listener) ) {
- listener.init(drawable);
- }
- }
- }
- if(setViewport) {
- if( GLContext.DEBUG_GL || DEBUG ) {
- final int glerr0 = drawable.getGL().glGetError();
- if( GL.GL_NO_ERROR != glerr0 ) {
- System.err.println("Info: GLDrawableHelper.reshape: pre-exisiting GL error 0x"+Integer.toHexString(glerr0));
- ExceptionUtils.dumpStack(System.err);
- }
- }
- drawable.getGL().glViewport(x, y, width, height);
- }
- listener.reshape(drawable, x, y, width, height);
+ /**
+ * Bug 1206: Security: Clear exposed framebuffer after creation and before visibility
+ * - Clear framebuffer after setting viewport
+ * - Since we only attempt to help against leaking un-initialized framebuffer content
+ * not against user-app faults, we do not clear a 2nd-buffer (double-buffering).
+ */
+ private final void setViewportAndClear(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
+ final GL gl = drawable.getGL();
+ if( DEBUG_SETCLEAR ) {
+ final int glerr0 = gl.glGetError();
+ if( GL.GL_NO_ERROR != glerr0 ) {
+ System.err.println("Info: GLDrawableHelper.reshape: pre-exisiting GL error 0x"+Integer.toHexString(glerr0));
+ ExceptionUtils.dumpStack(System.err);
+ }
+ }
+ gl.glViewport(x, y, width, height);
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT);
}
public final void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
+ setViewportAndClear(drawable, x, y, width, height);
synchronized(listenersLock) {
for (int i=0; i < listeners.size(); i++) {
- reshape(listeners.get(i), drawable, x, y, width, height, 0==i /* setViewport */, true /* checkInit */);
+ final GLEventListener l = listeners.get(i);
+ // GLEventListener may need to be init,
+ // in case this one is added after the realization of the GLAutoDrawable
+ if( listenersToBeInit.remove(l) ) {
+ l.init(drawable);
+ }
+ l.reshape(drawable, x, y, width, height);
}
}
}
@@ -874,9 +877,8 @@ public class GLDrawableHelper {
return false;
}
- GLRunnableTask rTask = null;
+ final GLRunnableTask rTask;
final Object rTaskLock = new Object();
- Throwable throwable = null;
synchronized(rTaskLock) {
boolean deferredHere;
synchronized(glRunnablesLock) {
@@ -910,13 +912,13 @@ public class GLDrawableHelper {
drawable.display();
} else if( wait ) {
try {
- rTaskLock.wait(); // free lock, allow execution of rTask
+ while( rTask.isInQueue() ) {
+ rTaskLock.wait(); // free lock, allow execution of rTask
+ }
} catch (final InterruptedException ie) {
- throwable = ie;
- }
- if(null==throwable) {
- throwable = rTask.getThrowable();
+ throw new InterruptedRuntimeException(ie);
}
+ final Throwable throwable = rTask.getThrowable();
if(null!=throwable) {
throw new RuntimeException(throwable);
}
@@ -941,9 +943,8 @@ public class GLDrawableHelper {
}
final int count = newGLRunnables.size();
- GLRunnableTask rTask = null;
+ final GLRunnableTask rTask;
final Object rTaskLock = new Object();
- Throwable throwable = null;
synchronized(rTaskLock) {
boolean deferredHere;
synchronized(glRunnablesLock) {
@@ -981,13 +982,13 @@ public class GLDrawableHelper {
drawable.display();
} else if( wait ) {
try {
- rTaskLock.wait(); // free lock, allow execution of rTask
+ while( rTask.isInQueue() ) {
+ rTaskLock.wait(); // free lock, allow execution of rTask
+ }
} catch (final InterruptedException ie) {
- throwable = ie;
- }
- if(null==throwable) {
- throwable = rTask.getThrowable();
+ throw new InterruptedRuntimeException(ie);
}
+ final Throwable throwable = rTask.getThrowable();
if(null!=throwable) {
throw new RuntimeException(throwable);
}
@@ -1082,6 +1083,21 @@ public class GLDrawableHelper {
return exclusiveContextThread;
}
+ /**
+ * Runs given {@code runnable} outside of a probable claimed exclusive thread,
+ * i.e. releases the exclusive thread, executes the runnable and reclaims it.
+ * @see #setExclusiveContextThread(Thread, GLContext)
+ * @since 2.3.2
+ */
+ public final void runOutsideOfExclusiveContextThread(final GLContext context, final Runnable runnable) {
+ final Thread t = setExclusiveContextThread(null, context);
+ try {
+ runnable.run();
+ } finally {
+ setExclusiveContextThread(t, context);
+ }
+ }
+
private static final ThreadLocal<WeakReference<Runnable>> perThreadInitAction = new ThreadLocal<WeakReference<Runnable>>();
private static final Runnable getLastInitAction() {
final WeakReference<Runnable> lastInitActionWR = perThreadInitAction.get();
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
index 849a08623..98a0a0948 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
@@ -67,14 +67,6 @@ public abstract class GLDrawableImpl implements GLDrawable {
this.requestedCapabilities = requestedCapabilities;
}
- /**
- * Returns the DynamicLookupHelper
- * @throws GLException if no DynamicLookupHelper is installed
- */
- public final GLDynamicLookupHelper getGLDynamicLookupHelper() throws GLException {
- return getFactoryImpl().getGLDynamicLookupHelper( getGLProfile().getImplName() );
- }
-
public final GLDrawableFactoryImpl getFactoryImpl() {
return (GLDrawableFactoryImpl) getFactory();
}
diff --git a/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java
index 39de3200d..7c75b0615 100644
--- a/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java
@@ -59,6 +59,16 @@ public abstract class GLDynamicLibraryBundleInfo implements DynamicLibraryBundle
public boolean shallLookupGlobal() { return false; }
@Override
+ public final boolean searchToolLibInSystemPath() {
+ return true;
+ }
+
+ @Override
+ public final boolean searchToolLibSystemPathFirst() {
+ return true;
+ }
+
+ @Override
public final RunnableExecutor getLibLoaderExecutor() {
return DynamicLibraryBundle.getDefaultRunnableExecutor();
}
diff --git a/src/jogl/classes/jogamp/opengl/GLRunnableTask.java b/src/jogl/classes/jogamp/opengl/GLRunnableTask.java
index 1a6024bfa..cfe3df95d 100644
--- a/src/jogl/classes/jogamp/opengl/GLRunnableTask.java
+++ b/src/jogl/classes/jogamp/opengl/GLRunnableTask.java
@@ -29,6 +29,7 @@
package jogamp.opengl;
import com.jogamp.opengl.GLRunnable;
+import com.jogamp.common.ExceptionUtils;
import com.jogamp.opengl.GLAutoDrawable;
/**
@@ -61,7 +62,7 @@ public class GLRunnableTask implements GLRunnable {
} catch (final Throwable t) {
runnableException = t;
if(catchExceptions) {
- runnableException.printStackTrace();
+ ExceptionUtils.dumpThrowable("", runnableException);
} else {
throw new RuntimeException(runnableException);
}
@@ -75,7 +76,7 @@ public class GLRunnableTask implements GLRunnable {
} catch (final Throwable t) {
runnableException = t;
if(catchExceptions) {
- runnableException.printStackTrace();
+ ExceptionUtils.dumpThrowable("", runnableException);
} else {
throw new RuntimeException(runnableException);
}
diff --git a/src/jogl/classes/jogamp/opengl/GLWorkerThread.java b/src/jogl/classes/jogamp/opengl/GLWorkerThread.java
index c03cdea02..3d0adfc9c 100644
--- a/src/jogl/classes/jogamp/opengl/GLWorkerThread.java
+++ b/src/jogl/classes/jogamp/opengl/GLWorkerThread.java
@@ -43,6 +43,9 @@ import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
+import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.opengl.GLContext;
/** Singleton thread upon which all OpenGL work is performed by
@@ -78,15 +81,18 @@ public class GLWorkerThread {
synchronized (GLWorkerThread.class) {
if (!started) {
lock = new Object();
- thread = new Thread(new WorkerRunnable(),
- "JOGL-GLWorkerThread-");
+ final WorkerRunnable worker = new WorkerRunnable();
+ thread = new InterruptSource.Thread(null, worker, "JOGL-GLWorkerThread-");
thread.setDaemon(true);
started = true;
synchronized (lock) {
thread.start();
try {
- lock.wait();
+ while(!worker.isRunning) {
+ lock.wait();
+ }
} catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
}
@@ -119,7 +125,7 @@ public class GLWorkerThread {
// less cooperatively
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
- Runtime.getRuntime().addShutdownHook(new Thread() {
+ Runtime.getRuntime().addShutdownHook(new InterruptSource.Thread() {
public void run() {
Object lockTemp = lock;
if (lockTemp == null) {
@@ -177,7 +183,9 @@ public class GLWorkerThread {
work = runnable;
lockTemp.notifyAll();
- lockTemp.wait();
+ while( null != work ) {
+ lockTemp.wait();
+ }
if (exception != null) {
final Throwable localException = exception;
exception = null;
@@ -222,10 +230,13 @@ public class GLWorkerThread {
protected static String getThreadName() { return Thread.currentThread().getName(); }
static class WorkerRunnable implements Runnable {
+ volatile boolean isRunning = false;
+
@Override
public void run() {
// Notify starting thread that we're ready
synchronized (lock) {
+ isRunning = true;
lock.notifyAll();
}
@@ -238,6 +249,7 @@ public class GLWorkerThread {
// Avoid race conditions with wanting to release contexts on this thread
lock.wait(1000);
} catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
if (GLContext.getCurrent() != null) {
@@ -269,8 +281,7 @@ public class GLWorkerThread {
final Runnable curAsync = queue.remove(0);
curAsync.run();
} catch (final Throwable t) {
- System.err.println(getThreadName()+": Exception occurred on JOGL OpenGL worker thread:");
- t.printStackTrace();
+ ExceptionUtils.dumpThrowable("suppressed", t); // Noncancelable
}
}
@@ -285,6 +296,7 @@ public class GLWorkerThread {
}
}
}
+ isRunning = false;
}
}
}
diff --git a/src/jogl/classes/jogamp/opengl/GLXExtensions.java b/src/jogl/classes/jogamp/opengl/GLXExtensions.java
index 9325c6f68..db4757e4d 100644
--- a/src/jogl/classes/jogamp/opengl/GLXExtensions.java
+++ b/src/jogl/classes/jogamp/opengl/GLXExtensions.java
@@ -34,4 +34,10 @@ public class GLXExtensions {
public static final String GLX_MESA_swap_control = "GLX_MESA_swap_control";
public static final String GLX_SGI_swap_control = "GLX_SGI_swap_control";
public static final String GLX_NV_swap_group = "GLX_NV_swap_group";
+
+ public static final String GLX_EXT_swap_control = "GLX_EXT_swap_control";
+ public static final String GLX_EXT_swap_control_tear = "GLX_EXT_swap_control_tear";
+
+ public static final String WGL_EXT_swap_control = "WGL_EXT_swap_control";
+ public static final String WGL_EXT_swap_control_tear = "WGL_EXT_swap_control_tear";
}
diff --git a/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java b/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java
index 9b9093a87..0f6c1f875 100644
--- a/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java
+++ b/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java
@@ -28,14 +28,19 @@
package jogamp.opengl;
import java.util.Collection;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.Map;
import com.jogamp.nativewindow.AbstractGraphicsDevice;
import com.jogamp.nativewindow.AbstractGraphicsScreen;
import com.jogamp.opengl.GLProfile;
import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.InterruptedRuntimeException;
+import com.jogamp.common.util.SourcedInterruptedException;
import com.jogamp.opengl.GLRendererQuirks;
public class SharedResourceRunner implements Runnable {
@@ -81,6 +86,29 @@ public class SharedResourceRunner implements Runnable {
/** Called within synchronized block. */
Collection<Resource> mapValues();
}
+ public static abstract class AImplementation implements Implementation {
+ private final HashMap<String /* uniqueId */, SharedResourceRunner.Resource> sharedMap = new HashMap<String, SharedResourceRunner.Resource>();
+ /** Called within synchronized block. Use w/ care! */
+ public Map<String /* uniqueId */, SharedResourceRunner.Resource> getSharedMap() {
+ return sharedMap;
+ }
+ @Override
+ public final void clear() {
+ sharedMap.clear();
+ }
+ @Override
+ public final SharedResourceRunner.Resource mapPut(final AbstractGraphicsDevice device, final SharedResourceRunner.Resource resource) {
+ return sharedMap.put(device.getUniqueID(), resource);
+ }
+ @Override
+ public final SharedResourceRunner.Resource mapGet(final AbstractGraphicsDevice device) {
+ return sharedMap.get(device.getUniqueID());
+ }
+ @Override
+ public final Collection<SharedResourceRunner.Resource> mapValues() {
+ return sharedMap.values();
+ }
+ }
final HashSet<String> devicesTried = new HashSet<String>();
final Implementation impl;
@@ -93,13 +121,13 @@ public class SharedResourceRunner implements Runnable {
AbstractGraphicsDevice releaseDevice;
private boolean getDeviceTried(final AbstractGraphicsDevice device) { // synchronized call
- return devicesTried.contains(device.getConnection());
+ return devicesTried.contains(device.getUniqueID());
}
private void addDeviceTried(final AbstractGraphicsDevice device) { // synchronized call
- devicesTried.add(device.getConnection());
+ devicesTried.add(device.getUniqueID());
}
private void removeDeviceTried(final AbstractGraphicsDevice device) { // synchronized call
- devicesTried.remove(device.getConnection());
+ devicesTried.remove(device.getUniqueID());
}
public SharedResourceRunner(final Implementation impl) {
@@ -141,13 +169,18 @@ public class SharedResourceRunner implements Runnable {
System.err.println("SharedResourceRunner.start() - start new Thread - "+getThreadName());
}
resetState();
- thread = new Thread(this, getThreadName()+"-SharedResourceRunner");
+ thread = new InterruptSource.Thread(null, this, getThreadName()+"-SharedResourceRunner");
thread.setDaemon(true); // Allow JVM to exit, even if this one is running
thread.start();
- while (!running) {
- try {
+ try {
+ while (!running) {
this.wait();
- } catch (final InterruptedException ex) { }
+ }
+ } catch (final InterruptedException ex) {
+ // Cleanup
+ shouldRelease = true;
+ this.notifyAll();
+ throw new InterruptedRuntimeException(ex);
}
}
}
@@ -163,11 +196,12 @@ public class SharedResourceRunner implements Runnable {
synchronized (this) {
shouldRelease = true;
this.notifyAll();
-
- while (running) {
- try {
+ try {
+ while (running) {
this.wait();
- } catch (final InterruptedException ex) { }
+ }
+ } catch (final InterruptedException ex) {
+ throw new InterruptedRuntimeException(ex);
}
}
}
@@ -188,7 +222,11 @@ public class SharedResourceRunner implements Runnable {
ExceptionUtils.dumpStack(System.err);
}
if ( impl.isDeviceSupported(device) ) {
- doAndWait(device, null);
+ try {
+ doAndWait(device, null);
+ } catch (final InterruptedException ex) {
+ throw new InterruptedRuntimeException(ex);
+ }
sr = impl.mapGet(device);
}
if (DEBUG) {
@@ -211,7 +249,11 @@ public class SharedResourceRunner implements Runnable {
if (DEBUG) {
System.err.println("SharedResourceRunner.releaseShared() " + device + ": trying - "+getThreadName());
}
- doAndWait(null, device);
+ try {
+ doAndWait(null, device);
+ } catch (final InterruptedException ex) {
+ throw new InterruptedRuntimeException(ex);
+ }
if (DEBUG) {
System.err.println("SharedResourceRunner.releaseShared() " + device + ": done - "+getThreadName());
}
@@ -221,7 +263,7 @@ public class SharedResourceRunner implements Runnable {
return sr;
}
- private final void doAndWait(final AbstractGraphicsDevice initDevice, final AbstractGraphicsDevice releaseDevice) {
+ private final void doAndWait(final AbstractGraphicsDevice initDevice, final AbstractGraphicsDevice releaseDevice) throws InterruptedException {
synchronized (this) {
// wait until thread becomes ready to init new device,
// pass the device and release the sync
@@ -229,26 +271,41 @@ public class SharedResourceRunner implements Runnable {
if (DEBUG) {
System.err.println("SharedResourceRunner.doAndWait() START init: " + initDevice + ", release: "+releaseDevice+" - "+threadName);
}
- while (!ready && running) {
- try {
+ try {
+ while (!ready && running) {
this.wait();
- } catch (final InterruptedException ex) { }
- }
- if (DEBUG) {
- System.err.println("SharedResourceRunner.doAndWait() set command: " + initDevice + ", release: "+releaseDevice+" - "+threadName);
- }
- this.initDevice = initDevice;
- this.releaseDevice = releaseDevice;
- this.notifyAll();
+ }
+ if (DEBUG) {
+ System.err.println("SharedResourceRunner.doAndWait() set command: " + initDevice + ", release: "+releaseDevice+" - "+threadName);
+ }
+ this.initDevice = initDevice;
+ this.releaseDevice = releaseDevice;
+ this.notifyAll();
- // wait until thread has init/released the device
- while ( running && ( !ready || null != this.initDevice || null != this.releaseDevice ) ) {
- try {
+ // wait until thread has init/released the device
+ while ( running && ( !ready || null != this.initDevice || null != this.releaseDevice ) ) {
this.wait();
- } catch (final InterruptedException ex) { }
+ }
+ } catch (final InterruptedException ex) {
+ final InterruptedException ex2 = SourcedInterruptedException.wrap(ex);
+ if (DEBUG) {
+ System.err.println("SharedResourceRunner.doAndWait() INTERRUPT init: " + initDevice + ", release: "+releaseDevice+" - "+threadName);
+ ExceptionUtils.dumpThrowable("", ex2);
+ }
+ // Cleanup initDevice due to exception!
+ final AbstractGraphicsDevice _initDevice = this.initDevice;
+ if( null != _initDevice ) {
+ if (DEBUG) {
+ System.err.println("SharedResourceRunner.doAndWait() Cleanup init: " + _initDevice + " -> release: "+this.releaseDevice+" - "+threadName);
+ }
+ this.releaseDevice = _initDevice;
+ this.initDevice = null;
+ this.notifyAll();
+ }
+ throw ex2;
}
if (DEBUG) {
- System.err.println("SharedResourceRunner.initializeAndWait END init: " + initDevice + ", release: "+releaseDevice+" - "+threadName);
+ System.err.println("SharedResourceRunner.doAndWait() END init: " + initDevice + ", release: "+releaseDevice+" - "+threadName);
}
}
// done
@@ -267,19 +324,18 @@ public class SharedResourceRunner implements Runnable {
while (!shouldRelease) {
try {
- // wait for stop or init
+ // wait until call-thread issues stop or init/released a device
ready = true;
if (DEBUG) {
System.err.println("SharedResourceRunner.run(): READY - " + threadName);
}
notifyAll();
- this.wait();
+ while ( !shouldRelease && null == initDevice && null == releaseDevice ) {
+ this.wait();
+ }
} catch (final InterruptedException ex) {
shouldRelease = true;
- if(DEBUG) {
- System.err.println("SharedResourceRunner.run(): INTERRUPTED - "+threadName);
- ex.printStackTrace();
- }
+ ExceptionUtils.dumpThrowable("handled", SourcedInterruptedException.wrap(ex)); // cancelable
}
ready = false;
@@ -296,7 +352,7 @@ public class SharedResourceRunner implements Runnable {
try {
sr = impl.createSharedResource(initDevice);
} catch (final Exception e) {
- e.printStackTrace();
+ ExceptionUtils.dumpThrowable("handled", e);
}
if (null != sr) {
impl.mapPut(initDevice, sr);
@@ -310,9 +366,10 @@ public class SharedResourceRunner implements Runnable {
if (null != sr) {
try {
impl.releaseSharedResource(sr);
- impl.mapPut(releaseDevice, null);
} catch (final Exception e) {
- e.printStackTrace();
+ ExceptionUtils.dumpThrowable("handled", e);
+ } finally {
+ impl.mapPut(releaseDevice, null);
}
}
}
@@ -345,8 +402,7 @@ public class SharedResourceRunner implements Runnable {
try {
impl.releaseSharedResource(iter.next());
} catch (final Throwable t) {
- System.err.println("Caught exception on thread "+getThreadName());
- t.printStackTrace();
+ ExceptionUtils.dumpThrowable("", t);
}
}
impl.clear();
diff --git a/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
index da81922a4..09d2dfda0 100644
--- a/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
+++ b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
@@ -33,7 +33,6 @@ import java.util.List;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GLES2;
import com.jogamp.opengl.GLException;
-
import com.jogamp.common.os.AndroidVersion;
import com.jogamp.common.os.Platform;
import com.jogamp.opengl.util.TimeFrameI;
@@ -364,7 +363,7 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl {
}
@Override
- protected final int getNextTextureImpl(final GL gl, final TextureFrame nextFrame) {
+ protected final int getNextTextureImpl(final GL gl, final TextureFrame nextFrame) throws InterruptedException {
int pts = TimeFrameI.INVALID_PTS;
if(null != mp || null != cam) {
final SurfaceTextureFrame sTexFrame = null != nextFrame ? (SurfaceTextureFrame) nextFrame : singleSTexFrame;
@@ -398,12 +397,8 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl {
boolean update = updateSurface;
if( !update ) {
synchronized(updateSurfaceLock) {
- if(!updateSurface) { // volatile OK.
- try {
- updateSurfaceLock.wait();
- } catch (final InterruptedException e) {
- e.printStackTrace();
- }
+ while(!updateSurface) { // volatile OK.
+ updateSurfaceLock.wait(); // propagates InterruptedException
}
update = updateSurface;
updateSurface = false;
diff --git a/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java b/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java
index 7cc009668..91573143d 100644
--- a/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java
+++ b/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java
@@ -41,6 +41,7 @@ import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
+import java.util.Locale;
import java.util.Set;
import java.util.Map.Entry;
@@ -330,7 +331,7 @@ public class AWTTilePainter {
// but that's the software rendering path which is very slow anyway.
final BufferedImage dstImage;
if( DEBUG_TILES ) {
- final String fname = String.format("file_%03d_0_tile_[%02d][%02d]_sz_%03dx%03d_pos0_%03d_%03d_yOff_%03d_pos1_%03d_%03d.png",
+ final String fname = String.format((Locale)null, "file_%03d_0_tile_[%02d][%02d]_sz_%03dx%03d_pos0_%03d_%03d_yOff_%03d_pos1_%03d_%03d.png",
_counter,
renderer.getParam(TileRenderer.TR_CURRENT_COLUMN), renderer.getParam(TileRenderer.TR_CURRENT_ROW),
tWidth, tHeight,
@@ -361,7 +362,7 @@ public class AWTTilePainter {
dstImage = tBuffer.image;
}
if( DEBUG_TILES ) {
- final String fname = String.format("file_%03d_1_tile_[%02d][%02d]_sz_%03dx%03d_pos0_%03d_%03d_yOff_%03d_pos1_%03d_%03d.png",
+ final String fname = String.format((Locale)null, "file_%03d_1_tile_[%02d][%02d]_sz_%03dx%03d_pos0_%03d_%03d_yOff_%03d_pos1_%03d_%03d.png",
_counter,
renderer.getParam(TileRenderer.TR_CURRENT_COLUMN), renderer.getParam(TileRenderer.TR_CURRENT_ROW),
tWidth, tHeight,
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index b6a05aeeb..28448d537 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -49,9 +49,9 @@ import com.jogamp.opengl.GLProfile;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
import jogamp.opengl.egl.EGLExtImpl;
import jogamp.opengl.egl.EGLExtProcAddressTable;
-import jogamp.opengl.windows.wgl.WindowsWGLContext;
import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.nio.Buffers;
@@ -168,19 +168,17 @@ public class EGLContext extends GLContextImpl {
final long eglConfig = config.getNativeConfig();
final EGLDrawableFactory factory = (EGLDrawableFactory) drawable.getFactoryImpl();
- final boolean hasOpenGLAPISupport = factory.hasOpenGLAPISupport();
+ final boolean hasFullOpenGLAPISupport = factory.hasOpenGLDesktopSupport();
final boolean useKHRCreateContext = factory.hasDefaultDeviceKHRCreateContext();
- final boolean allowOpenGLAPI = hasOpenGLAPISupport && useKHRCreateContext;
- final boolean ctDesktopGL = 0 == ( GLContext.CTX_PROFILE_ES & ctp );
+ final boolean ctDesktopGL = 0 == ( CTX_PROFILE_ES & ctp );
final boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
final boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ;
final boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ;
if(DEBUG) {
System.err.println(getThreadName() + ": EGLContext.createContextARBImpl: Start "+getGLVersion(reqMajor, reqMinor, ctp, "@creation")
- + ", hasOpenGLAPISupport "+hasOpenGLAPISupport
+ ", useKHRCreateContext "+useKHRCreateContext
- + ", allowOpenGLAPI "+allowOpenGLAPI
+ + ", OpenGL API Support "+hasFullOpenGLAPISupport
+ ", device "+device);
}
if ( 0 == eglDisplay ) {
@@ -203,8 +201,7 @@ public class EGLContext extends GLContextImpl {
* hence it must be switched before makeCurrent w/ different APIs, see:
* eglWaitClient();
*/
- if( ctDesktopGL && !allowOpenGLAPI ) {
- // if( ctDesktopGL && !hasOpenGLAPISupport ) {
+ if( ctDesktopGL && !hasFullOpenGLAPISupport ) {
if(DEBUG) {
System.err.println(getThreadName() + ": EGLContext.createContextARBImpl: DesktopGL not avail "+getGLVersion(reqMajor, reqMinor, ctp, "@creation"));
}
@@ -212,7 +209,7 @@ public class EGLContext extends GLContextImpl {
}
try {
- if( allowOpenGLAPI && device.getEGLVersion().compareTo(Version1_2) >= 0 ) {
+ if( hasFullOpenGLAPISupport && device.getEGLVersion().compareTo(Version1_2) >= 0 ) {
EGL.eglWaitClient(); // EGL >= 1.2
}
if( !EGL.eglBindAPI( ctDesktopGL ? EGL.EGL_OPENGL_API : EGL.EGL_OPENGL_ES_API) ) {
@@ -238,11 +235,11 @@ public class EGLContext extends GLContextImpl {
int index = ctx_attribs_idx_major + 2;
- /** if( ctDesktopGL && reqMinor >= 0 ) { // FIXME: No minor version probing for ES currently!
+ if( reqMinor >= 0 ) {
attribs.put(index + 0, EGLExt.EGL_CONTEXT_MINOR_VERSION_KHR);
attribs.put(index + 1, reqMinor);
index += 2;
- } */
+ }
if( ctDesktopGL && ( useMajor > 3 || useMajor == 3 && reqMinor >= 2 ) ) {
attribs.put(index + 0, EGLExt.EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR);
@@ -364,14 +361,17 @@ public class EGLContext extends GLContextImpl {
}
@Override
- protected final void updateGLXProcAddressTable() {
+ protected final void updateGLXProcAddressTable(final String contextFQN, final GLDynamicLookupHelper dlh) {
+ if( null == dlh ) {
+ throw new GLException("No GLDynamicLookupHelper for "+this);
+ }
final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
final String key = "EGL-"+adevice.getUniqueID();
+ // final String key = contextFQN;
if (DEBUG) {
System.err.println(getThreadName() + ": Initializing EGLextension address table: "+key);
}
-
ProcAddressTable table = null;
synchronized(mappedContextTypeObjectLock) {
table = mappedGLXProcAddress.get( key );
@@ -386,7 +386,7 @@ public class EGLContext extends GLContextImpl {
}
} else {
eglExtProcAddressTable = new EGLExtProcAddressTable(new GLProcAddressResolver());
- resetProcAddressTable(eglExtProcAddressTable);
+ resetProcAddressTable(eglExtProcAddressTable, dlh);
synchronized(mappedContextTypeObjectLock) {
mappedGLXProcAddress.put(key, eglExtProcAddressTable);
if(DEBUG) {
@@ -432,11 +432,21 @@ public class EGLContext extends GLContextImpl {
}
@Override
- protected boolean setSwapIntervalImpl(final int interval) {
- if( hasRendererQuirk(GLRendererQuirks.NoSetSwapInterval) ) {
- return false;
+ protected final Integer setSwapIntervalImpl2(final int interval) {
+ if( !drawable.getChosenGLCapabilities().isOnscreen() ||
+ hasRendererQuirk(GLRendererQuirks.NoSetSwapInterval) ) {
+ return null;
+ }
+ final int useInterval;
+ if( 0 > interval ) {
+ useInterval = Math.abs(interval);
+ } else {
+ useInterval = interval;
}
- return EGL.eglSwapInterval(drawable.getNativeSurface().getDisplayHandle(), interval);
+ if( EGL.eglSwapInterval(drawable.getNativeSurface().getDisplayHandle(), useInterval) ) {
+ return Integer.valueOf(useInterval);
+ }
+ return null;
}
static long eglGetProcAddress(final long eglGetProcAddressHandle, final String procname)
@@ -453,52 +463,32 @@ public class EGLContext extends GLContextImpl {
// Accessible ..
//
- /* pp */ void mapCurrentAvailableGLESVersion(final AbstractGraphicsDevice device) {
- mapStaticGLESVersion(device, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ /* pp */ static final boolean isGLES1(final int majorVersion, final int ctxOptions) {
+ return 0 != ( ctxOptions & GLContext.CTX_PROFILE_ES ) && majorVersion == 1 ;
}
- /* pp */ int getContextOptions() { return ctxOptions; }
- /* pp */ static void mapStaticGLESVersion(final AbstractGraphicsDevice device, final GLCapabilitiesImmutable caps) {
- final GLProfile glp = caps.getGLProfile();
- final int[] reqMajorCTP = new int[2];
- GLContext.getRequestMajorAndCompat(glp, reqMajorCTP);
- if( glp.isGLES() ) {
- if( reqMajorCTP[0] >= 3 ) {
- reqMajorCTP[1] |= GLContext.CTX_IMPL_ES3_COMPAT | GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ;
- } else if( reqMajorCTP[0] >= 2 ) {
- reqMajorCTP[1] |= GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ;
- }
- }
- if( !caps.getHardwareAccelerated() ) {
- reqMajorCTP[1] |= GLContext.CTX_IMPL_ACCEL_SOFT;
+ /* pp */ static final boolean isGLES2ES3(final int majorVersion, final int ctxOptions) {
+ if( 0 != ( ctxOptions & CTX_PROFILE_ES ) ) {
+ return 2 == majorVersion || 3 == majorVersion;
+ } else {
+ return false;
}
- mapStaticGLESVersion(device, reqMajorCTP[0], 0, reqMajorCTP[1]);
}
- /* pp */ static void mapStaticGLESVersion(final AbstractGraphicsDevice device, final int major, final int minor, final int ctp) {
- if( 0 != ( ctp & GLContext.CTX_PROFILE_ES) ) {
- // ES1, ES2, ES3, ..
- mapStaticGLESVersion(device, major /* reqMajor */, major, minor, ctp);
- if( 3 == major ) {
- // map ES2 -> ES3
- mapStaticGLESVersion(device, 2 /* reqMajor */, major, minor, ctp);
- }
- }
+ /* pp */ static final boolean isGLDesktop(final int ctxOptions) {
+ return 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE));
}
- private static void mapStaticGLESVersion(final AbstractGraphicsDevice device, final int reqMajor, final int major, final int minor, final int ctp) {
- GLContext.mapAvailableGLVersion(device, reqMajor, GLContext.CTX_PROFILE_ES, major, minor, ctp);
- if(! ( device instanceof EGLGraphicsDevice ) ) {
- final EGLGraphicsDevice eglDevice = new EGLGraphicsDevice(device.getHandle(), EGL.EGL_NO_DISPLAY, device.getConnection(), device.getUnitID(), null);
- GLContext.mapAvailableGLVersion(eglDevice, reqMajor, GLContext.CTX_PROFILE_ES, major, minor, ctp);
- }
+ protected static StringBuilder getGLProfile(final StringBuilder sb, final int ctp) {
+ return GLContext.getGLProfile(sb, ctp);
}
- protected static String getGLVersion(final int major, final int minor, final int ctp, final String gl_version) {
- return GLContext.getGLVersion(major, minor, ctp, gl_version);
+ /* pp */ int getContextOptions() { return ctxOptions; }
+ protected static void remapAvailableGLVersions(final AbstractGraphicsDevice fromDevice, final AbstractGraphicsDevice toDevice) {
+ GLContextImpl.remapAvailableGLVersions(fromDevice, toDevice);
}
-
- protected static boolean getAvailableGLVersionsSet(final AbstractGraphicsDevice device) {
- return GLContext.getAvailableGLVersionsSet(device);
+ protected static synchronized void setMappedGLVersionListener(final MappedGLVersionListener mvl) {
+ GLContextImpl.setMappedGLVersionListener(mvl);
}
- protected static void setAvailableGLVersionsSet(final AbstractGraphicsDevice device, final boolean set) {
- GLContext.setAvailableGLVersionsSet(device, set);
+
+ protected static String getGLVersion(final int major, final int minor, final int ctp, final String gl_version) {
+ return GLContext.getGLVersion(major, minor, ctp, gl_version);
}
protected static String toHexString(final int hex) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
index 3d2d03403..fcd4f54eb 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
@@ -80,10 +80,17 @@ public class EGLDisplayUtil {
static EGLDisplayRef getOrCreateOpened(final long eglDisplay, final IntBuffer major, final IntBuffer minor) {
final EGLDisplayRef o = (EGLDisplayRef) openEGLDisplays.get(eglDisplay);
if( null == o ) {
- if( EGL.eglInitialize(eglDisplay, major, minor) ) {
+ final boolean ok = EGL.eglInitialize(eglDisplay, major, minor);
+ if( DEBUG ) {
+ System.err.println("EGLDisplayUtil.EGL.eglInitialize 0x"+Long.toHexString(eglDisplay)+" -> "+ok);
+ }
+ if( ok ) {
final EGLDisplayRef n = new EGLDisplayRef(eglDisplay);
openEGLDisplays.put(eglDisplay, n);
n.initRefCount++;
+ if( DEBUG ) {
+ System.err.println("EGLDisplayUtil.EGL.eglInitialize "+n);
+ }
if( null == singletonEGLDisplay ) {
singletonEGLDisplay = n;
}
@@ -113,7 +120,12 @@ public class EGLDisplayUtil {
if( 0 < o.initRefCount ) { // no negative refCount
o.initRefCount--;
if( 0 == o.initRefCount ) {
- res[0] = EGL.eglTerminate(eglDisplay);
+ final boolean ok = EGL.eglTerminate(eglDisplay);
+ if( DEBUG ) {
+ System.err.println("EGLDisplayUtil.EGL.eglTerminate 0x"+Long.toHexString(eglDisplay)+" -> "+ok);
+ System.err.println("EGLDisplayUtil.EGL.eglTerminate "+o);
+ }
+ res[0] = ok;
if( o == singletonEGLDisplay ) {
singletonEGLDisplay = null;
}
@@ -340,6 +352,22 @@ public class EGLDisplayUtil {
* <p>
* Using the default {@link ToolkitLock}, via {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
* </p>
+ * @param adevice
+ * @return an uninitialized {@link EGLGraphicsDevice}
+ */
+ public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(final AbstractGraphicsDevice aDevice) {
+ return new EGLGraphicsDevice(aDevice, EGL.EGL_NO_DISPLAY, eglLifecycleCallback);
+ }
+
+ /**
+ * Returns an uninitialized {@link EGLGraphicsDevice}. User needs to issue {@link EGLGraphicsDevice#open()} before usage.
+ * <p>
+ * Using {@link #eglGetDisplayAndInitialize(long[])} for the {@link EGLGraphicsDevice#open()} implementation
+ * and {@link #eglTerminate(long)} for {@link EGLGraphicsDevice#close()}.
+ * </p>
+ * <p>
+ * Using the default {@link ToolkitLock}, via {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
+ * </p>
* @param surface
* @return an uninitialized EGLGraphicsDevice
*/
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
index e63a63634..ef3c96aeb 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
@@ -36,6 +36,7 @@
package jogamp.opengl.egl;
+import com.jogamp.common.ExceptionUtils;
import com.jogamp.nativewindow.ProxySurface;
import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.GLException;
@@ -82,7 +83,10 @@ public class EGLDrawable extends GLDrawableImpl {
final EGLSurface eglSurf = (EGLSurface) surface;
final long eglSurfHandle = eglSurf.getSurfaceHandle();
if(DEBUG) {
- System.err.println(getThreadName() + ": destroyHandle of "+eglSurf);
+ System.err.println(getThreadName() + ": EGLDrawable: destroyHandle of "+toHexString(eglSurfHandle));
+ ProxySurfaceImpl.dumpHierarchy(System.err, eglSurf);
+ System.err.println(getThreadName() + ": EGLSurface : "+eglSurf);
+ ExceptionUtils.dumpStack(System.err);
}
if( !eglSurf.containsUpstreamOptionBits( ProxySurface.OPT_UPSTREAM_SURFACELESS ) &&
EGL.EGL_NO_SURFACE == eglSurfHandle ) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index 4fecafdfc..fed02f34e 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -38,10 +38,9 @@ package jogamp.opengl.egl;
import java.nio.IntBuffer;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
@@ -67,6 +66,7 @@ import com.jogamp.opengl.GLProfile;
import jogamp.common.os.PlatformPropsImpl;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
+import jogamp.opengl.GLContextImpl.MappedGLVersion;
import jogamp.opengl.GLDrawableFactoryImpl;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.GLDynamicLookupHelper;
@@ -78,7 +78,6 @@ import com.jogamp.common.nio.Buffers;
import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.common.os.DynamicLookupHelper;
import com.jogamp.common.os.Platform;
-import com.jogamp.common.util.PropertyAccess;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.common.util.VersionNumber;
import com.jogamp.nativewindow.GenericUpstreamSurfacelessHook;
@@ -90,17 +89,20 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
protected static final boolean DEBUG = GLDrawableFactoryImpl.DEBUG; // allow package access
private static final boolean DEBUG_SHAREDCTX = DEBUG || GLContext.DEBUG;
- /* package */ static final boolean QUERY_EGL_ES_NATIVE_TK;
-
static {
Debug.initSingleton();
- QUERY_EGL_ES_NATIVE_TK = PropertyAccess.isPropertyDefined("jogl.debug.EGLDrawableFactory.QueryNativeTK", true);
}
private static boolean eglDynamicLookupHelperInit = false;
private static GLDynamicLookupHelper eglES1DynamicLookupHelper = null;
private static GLDynamicLookupHelper eglES2DynamicLookupHelper = null;
private static GLDynamicLookupHelper eglGLnDynamicLookupHelper = null;
+ private static boolean isANGLE = false;
+ private static boolean hasX11 = false;
+ private static String defaultConnection = null;
+ private static EGLGraphicsDevice defaultDevice = null;
+ private static EGLFeatures defaultDeviceEGLFeatures = null;
+ private static SharedResource defaultSharedResource = null;
private static final boolean isANGLE(final GLDynamicLookupHelper dl) {
if(Platform.OSType.WINDOWS == PlatformPropsImpl.OS_TYPE) {
@@ -128,7 +130,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
public EGLFeatures(final EGLGraphicsDevice device) {
final long eglDisplay = device.getHandle();
vendor = EGL.eglQueryString(eglDisplay, EGL.EGL_VENDOR);
- if(DEBUG) {
+ if(DEBUG_SHAREDCTX) {
System.err.println("EGLFeatures on device "+device+", vendor "+vendor);
}
version = device.getEGLVersion();
@@ -139,13 +141,13 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
final String eglClientAPIStr = EGL.eglQueryString(eglDisplay, EGL.EGL_CLIENT_APIS);
if( hasEGL_1_4 ) {
final String[] eglClientAPIs = eglClientAPIStr.split("\\s");
- for(int i=eglClientAPIs.length-1; i>=0; i--) {
+ for(int i=eglClientAPIs.length-1; !_hasGLAPI && i>=0; i--) {
_hasGLAPI = eglClientAPIs[i].equals("OpenGL");
}
}
hasGLAPI = _hasGLAPI;
- if(DEBUG) {
- System.err.println(" Client APIs: "+eglClientAPIStr+"; has EGL 1.4 "+hasEGL_1_4+" -> has OpenGL "+hasGLAPI);
+ if(DEBUG_SHAREDCTX) {
+ System.err.println(" Client APIs: '"+eglClientAPIStr+"'; has EGL 1.4 "+hasEGL_1_4+" -> has OpenGL "+hasGLAPI);
}
}
{
@@ -163,7 +165,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
hasKHRSurfaceless = extensions.contains("EGL_KHR_surfaceless_context");
}
- if(DEBUG) {
+ if(DEBUG_SHAREDCTX) {
System.err.println(" Extensions: "+extensions);
System.err.println(" KHR_create_context: "+hasKHRCreateContext);
System.err.println(" KHR_surfaceless_context: "+hasKHRSurfaceless);
@@ -193,12 +195,16 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
eglDynamicLookupHelperInit = true;
// Check for other underlying stuff ..
- if(NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true)) {
+ final String nwt = NativeWindowFactory.getNativeWindowType(true);
+ if(NativeWindowFactory.TYPE_X11 == nwt) {
hasX11 = true;
try {
ReflectionUtil.createInstance("jogamp.opengl.x11.glx.X11GLXGraphicsConfigurationFactory", EGLDrawableFactory.class.getClassLoader());
} catch (final Exception jre) { /* n/a .. */ }
+ } else {
+ hasX11 = false;
}
+ defaultConnection = NativeWindowFactory.getDefaultDisplayConnection(nwt);
/**
* FIXME: Probably need to move EGL from a static model
@@ -337,14 +343,14 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
// The act of constructing them causes them to be registered
EGLGraphicsConfigurationFactory.registerFactory();
- sharedMap = new HashMap<String, SharedResourceRunner.Resource>();
-
- // FIXME: defaultDevice.open() triggers eglInitialize(..) which crashed on Windows w/ Chrome/ANGLE, FF/ANGLE!
- defaultDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ // Note: defaultDevice.open() triggers eglInitialize(..) which crashed on Windows w/ Chrome/ANGLE, FF/ANGLE!
+ // Hence opening will happen later, eventually
+ defaultDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, defaultConnection, AbstractGraphicsDevice.DEFAULT_UNIT);
// Init shared resources off thread
// Will be released via ShutdownHook
- sharedResourceRunner = new SharedResourceRunner(new SharedResourceImplementation());
+ sharedResourceImplementation = new SharedResourceImplementation();
+ sharedResourceRunner = new SharedResourceRunner(sharedResourceImplementation);
sharedResourceRunner.start();
}
}
@@ -353,7 +359,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
protected final boolean isComplete() {
- return null != sharedMap; // null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper;
+ return null != sharedResourceImplementation; // null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper || ..;
}
@@ -366,9 +372,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
sharedResourceRunner.stop();
sharedResourceRunner = null;
}
- if(null != sharedMap) {
- sharedMap.clear();
- sharedMap = null;
+ if(null != sharedResourceImplementation) {
+ sharedResourceImplementation.clear();
+ sharedResourceImplementation = null;
}
if(null != defaultDevice) {
@@ -395,57 +401,63 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
private void dumpMap() {
- synchronized(sharedMap) {
- System.err.println("EGLDrawableFactory.map "+sharedMap.size());
+ synchronized(sharedResourceImplementation) {
+ final Map<String /* uniqueId */, SharedResourceRunner.Resource> sharedMap = sharedResourceImplementation.getSharedMap();
+ System.err.println("EGLDrawableFactory.MapGLVersion.map "+sharedMap.size());
int i=0;
final Set<String> keys = sharedMap.keySet();
for(final Iterator<String> keyI = keys.iterator(); keyI.hasNext(); i++) {
final String key = keyI.next();
final SharedResource sr = (SharedResource) sharedMap.get(key);
- System.err.println("EGLDrawableFactory.map["+i+"] "+key+" -> "+sr.getDevice()+", avail "+sr.isAvailable+
- "gln [quirks "+sr.rendererQuirksGLn+", ctp "+EGLContext.getGLVersion(3, 0, sr.ctpGLn, null)+"], "+
- "es1 [quirks "+sr.rendererQuirksES1+", ctp "+EGLContext.getGLVersion(1, 0, sr.ctpES1, null)+"], "+
- "es2/3 [quirks "+sr.rendererQuirksES3ES2+", ctp "+EGLContext.getGLVersion(2, 0, sr.ctpES3ES2, null)+"]");
+ System.err.println("EGLDrawableFactory.MapGLVersion.map["+i+"] "+key+" -> "+sr.getDevice()+", avail "+sr.isAvailable+", "+
+ "es1 [avail "+sr.isAvailableES1+", quirks "+sr.rendererQuirksES1+", ctp "+EGLContext.getGLVersion(1, 0, sr.ctpES1, null)+"], "+
+ "es2 [avail "+sr.isAvailableES2+", quirks "+sr.rendererQuirksES2+", ctp "+EGLContext.getGLVersion(2, 0, sr.ctpES2, null)+"], "+
+ "es3 [avail "+sr.isAvailableES3+", quirks "+sr.rendererQuirksES3+", ctp "+EGLContext.getGLVersion(2, 0, sr.ctpES3, null)+"], "+
+ "gln [avail "+sr.isAvailableGLn+", quirks "+sr.rendererQuirksGLn+", ctp "+EGLContext.getGLVersion(3, 0, sr.ctpGLn, null)+"]");
}
;
}
}
- private boolean isANGLE = false;
- private boolean hasX11 = false;
- private EGLGraphicsDevice defaultDevice = null;
- private EGLFeatures defaultDeviceEGLFeatures;
+ private SharedResourceImplementation sharedResourceImplementation;
private SharedResourceRunner sharedResourceRunner;
- private HashMap<String /* uniqueKey */, SharedResourceRunner.Resource> sharedMap;
static class SharedResource implements SharedResourceRunner.Resource {
private EGLGraphicsDevice device;
- // private final EGLContext contextES1;
- // private final EGLContext contextES2;
- // private final EGLContext contextES3;
final boolean isAvailable;
- final GLRendererQuirks rendererQuirksGLn;
+ final boolean isAvailableES1;
+ final boolean isAvailableES2;
+ final boolean isAvailableES3;
+ final boolean isAvailableGLn;
final GLRendererQuirks rendererQuirksES1;
- final GLRendererQuirks rendererQuirksES3ES2;
- final int ctpGLn;
+ final GLRendererQuirks rendererQuirksES2;
+ final GLRendererQuirks rendererQuirksES3;
+ final GLRendererQuirks rendererQuirksGLn;
final int ctpES1;
- final int ctpES3ES2;
+ final int ctpES2;
+ final int ctpES3;
+ final int ctpGLn;
- SharedResource(final EGLGraphicsDevice dev, final boolean isAvailable,
- final GLRendererQuirks rendererQuirksGLn, final int ctpGLn,
- final GLRendererQuirks rendererQuirksES1, final int ctpES1,
- final GLRendererQuirks rendererQuirksES3ES2, final int ctpES3ES2) {
+ SharedResource(final EGLGraphicsDevice dev,
+ final boolean isAvailableES1, final GLRendererQuirks rendererQuirksES1, final int ctpES1,
+ final boolean isAvailableES2, final GLRendererQuirks rendererQuirksES2, final int ctpES2,
+ final boolean isAvailableES3, final GLRendererQuirks rendererQuirksES3, final int ctpES3,
+ final boolean isAvailableGLn, final GLRendererQuirks rendererQuirksGLn, final int ctpGLn) {
this.device = dev;
- this.isAvailable = isAvailable;
-
- this.rendererQuirksGLn = rendererQuirksGLn;
- this.ctpGLn = ctpGLn;
+ this.isAvailable = isAvailableES1 || isAvailableES2 || isAvailableES3 || isAvailableGLn;
+ this.isAvailableES1 = isAvailableES1;
this.rendererQuirksES1 = rendererQuirksES1;
this.ctpES1 = ctpES1;
-
- this.rendererQuirksES3ES2 = rendererQuirksES3ES2;
- this.ctpES3ES2 = ctpES3ES2;
+ this.isAvailableES2 = isAvailableES2;
+ this.rendererQuirksES2 = rendererQuirksES2;
+ this.ctpES2 = ctpES2;
+ this.isAvailableES3 = isAvailableES3;
+ this.rendererQuirksES3 = rendererQuirksES3;
+ this.ctpES3 = ctpES3;
+ this.isAvailableGLn = isAvailableGLn;
+ this.rendererQuirksGLn = rendererQuirksGLn;
+ this.ctpGLn = ctpGLn;
}
@Override
@@ -470,8 +482,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
public GLRendererQuirks getRendererQuirks(final GLProfile glp) {
if( null == glp ) {
- if( null != rendererQuirksES3ES2 ) {
- return rendererQuirksES3ES2;
+ if( null != rendererQuirksES3 ) {
+ return rendererQuirksES3;
+ } else if( null != rendererQuirksES2 ) {
+ return rendererQuirksES2;
} else if( null != rendererQuirksES1 ) {
return rendererQuirksES1;
} else {
@@ -481,33 +495,18 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
return rendererQuirksGLn;
} else if( glp.isGLES1() ) {
return rendererQuirksES1;
- } else {
- return rendererQuirksES3ES2;
+ } else if( glp.isGLES2() ) {
+ return rendererQuirksES2;
+ } else /* if( glp.isGLES3() ) */ {
+ return rendererQuirksES3;
}
}
}
- class SharedResourceImplementation implements SharedResourceRunner.Implementation {
- @Override
- public void clear() {
- sharedMap.clear();
- }
- @Override
- public SharedResourceRunner.Resource mapPut(final AbstractGraphicsDevice device, final SharedResourceRunner.Resource resource) {
- return sharedMap.put(device.getConnection(), resource);
- }
- @Override
- public SharedResourceRunner.Resource mapGet(final AbstractGraphicsDevice device) {
- return sharedMap.get(device.getConnection());
- }
- @Override
- public Collection<SharedResourceRunner.Resource> mapValues() {
- return sharedMap.values();
- }
-
+ class SharedResourceImplementation extends SharedResourceRunner.AImplementation {
@Override
public boolean isDeviceSupported(final AbstractGraphicsDevice device) {
- return null != sharedMap; // null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper
+ return null != sharedResourceImplementation; // null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper || ..
}
@Override
@@ -523,78 +522,128 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
private SharedResource createEGLSharedResourceImpl(final AbstractGraphicsDevice adevice) {
- final GLRendererQuirks[] rendererQuirksES1 = new GLRendererQuirks[] { null };
- final GLRendererQuirks[] rendererQuirksES3ES2 = new GLRendererQuirks[] { null };
- final GLRendererQuirks[] rendererQuirksGLn = new GLRendererQuirks[] { null };
- final int[] ctpES1 = new int[] { EGLContext.CTX_PROFILE_ES };
- final int[] ctpES3ES2 = new int[] { EGLContext.CTX_PROFILE_ES };
- final int[] ctpGLn = new int[] { EGLContext.CTX_PROFILE_CORE };
-
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.createShared(): device "+adevice);
+ System.err.println("EGLDrawableFactory.MapGLVersions: device "+adevice);
}
- boolean madeCurrentES1 = false;
- boolean madeCurrentES2 = false;
- boolean madeCurrentES3 = false;
- boolean madeCurrentGLn = false;
-
- if( null != eglGLnDynamicLookupHelper ) {
- // OpenGL 3.1 core -> GL3, will utilize normal desktop profile mapping
- final int[] major = { 3 };
- final int[] minor = { 1 }; // FIXME: No minor version probing for ES currently!
- madeCurrentGLn = mapAvailableEGLESConfig(adevice, major, minor,
- ctpGLn, rendererQuirksGLn) && 0 != major[0];
+ final boolean initDefaultDevice;
+ if( 0 == defaultDevice.getHandle() ) { // Note: GLProfile always triggers EGL device initialization first!
+ initDefaultDevice = true;
+ defaultDevice.open();
+ defaultDeviceEGLFeatures = new EGLFeatures(defaultDevice);
+ if ( DEBUG_SHAREDCTX ) {
+ System.err.println("EGLDrawableFactory.MapGLVersions: defaultDevice "+defaultDevice);
+ System.err.println("EGLDrawableFactory.MapGLVersions: defaultDevice EGLFeatures "+defaultDeviceEGLFeatures);
+ }
+ // Probe for GLRendererQuirks.SingletonEGLDisplayOnly
+ final boolean singletonEGLDisplayOnlyVendor, singletonEGLDisplayOnlyProbe;
+ if( defaultDeviceEGLFeatures.vendor.contains("NVIDIA") ) { // OpenGL ES 3.1 NVIDIA 355.06 unstable
+ singletonEGLDisplayOnlyVendor=true;
+ singletonEGLDisplayOnlyProbe=false;
+ } else {
+ singletonEGLDisplayOnlyVendor=false;
+ final long secondEGLDisplay = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY);
+ singletonEGLDisplayOnlyProbe = EGL.EGL_NO_DISPLAY == secondEGLDisplay;
+ }
+ if( singletonEGLDisplayOnlyVendor || singletonEGLDisplayOnlyProbe ) {
+ final int quirk = GLRendererQuirks.SingletonEGLDisplayOnly;
+ GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
+ EGLDisplayUtil.setSingletonEGLDisplayOnly(true);
+ if ( DEBUG_SHAREDCTX ) {
+ if( singletonEGLDisplayOnlyVendor ) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Vendor: "+defaultDeviceEGLFeatures);
+ } else if( singletonEGLDisplayOnlyProbe ) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Second eglGetDisplay(EGL_DEFAULT_DISPLAY) failed");
+ }
+ }
+ }
} else {
- madeCurrentGLn = false;
+ initDefaultDevice = false;
+ if( null == defaultSharedResource ) {
+ throw new InternalError("XXX: defaultDevice "+defaultDevice+", adevice "+adevice);
+ }
}
- EGLContext.setAvailableGLVersionsSet(adevice, true);
- if( null != eglES1DynamicLookupHelper ) {
- final int[] major = { 1 };
- final int[] minor = { 0 };
- madeCurrentES1 = mapAvailableEGLESConfig(adevice, major, minor,
- ctpES1, rendererQuirksES1) && 1 == major[0];
- } else {
- madeCurrentES1 = false;
- }
- if( null != eglES2DynamicLookupHelper ) {
- // ES3 Query
- final int[] major = { 3 };
- final int[] minor = { 0 };
- madeCurrentES3 = mapAvailableEGLESConfig(adevice, major, minor,
- ctpES3ES2, rendererQuirksES3ES2) && 3 == major[0];
- if( !madeCurrentES3 ) {
- // ES2 Query, may result in ES3
- major[0] = 2;
- if( mapAvailableEGLESConfig(adevice, major, minor,
- ctpES3ES2, rendererQuirksES3ES2) )
- {
- switch( major[0] ) {
- case 2: madeCurrentES2 = true; break;
- case 3: madeCurrentES3 = true; break;
- default: throw new InternalError("XXXX Got "+major[0]);
+ final boolean[] mappedToDefaultDevice = { false };
+ final GLRendererQuirks[] rendererQuirksES1 = new GLRendererQuirks[] { null };
+ final GLRendererQuirks[] rendererQuirksES2 = new GLRendererQuirks[] { null };
+ final GLRendererQuirks[] rendererQuirksES3 = new GLRendererQuirks[] { null };
+ final GLRendererQuirks[] rendererQuirksGLn = new GLRendererQuirks[] { null };
+ final int[] ctpES1 = new int[] { 0 };
+ final int[] ctpES2 = new int[] { 0 };
+ final int[] ctpES3 = new int[] { 0 };
+ final int[] ctpGLn = new int[] { 0 };
+ final boolean[] madeCurrentES1 = { false };
+ final boolean[] madeCurrentES2 = { false };
+ final boolean[] madeCurrentES3 = { false };
+ final boolean[] madeCurrentGLn = { false };
+
+ final GLContextImpl.MappedGLVersionListener mvl = new GLContextImpl.MappedGLVersionListener() {
+ @Override
+ public void glVersionMapped(final MappedGLVersion e) {
+ if ( DEBUG_SHAREDCTX ) {
+ System.err.println("EGLDrawableFactory.MapGLVersions: Mapped: "+e);
+ }
+ if ( EGLContext.isGLES2ES3(e.ctxVersion.getMajor(), e.ctxOptions) ) {
+ if( e.ctxVersion.getMajor() == 3 ) {
+ madeCurrentES3[0] = true;
+ rendererQuirksES3[0] = e.quirks;
+ ctpES3[0] = e.ctxOptions;
}
+ madeCurrentES2[0] = true;
+ rendererQuirksES2[0] = e.quirks;
+ ctpES2[0] = e.ctxOptions;
+ } else if ( EGLContext.isGLES1(e.ctxVersion.getMajor(), e.ctxOptions) ) {
+ madeCurrentES1[0] = true;
+ rendererQuirksES1[0] = e.quirks;
+ ctpES1[0] = e.ctxOptions;
+ } else if( EGLContext.isGLDesktop(e.ctxOptions) ) {
+ madeCurrentGLn[0] = true;
+ rendererQuirksGLn[0] = e.quirks;
+ ctpGLn[0] = e.ctxOptions;
}
}
+ };
+ final SharedResource sr;
+ final EGLGraphicsDevice[] eglDevice = { null };
+ final boolean mapSuccess;
+ EGLContext.setMappedGLVersionListener(mvl);
+ try {
+ // Query triggers profile mapping!
+ mapSuccess = mapAvailableEGLESConfig(adevice, mappedToDefaultDevice, eglDevice);
+ } finally {
+ EGLContext.setMappedGLVersionListener(null);
}
- if( hasX11 ) {
- handleDontCloseX11DisplayQuirk(rendererQuirksES1[0]);
- handleDontCloseX11DisplayQuirk(rendererQuirksES3ES2[0]);
+ if( mappedToDefaultDevice[0] ) {
+ EGLContext.remapAvailableGLVersions(defaultDevice, adevice);
+ sr = defaultSharedResource;
+ } else {
+ if( hasX11 ) {
+ handleDontCloseX11DisplayQuirk(rendererQuirksES1[0]);
+ handleDontCloseX11DisplayQuirk(rendererQuirksGLn[0]);
+ handleDontCloseX11DisplayQuirk(rendererQuirksES3[0]);
+ handleDontCloseX11DisplayQuirk(rendererQuirksES2[0]);
+ }
+ sr = new SharedResource(eglDevice[0],
+ madeCurrentES1[0], rendererQuirksES1[0], ctpES1[0],
+ madeCurrentES2[0], rendererQuirksES2[0], ctpES2[0],
+ madeCurrentES3[0], rendererQuirksES3[0], ctpES3[0],
+ madeCurrentGLn[0], rendererQuirksGLn[0], ctpGLn[0]);
+ if( initDefaultDevice ) {
+ defaultSharedResource = sr;
+ }
}
- final SharedResource sr = new SharedResource(defaultDevice,
- madeCurrentGLn || madeCurrentES1 || madeCurrentES2 || madeCurrentES3,
- rendererQuirksGLn[0], ctpGLn[0],
- rendererQuirksES1[0], ctpES1[0],
- rendererQuirksES3ES2[0], ctpES3ES2[0]);
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.createShared: devices: queried nativeTK "+QUERY_EGL_ES_NATIVE_TK+", adevice " + adevice + ", defaultDevice " + defaultDevice);
- System.err.println("EGLDrawableFactory.createShared: context GLn: " + madeCurrentGLn + ", quirks "+rendererQuirksGLn[0]);
- System.err.println("EGLDrawableFactory.createShared: context ES1: " + madeCurrentES1 + ", quirks "+rendererQuirksES1[0]);
- System.err.println("EGLDrawableFactory.createShared: context ES2: " + madeCurrentES2 + ", quirks "+rendererQuirksES3ES2[0]);
- System.err.println("EGLDrawableFactory.createShared: context ES3: " + madeCurrentES3 + ", quirks "+rendererQuirksES3ES2[0]);
+ System.err.println("EGLDrawableFactory.MapGLVersions: mapSuccess "+mapSuccess+", mappedToDefaultDevice "+mappedToDefaultDevice[0]);
+ System.err.println("EGLDrawableFactory.MapGLVersions: defDevice : " + defaultDevice);
+ System.err.println("EGLDrawableFactory.MapGLVersions: adevice : " + adevice);
+ System.err.println("EGLDrawableFactory.MapGLVersions: eglDevice : " + sr.device);
+ System.err.println("EGLDrawableFactory.MapGLVersions: context ES1: " + sr.isAvailableES1 + ", quirks "+sr.rendererQuirksES1);
+ System.err.println("EGLDrawableFactory.MapGLVersions: context ES2: " + sr.isAvailableES2 + ", quirks "+sr.rendererQuirksES2);
+ System.err.println("EGLDrawableFactory.MapGLVersions: context ES3: " + sr.isAvailableES3 + ", quirks "+sr.rendererQuirksES3);
+ System.err.println("EGLDrawableFactory.MapGLVersions: context GLn: " + sr.isAvailableGLn + ", quirks "+sr.rendererQuirksGLn);
dumpMap();
}
return sr;
@@ -607,200 +656,218 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
private boolean mapAvailableEGLESConfig(final AbstractGraphicsDevice adevice,
- final int[] majorVersion, final int[] minorVersion,
- final int[] ctxProfile, final GLRendererQuirks[] rendererQuirks) {
- final String profileString = EGLContext.getGLProfile(majorVersion[0], minorVersion[0], ctxProfile[0]);
+ final boolean[] mapsADeviceToDefaultDevice,
+ final EGLGraphicsDevice[] resEGLDevice) {
+ final int majorVersion = 2;
+ final int minorVersion = 0;
+ final int ctxProfile = EGLContext.CTX_PROFILE_ES;
+ final String profileString = EGLContext.getGLProfile(majorVersion, minorVersion, ctxProfile);
if ( !GLProfile.isAvailable(adevice, profileString) ) {
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: "+profileString+" n/a on "+adevice);
+ System.err.println("EGLDrawableFactory.MapGLVersions: "+profileString+" n/a on "+adevice);
}
return false;
}
final GLProfile glp = GLProfile.get(adevice, profileString) ;
final GLDrawableFactoryImpl desktopFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getDesktopFactory();
- final boolean initDefaultDevice = 0 == defaultDevice.getHandle(); // Note: GLProfile always triggers EGL device initialization first!
- final boolean mapsADeviceToDefaultDevice = !QUERY_EGL_ES_NATIVE_TK || initDefaultDevice ||
- null == desktopFactory;
- // FIXME || adevice instanceof EGLGraphicsDevice ;
+
+ final GLCapabilities reqCapsAny = new GLCapabilities(glp);
+ reqCapsAny.setRedBits(5); reqCapsAny.setGreenBits(5); reqCapsAny.setBlueBits(5); reqCapsAny.setAlphaBits(0);
+ reqCapsAny.setDoubleBuffered(false);
+ final GLCapabilitiesImmutable reqCapsPBuffer = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(reqCapsAny);
+ final List<GLCapabilitiesImmutable> defaultDevicePBufferCapsL = getAvailableEGLConfigs(defaultDevice, reqCapsPBuffer);
+ final boolean defaultDeviceHasPBuffer = defaultDevicePBufferCapsL.size() > 0;
+
+ final boolean useDefaultDevice = adevice == defaultDevice;
+
+ mapsADeviceToDefaultDevice[0] = !useDefaultDevice &&
+ null != defaultSharedResource && defaultSharedResource.isAvailable &&
+ defaultConnection.equals(adevice.getConnection());
+
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: "+profileString+" ( "+majorVersion[0]+" ), "+
- "mapsADeviceToDefaultDevice "+mapsADeviceToDefaultDevice+
- " (QUERY_EGL_ES_NATIVE_TK "+QUERY_EGL_ES_NATIVE_TK+", initDefaultDevice "+initDefaultDevice+", hasDesktopFactory "+(null != desktopFactory)+
+ System.err.println("EGLDrawableFactory.MapGLVersions: "+profileString+" ( "+majorVersion+" ), "+
+ "mapsADeviceToDefaultDevice "+mapsADeviceToDefaultDevice[0]+
+ " (useDefaultDevice "+useDefaultDevice+", defaultDeviceHasPBuffer "+defaultDeviceHasPBuffer+", hasDesktopFactory "+(null != desktopFactory)+
", isEGLGraphicsDevice "+(adevice instanceof EGLGraphicsDevice)+")");
}
- boolean hasPBuffer;
- EGLGraphicsDevice eglDevice = null;
- EGLFeatures eglFeatures = null;
- NativeSurface surface = null;
- ProxySurface upstreamSurface = null; // X11, GLX, ..
- ProxySurface downstreamSurface = null; // EGL
+ if( mapsADeviceToDefaultDevice[0] ) {
+ return true;
+ }
+
+ final boolean defaultNoSurfacelessCtx = GLRendererQuirks.existStickyDeviceQuirk(defaultDevice, GLRendererQuirks.NoSurfacelessCtx);
boolean success = false;
- try {
- final GLCapabilities reqCapsAny = new GLCapabilities(glp);
- reqCapsAny.setRedBits(5); reqCapsAny.setGreenBits(5); reqCapsAny.setBlueBits(5); reqCapsAny.setAlphaBits(0);
- reqCapsAny.setDoubleBuffered(false);
-
- if( mapsADeviceToDefaultDevice ) {
- // In this branch, any non EGL device is mapped to EGL default shared resources (default behavior).
- // Only one default shared resource instance is ever be created.
- if( initDefaultDevice ) {
- defaultDevice.open();
- defaultDeviceEGLFeatures = new EGLFeatures(defaultDevice);
-
- // Probe for GLRendererQuirks.SingletonEGLDisplayOnly
- final long secondEGLDisplay = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY);
- if ( EGL.EGL_NO_DISPLAY == secondEGLDisplay ) {
- final int quirk = GLRendererQuirks.SingletonEGLDisplayOnly;
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- EGLDisplayUtil.setSingletonEGLDisplayOnly(true);
+ final boolean hasKHRSurfacelessTried;
+ if( defaultDeviceEGLFeatures.hasKHRSurfaceless && !defaultNoSurfacelessCtx ) {
+ hasKHRSurfacelessTried = true;
+ final AbstractGraphicsDevice zdevice = useDefaultDevice ? defaultDevice : adevice; // reuse
+ final EGLSurface zeroSurface = createSurfacelessImpl(zdevice, false, reqCapsAny, reqCapsAny, null, 64, 64);
+ resEGLDevice[0] = (EGLGraphicsDevice) zeroSurface.getGraphicsConfiguration().getScreen().getDevice();
+ if ( DEBUG_SHAREDCTX ) {
+ System.err.println("EGLDrawableFactory-MapGLVersions.0: "+resEGLDevice[0]);
+ }
+ EGLDrawable zeroDrawable = null;
+ EGLContext context = null;
+ boolean hasException = false;
+ try {
+ zeroDrawable = (EGLDrawable) createOnscreenDrawableImpl ( zeroSurface );
+ zeroDrawable.setRealized(true);
+
+ context = (EGLContext) zeroDrawable.createContext(null);
+ if (null == context) {
+ throw new GLException("Couldn't create shared context for drawable: "+zeroDrawable);
+ }
+ // Triggers initial mapping, if not done yet
+ if( GLContext.CONTEXT_NOT_CURRENT != context.makeCurrent() ) { // could cause exception
+ // context.isCurrent() !
+ final GL gl = context.getGL();
+ final String glVersionString = gl.glGetString(GL.GL_VERSION);
+ if(null != glVersionString) {
+ success = true;
+ } else {
+ setNoSurfacelessCtxQuirk(context);
+ }
+ } else if ( DEBUG_SHAREDCTX ) {
+ System.err.println("EGLDrawableFactory-MapGLVersions.0: NOT_CURRENT: "+resEGLDevice[0]+", "+context);
+ }
+ } catch (final Throwable t) {
+ hasException = true;
+ if ( DEBUG_SHAREDCTX ) {
+ System.err.println("EGLDrawableFactory-MapGLVersions.0: INFO: context create/makeCurrent failed");
+ t.printStackTrace();
+ }
+ } finally {
+ if( null != context ) {
+ try {
+ context.destroy();
+ } catch (final GLException gle) {
if ( DEBUG_SHAREDCTX ) {
- System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Second eglGetDisplay(EGL_DEFAULT_DISPLAY) failed");
+ System.err.println("EGLDrawableFactory-MapGLVersions.0: INFO: destroy caught exception:");
+ gle.printStackTrace();
}
}
}
- eglDevice = defaultDevice; // reuse
+ if( null != zeroDrawable ) {
+ zeroDrawable.setRealized(false);
+ }
+ if( null != zeroSurface ) {
+ zeroSurface.destroyNotify();
+ }
+ if( success || hasException ) { // cont. using device if !success
+ if( defaultDevice != resEGLDevice[0] ) { // don't close default device
+ if(null != resEGLDevice[0]) {
+ resEGLDevice[0].close();
+ }
+ }
+ }
+ }
+ if( success ) {
+ return true;
+ }
+ } else { // hasKHRSurfaceless
+ hasKHRSurfacelessTried = false;
+ }
+ EGLFeatures eglFeatures = null;
+ NativeSurface surface = null;
+ EGLDrawable drawable = null;
+ GLDrawable zeroDrawable = null;
+ EGLContext context = null;
+ ProxySurface upstreamSurface = null; // X11, GLX, ..
+ ProxySurface downstreamSurface = null; // EGL
+ try {
+ if( useDefaultDevice && defaultDeviceHasPBuffer ) {
+ // Map any non EGL device to EGL default shared resources (default behavior), using a pbuffer surface
+ resEGLDevice[0] = defaultDevice; // reuse
eglFeatures = defaultDeviceEGLFeatures;
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig.0: "+eglFeatures);
+ System.err.println("EGLDrawableFactory-MapGLVersions.1: "+resEGLDevice[0]);
+ System.err.println("EGLDrawableFactory-MapGLVersions.1: "+eglFeatures);
}
- if( !glp.isGLES() && !eglFeatures.hasGLAPI ) {
- if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig() OpenGL API not supported (1)");
- }
- } else {
- final GLCapabilitiesImmutable reqCapsPBuffer = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(reqCapsAny);
- final List<GLCapabilitiesImmutable> availablePBufferCapsL = getAvailableEGLConfigs(eglDevice, reqCapsPBuffer);
- hasPBuffer = availablePBufferCapsL.size() > 0;
-
- // attempt to created the default shared resources ..
- if( hasPBuffer ) {
- // 2nd case create defaultDevice shared resource using pbuffer surface
- downstreamSurface = createDummySurfaceImpl(eglDevice, false, reqCapsPBuffer, reqCapsPBuffer, null, 64, 64); // egl pbuffer offscreen
- if( null != downstreamSurface ) {
- downstreamSurface.createNotify();
- surface = downstreamSurface;
- }
- } else {
- // 3rd case fake creation of defaultDevice shared resource, no pbuffer available
- final List<GLCapabilitiesImmutable> capsAnyL = getAvailableEGLConfigs(eglDevice, reqCapsAny);
- if(capsAnyL.size() > 0) {
- final GLCapabilitiesImmutable chosenCaps = capsAnyL.get(0);
- EGLContext.mapStaticGLESVersion(eglDevice, chosenCaps);
- success = true;
- }
- if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig() no pbuffer config available, detected !pbuffer config: "+success);
- EGLGraphicsConfigurationFactory.printCaps("!PBufferCaps", capsAnyL, System.err);
- }
- }
+ downstreamSurface = createDummySurfaceImpl(resEGLDevice[0], false, reqCapsPBuffer, reqCapsPBuffer, null, 64, 64);
+ if( null != downstreamSurface ) {
+ downstreamSurface.createNotify();
+ surface = downstreamSurface;
}
- } else {
- // 4th case always creates a true mapping of given device to EGL
+ } else if( adevice != defaultDevice ) {
+ // Create a true mapping of given device to EGL
upstreamSurface = desktopFactory.createDummySurface(adevice, reqCapsAny, null, 64, 64); // X11, WGL, .. dummy window
if(null != upstreamSurface) {
upstreamSurface.createNotify();
- eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(upstreamSurface);
- eglDevice.open();
- eglFeatures = new EGLFeatures(eglDevice);
+ resEGLDevice[0] = EGLDisplayUtil.eglCreateEGLGraphicsDevice(upstreamSurface);
+ resEGLDevice[0].open();
+ eglFeatures = new EGLFeatures(resEGLDevice[0]);
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig.1: "+eglFeatures);
- }
- if( !glp.isGLES() && !eglFeatures.hasGLAPI ) {
- if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig() OpenGL API not supported (2)");
- }
- // disposed at finalized: eglDevice, upstreamSurface
- } else {
- hasPBuffer = true;
- surface = upstreamSurface;
+ System.err.println("EGLDrawableFactory-MapGLVersions.2: "+resEGLDevice[0]);
+ System.err.println("EGLDrawableFactory-MapGLVersions.2: "+eglFeatures);
}
+ surface = upstreamSurface;
}
}
if(null != surface) {
- EGLDrawable drawable = null;
- GLDrawable zeroDrawable = null;
- EGLContext context = null;
- try {
- drawable = (EGLDrawable) createOnscreenDrawableImpl ( surface );
- drawable.setRealized(true);
-
- context = (EGLContext) drawable.createContext(null);
- if (null == context) {
- throw new GLException("Couldn't create shared context for drawable: "+drawable);
- }
+ drawable = (EGLDrawable) createOnscreenDrawableImpl ( surface );
+ drawable.setRealized(true);
- if( GLContext.CONTEXT_NOT_CURRENT != context.makeCurrent() ) { // could cause exception
- // context.isCurrent() !
- final String glVersionString = context.getGL().glGetString(GL.GL_VERSION);
- if(null != glVersionString) {
- context.mapCurrentAvailableGLESVersion(eglDevice);
- if(eglDevice != adevice) {
- context.mapCurrentAvailableGLESVersion(adevice);
- }
+ context = (EGLContext) drawable.createContext(null);
+ if (null == context) {
+ throw new GLException("Couldn't create shared context for drawable: "+drawable);
+ }
- if( eglFeatures.hasKHRSurfaceless &&
- ( context.isGLES() || context.getGLVersionNumber().compareTo(GLContext.Version3_0) >= 0 )
- )
- {
- if( probeSurfacelessCtx(context, false /* restoreDrawable */) ) {
- zeroDrawable = context.getGLDrawable();
- }
- } else {
- setNoSurfacelessCtxQuirk(context);
+ // Triggers initial mapping, if not done yet
+ if( GLContext.CONTEXT_NOT_CURRENT != context.makeCurrent() ) { // could cause exception
+ // context.isCurrent() !
+ final GL gl = context.getGL();
+ final String glVersionString = gl.glGetString(GL.GL_VERSION);
+ if(null != glVersionString) {
+ success = true;
+ if( !hasKHRSurfacelessTried && eglFeatures.hasKHRSurfaceless &&
+ ( context.isGLES() || context.getGLVersionNumber().compareTo(GLContext.Version3_0) >= 0 )
+ )
+ {
+ if( probeSurfacelessCtx(context, false /* restoreDrawable */) ) {
+ zeroDrawable = context.getGLDrawable();
}
- rendererQuirks[0] = context.getRendererQuirks();
- ctxProfile[0] = context.getContextOptions();
- majorVersion[0] = context.getGLVersionNumber().getMajor();
- minorVersion[0] = context.getGLVersionNumber().getMinor();
- success = true;
} else {
- // Oops .. something is wrong
- if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: "+eglDevice+", "+context.getGLVersion()+" - VERSION is null, dropping availability!");
- }
+ setNoSurfacelessCtxQuirk(context);
}
+ } else if ( DEBUG_SHAREDCTX ) {
+ System.err.println("EGLDrawableFactory-MapGLVersions.12: NULL VERSION: "+resEGLDevice[0]+", "+context.getGLVersion());
}
- } catch (final Throwable t) {
- if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: INFO: context create/makeCurrent failed");
- t.printStackTrace();
- }
- } finally {
- if( null != context ) {
- try {
- context.destroy();
- } catch (final GLException gle) {
- if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: INFO: destroy caught exception:");
- gle.printStackTrace();
- }
- }
- }
- if( null != zeroDrawable ) {
- zeroDrawable.setRealized(false);
- }
- if( null != drawable ) {
- drawable.setRealized(false);
- }
+ } else if ( DEBUG_SHAREDCTX ) {
+ System.err.println("EGLDrawableFactory-MapGLVersions.12: NOT_CURRENT: "+resEGLDevice[0]+", "+context);
}
}
} catch (final Throwable t) {
if ( DEBUG_SHAREDCTX ) {
- System.err.println("Caught exception on thread "+getThreadName());
+ System.err.println("EGLDrawableFactory-MapGLVersions.12: INFO: context create/makeCurrent failed");
t.printStackTrace();
}
success = false;
} finally {
- if(null != downstreamSurface) {
+ if( null != context ) {
+ try {
+ context.destroy();
+ } catch (final GLException gle) {
+ if ( DEBUG_SHAREDCTX ) {
+ System.err.println("EGLDrawableFactory-MapGLVersions.12: INFO: destroy caught exception:");
+ gle.printStackTrace();
+ }
+ }
+ }
+ if( null != zeroDrawable ) {
+ zeroDrawable.setRealized(false);
+ }
+ if( null != drawable ) {
+ drawable.setRealized(false);
+ }
+ if( null != downstreamSurface ) {
downstreamSurface.destroyNotify();
}
- if( defaultDevice != eglDevice ) { // don't close default device
- if(null != eglDevice) {
- eglDevice.close();
+ if( defaultDevice != resEGLDevice[0] ) { // don't close default device
+ if(null != resEGLDevice[0]) {
+ resEGLDevice[0].close();
}
}
if(null != upstreamSurface) {
@@ -831,8 +898,44 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
public final boolean hasDefaultDeviceKHRCreateContext() {
return defaultDeviceEGLFeatures.hasKHRCreateContext;
}
- public final boolean hasOpenGLAPISupport() {
- return defaultDeviceEGLFeatures.hasGLAPI;
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory may support native desktop OpenGL if {@link EGL#EGL_CLIENT_APIS} contains {@code OpenGL}
+ * <i>and</i> if {@code EGL_KHR_create_context} extension is supported.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLDesktopSupport() {
+ /**
+ * It has been experienced w/ Mesa 10.3.2 (EGL 1.4/Gallium)
+ * that even though initial OpenGL context can be created w/o 'EGL_KHR_create_context',
+ * switching the API via 'eglBindAPI(EGL_OpenGL_API)' the latter 'eglCreateContext(..)' fails w/ EGL_BAD_ACCESS.
+ * Hence we require both: OpenGL API support _and_ 'EGL_KHR_create_context'.
+ */
+ return null != eglGLnDynamicLookupHelper &&
+ defaultDeviceEGLFeatures.hasGLAPI && defaultDeviceEGLFeatures.hasKHRCreateContext;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory always supports native GLES profiles.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLESSupport() { return true; }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Return true if {@code EGL_KHR_create_context} extension is supported,
+ * see {@link #hasDefaultDeviceKHRCreateContext()}.
+ * </p>
+ */
+ @Override
+ public final boolean hasMajorMinorCreateContextARB() {
+ return hasDefaultDeviceKHRCreateContext();
}
@Override
@@ -843,7 +946,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
public final boolean getIsDeviceCompatible(final AbstractGraphicsDevice device) {
// via mappings (X11/WGL/.. -> EGL) we shall be able to handle all types.
- return null != sharedMap ; // null!=eglES2DynamicLookupHelper || null!=eglES1DynamicLookupHelper;
+ return null != sharedResourceImplementation ; // null!=eglES2DynamicLookupHelper || null!=eglES1DynamicLookupHelper || ..;
}
private static List<GLCapabilitiesImmutable> getAvailableEGLConfigs(final EGLGraphicsDevice eglDisplay, final GLCapabilitiesImmutable caps) {
@@ -885,24 +988,28 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- public GLDynamicLookupHelper getGLDynamicLookupHelper(final String esProfile) {
+ public final GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions) {
final GLDynamicLookupHelper res;
- if ( GLProfile.GLES2 == esProfile || GLProfile.GLES3 == esProfile ) {
+ if ( EGLContext.isGLES2ES3(majorVersion, contextOptions) ) {
res = eglES2DynamicLookupHelper;
- } else if ( GLProfile.GLES1 == esProfile ) {
+ } else if ( EGLContext.isGLES1(majorVersion, contextOptions) ) {
res = eglES1DynamicLookupHelper;
- } else {
+ } else if( EGLContext.isGLDesktop(contextOptions) ) {
res = eglGLnDynamicLookupHelper;
+ } else {
+ throw new IllegalArgumentException("neither GLES1, GLES2, GLES3 nor desktop GL has been specified: "+majorVersion+" ("+EGLContext.getGLProfile(new StringBuilder(), contextOptions).toString());
}
- if( null == res ) {
- throw new GLException("No lookup for esProfile "+esProfile);
+ if( DEBUG_SHAREDCTX ) {
+ if( null == res ) {
+ System.err.println("EGLDrawableFactory.getGLDynamicLookupHelper: NULL for profile "+majorVersion+" ("+EGLContext.getGLProfile(new StringBuilder(), contextOptions).toString());
+ }
}
return res;
}
@Override
protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(final AbstractGraphicsDevice device) {
- if(null == sharedMap) { // null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper
+ if(null == sharedResourceImplementation) { // null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper || ..
return new ArrayList<GLCapabilitiesImmutable>(); // null
}
return EGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device);
@@ -942,9 +1049,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
final GLCapabilitiesChooser chooser) {
final EGLGraphicsDevice device;
if( createNewDevice || ! (deviceReq instanceof EGLGraphicsDevice) ) {
- final long nativeDisplayID = ( deviceReq instanceof EGLGraphicsDevice) ?
- ( (EGLGraphicsDevice) deviceReq ).getNativeDisplayID() : deviceReq.getHandle() ;
- device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(nativeDisplayID, deviceReq.getConnection(), deviceReq.getUnitID());
+ device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(deviceReq);
device.open();
ownDevice[0] = true;
} else {
@@ -960,7 +1065,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- protected final ProxySurface createMutableSurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
+ protected final EGLSurface createMutableSurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
final GLCapabilitiesImmutable capsChosen, final GLCapabilitiesImmutable capsRequested,
final GLCapabilitiesChooser chooser, final UpstreamSurfaceHook upstreamHook) {
final boolean[] ownDevice = { false };
@@ -969,14 +1074,14 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- public final ProxySurface createDummySurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
+ public final EGLSurface createDummySurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
GLCapabilitiesImmutable chosenCaps, final GLCapabilitiesImmutable requestedCaps, final GLCapabilitiesChooser chooser, final int width, final int height) {
chosenCaps = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(chosenCaps); // complete validation in EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(..) above
return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new EGLDummyUpstreamSurfaceHook(width, height));
}
@Override
- public final ProxySurface createSurfacelessImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
+ public final EGLSurface createSurfacelessImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
GLCapabilitiesImmutable chosenCaps, final GLCapabilitiesImmutable requestedCaps, final GLCapabilitiesChooser chooser, final int width, final int height) {
chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps);
final boolean[] ownDevice = { false };
@@ -1019,11 +1124,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- protected ProxySurface createProxySurfaceImpl(final AbstractGraphicsDevice deviceReq, final int screenIdx, final long windowHandle,
+ protected EGLSurface createProxySurfaceImpl(final AbstractGraphicsDevice deviceReq, final int screenIdx, final long windowHandle,
final GLCapabilitiesImmutable capsRequested, final GLCapabilitiesChooser chooser,
final UpstreamSurfaceHook upstream) {
- final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq;
- final EGLGraphicsDevice device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID());
+ final EGLGraphicsDevice device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(deviceReq);
device.open();
final DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx);
final EGLGraphicsConfiguration cfg = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
index 6c11b3bdc..890dab8f7 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
@@ -1,5 +1,6 @@
package jogamp.opengl.egl;
+import com.jogamp.common.ExceptionUtils;
import com.jogamp.nativewindow.NativeSurface;
import com.jogamp.nativewindow.ProxySurface;
import com.jogamp.nativewindow.UpstreamSurfaceHook;
@@ -8,6 +9,8 @@ import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
import com.jogamp.opengl.egl.EGL;
+import jogamp.nativewindow.ProxySurfaceImpl;
+
/** Uses a PBuffer offscreen surface */
public class EGLDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
/**
@@ -50,6 +53,11 @@ public class EGLDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize
}
eglDevice.lock();
try {
+ if( EGLDrawable.DEBUG ) {
+ System.err.println(EGLSurface.getThreadName()+": EGLDummyUpstreamSurfaceHook: EGL.eglDestroySurface: 0x"+Long.toHexString(s.getSurfaceHandle()));
+ ProxySurfaceImpl.dumpHierarchy(System.err, s);
+ ExceptionUtils.dumpStack(System.err);
+ }
EGL.eglDestroySurface(eglDevice.getHandle(), s.getSurfaceHandle());
s.setSurfaceHandle(EGL.EGL_NO_SURFACE);
s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
index d37efc455..038194d58 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
@@ -31,6 +31,8 @@ package jogamp.opengl.egl;
import java.util.ArrayList;
import java.util.List;
+import jogamp.nativewindow.BcmVCArtifacts;
+
/**
* <p>
* Covering ES3 and ES2.
@@ -41,12 +43,20 @@ public final class EGLES2DynamicLibraryBundleInfo extends EGLDynamicLibraryBundl
super();
}
+
@Override
public final List<List<String>> getToolLibNames() {
+
final List<List<String>> libsList = new ArrayList<List<String>>();
{
final List<String> libsGL = new ArrayList<String>();
+ /**
+ * Prefer libGLESv2.so over libGLESv2.so.2 for proprietary
+ * Broadcom graphics when the VC4 DRM Xorg driver isn't present
+ */
+ final boolean bcm_vc_iv_quirk = BcmVCArtifacts.guessVCIVUsed();
+
// ES3: This is the default lib name, according to the spec
libsGL.add("libGLESv3.so.3");
@@ -63,12 +73,18 @@ public final class EGLES2DynamicLibraryBundleInfo extends EGLDynamicLibraryBundl
libsGL.add("libGLES30");
// ES2: This is the default lib name, according to the spec
- libsGL.add("libGLESv2.so.2");
+ if (!bcm_vc_iv_quirk) {
+ libsGL.add("libGLESv2.so.2");
+ }
// ES2: Try these as well, if spec fails
libsGL.add("libGLESv2.so");
libsGL.add("GLESv2");
+ if (bcm_vc_iv_quirk) {
+ libsGL.add("libGLESv2.so.2");
+ }
+
// ES2: Alternative names
libsGL.add("GLES20");
libsGL.add("GLESv2_CM");
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
index d10263f22..5505fed52 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
@@ -242,7 +242,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
}
ownEGLDisplay = false;
} else {
- eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(absDevice.getHandle(), absDevice.getConnection(), absDevice.getUnitID());
+ eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(absDevice);
eglDevice.open();
ownEGLDisplay = true;
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLSurface.java b/src/jogl/classes/jogamp/opengl/egl/EGLSurface.java
index e4e692fb2..8956bcbd9 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLSurface.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLSurface.java
@@ -35,7 +35,7 @@ import com.jogamp.nativewindow.ProxySurface;
import com.jogamp.nativewindow.UpstreamSurfaceHook;
import com.jogamp.opengl.GLCapabilitiesImmutable;
import com.jogamp.opengl.GLException;
-
+import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.nio.Buffers;
import com.jogamp.nativewindow.GenericUpstreamSurfacelessHook;
import com.jogamp.opengl.egl.EGL;
@@ -101,16 +101,22 @@ public class EGLSurface extends WrappedSurface {
final boolean isPBuffer = ((GLCapabilitiesImmutable) config.getChosenCapabilities()).isPBuffer();
long eglSurface = createEGLSurfaceHandle(isPBuffer, true /* useSurfaceHandle */, config, nativeSurface);
+ if( DEBUG ) {
+ System.err.println(getThreadName() + ": EGLSurface: EGL.eglCreateSurface.0: 0x"+Long.toHexString(eglSurface));
+ ProxySurfaceImpl.dumpHierarchy(System.err, this);
+ }
+
if ( EGL.EGL_NO_SURFACE == eglSurface ) {
final int eglError0 = EGL.eglGetError();
if( EGL.EGL_BAD_NATIVE_WINDOW == eglError0 && !isPBuffer ) {
// Try window handle if available and differs (Windows HDC / HWND).
// ANGLE impl. required HWND on Windows.
if( hasUniqueNativeWindowHandle(nativeSurface) ) {
- if(DEBUG) {
+ eglSurface = createEGLSurfaceHandle(isPBuffer, false /* useSurfaceHandle */, config, nativeSurface);
+ if( DEBUG ) {
System.err.println(getThreadName() + ": Info: Creation of window surface w/ surface handle failed: "+config+", error "+GLDrawableImpl.toHexString(eglError0)+", retry w/ windowHandle");
+ System.err.println(getThreadName() + ": EGLSurface: EGL.eglCreateSurface.1: 0x"+Long.toHexString(eglSurface));
}
- eglSurface = createEGLSurfaceHandle(isPBuffer, false /* useSurfaceHandle */, config, nativeSurface);
if (EGL.EGL_NO_SURFACE == eglSurface) {
throw new GLException("Creation of window surface w/ window handle failed: "+config+", "+this+", error "+GLDrawableImpl.toHexString(EGL.eglGetError()));
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index d4fc0b005..995ff870e 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -63,6 +63,7 @@ import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
import jogamp.opengl.GLFBODrawableImpl;
import jogamp.opengl.GLGraphicsConfigurationUtil;
import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType;
@@ -85,6 +86,8 @@ public class MacOSXCGLContext extends GLContextImpl
// NSOpenGL-based or CGL-based)
protected interface GLBackendImpl {
boolean isNSContext();
+ /** Indicating CALayer, i.e. onscreen rendering using offscreen layer. */
+ boolean isUsingCALayer();
long create(long share, int ctp, int major, int minor);
boolean destroy(long ctx);
void associateDrawable(boolean bound);
@@ -108,6 +111,9 @@ public class MacOSXCGLContext extends GLContextImpl
}
static boolean isGLProfileSupported(final int ctp, final int major, final int minor) {
+ if( 0 != ( CTX_PROFILE_ES & ctp ) ) {
+ return false;
+ }
final boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
final boolean ctCore = 0 != ( CTX_PROFILE_CORE & ctp ) ;
@@ -423,12 +429,33 @@ public class MacOSXCGLContext extends GLContextImpl
}
@Override
- protected boolean setSwapIntervalImpl(final int interval) {
- return impl.setSwapInterval(interval);
+ protected final Integer setSwapIntervalImpl2(final int interval) {
+ if( !impl.isUsingCALayer() && !drawable.getChosenGLCapabilities().isOnscreen() ) {
+ return null;
+ }
+ final int useInterval;
+ if( 0 > interval ) {
+ useInterval = Math.abs(interval);
+ } else {
+ useInterval = interval;
+ }
+ if( impl.setSwapInterval(useInterval) ) {
+ return Integer.valueOf(useInterval);
+ }
+ return null;
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Ignoring {@code contextFQN}, using {@code MacOSX}-{@link AbstractGraphicsDevice#getUniqueID()}.
+ * </p>
+ */
@Override
- protected final void updateGLXProcAddressTable() {
+ protected final void updateGLXProcAddressTable(final String contextFQN, final GLDynamicLookupHelper dlh) {
+ if( null == dlh ) {
+ throw new GLException("No GLDynamicLookupHelper for "+this);
+ }
final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
final String key = "MacOSX-"+adevice.getUniqueID();
@@ -446,7 +473,7 @@ public class MacOSXCGLContext extends GLContextImpl
}
} else {
cglExtProcAddressTable = new CGLExtProcAddressTable(new GLProcAddressResolver());
- resetProcAddressTable(getCGLExtProcAddressTable());
+ resetProcAddressTable(getCGLExtProcAddressTable(), dlh);
synchronized(mappedContextTypeObjectLock) {
mappedGLXProcAddress.put(key, getCGLExtProcAddressTable());
if(DEBUG) {
@@ -521,6 +548,8 @@ public class MacOSXCGLContext extends GLContextImpl
@Override
public boolean isNSContext() { return true; }
+ @Override
+ public boolean isUsingCALayer() { return null != backingLayerHost; }
/** Only returns a valid NSView. If !NSView, return null and mark either isPBuffer, isFBO or isSurfaceless. */
private long getNSViewHandle(final boolean[] isPBuffer, final boolean[] isFBO, final boolean[] isSurfaceless) {
@@ -547,7 +576,7 @@ public class MacOSXCGLContext extends GLContextImpl
nsViewHandle = OSXUtil.GetNSView(drawableHandle);
} else if( isPBuffer[0] ) {
nsViewHandle = 0;
- } else if( isSurfacelessOK() ) {
+ } else if( isSurfaceless() ) {
isSurfaceless[0] = true;
nsViewHandle = 0;
} else {
@@ -1128,6 +1157,9 @@ public class MacOSXCGLContext extends GLContextImpl
public boolean isNSContext() { return false; }
@Override
+ public boolean isUsingCALayer() { return false; }
+
+ @Override
public long create(final long share, final int ctp, final int major, final int minor) {
long ctx = 0;
final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
index ab1d56e29..871067f4c 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -148,7 +148,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- public GLDynamicLookupHelper getGLDynamicLookupHelper(final String profileName) {
+ public final GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions) {
return macOSXCGLDynamicLookupHelper;
}
@@ -335,6 +335,33 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
return null;
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory always supports native desktop OpenGL profiles.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLDesktopSupport() { return true; }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory never supports native GLES profiles.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLESSupport() { return false; }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Always returns true.
+ * </p>
+ */
+ @Override
+ public final boolean hasMajorMinorCreateContextARB() { return true; }
+
@Override
protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(final AbstractGraphicsDevice device) {
return MacOSXCGLGraphicsConfiguration.getAvailableCapabilities(this, device);
diff --git a/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java b/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java
index 562d4883d..bdd9b6c95 100644
--- a/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java
+++ b/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java
@@ -195,11 +195,21 @@ public class ALAudioSink implements AudioSink {
clearPreALError("init."+checkErrIter++);
preferredAudioFormat = new AudioFormat(querySampleRate(), DefaultFormat.sampleSize, DefaultFormat.channelCount, DefaultFormat.signed, DefaultFormat.fixedP, DefaultFormat.planar, DefaultFormat.littleEndian);
if( DEBUG ) {
- System.out.println("ALAudioSink: OpenAL Extensions:"+al.alGetString(ALConstants.AL_EXTENSIONS));
+ final int[] alcvers = { 0, 0 };
+ System.out.println("ALAudioSink: OpenAL Version: "+al.alGetString(ALConstants.AL_VERSION));
+ System.out.println("ALAudioSink: OpenAL Extensions: "+al.alGetString(ALConstants.AL_EXTENSIONS));
clearPreALError("init."+checkErrIter++);
- System.out.println("ALAudioSink: Null device OpenAL Extensions:"+alc.alcGetString(null, ALCConstants.ALC_EXTENSIONS));
+ System.out.println("ALAudioSink: Null device OpenALC:");
+ alc.alcGetIntegerv(null, ALCConstants.ALC_MAJOR_VERSION, 1, alcvers, 0);
+ alc.alcGetIntegerv(null, ALCConstants.ALC_MINOR_VERSION, 1, alcvers, 1);
+ System.out.println(" Version: "+alcvers[0]+"."+alcvers[1]);
+ System.out.println(" Extensions: "+alc.alcGetString(null, ALCConstants.ALC_EXTENSIONS));
clearPreALError("init."+checkErrIter++);
- System.out.println("ALAudioSink: Device "+deviceSpecifier+" OpenAL Extensions:"+alc.alcGetString(device, ALCConstants.ALC_EXTENSIONS));
+ System.out.println("ALAudioSink: Device "+deviceSpecifier+" OpenALC:");
+ alc.alcGetIntegerv(device, ALCConstants.ALC_MAJOR_VERSION, 1, alcvers, 0);
+ alc.alcGetIntegerv(device, ALCConstants.ALC_MINOR_VERSION, 1, alcvers, 1);
+ System.out.println(" Version: "+alcvers[0]+"."+alcvers[1]);
+ System.out.println(" Extensions: "+alc.alcGetString(device, ALCConstants.ALC_EXTENSIONS));
System.out.println("ALAudioSink: hasSOFTBufferSamples "+hasSOFTBufferSamples);
System.out.println("ALAudioSink: hasALC_thread_local_context "+hasALC_thread_local_context);
System.out.println("ALAudioSink: preferredAudioFormat "+preferredAudioFormat);
@@ -310,12 +320,14 @@ public class ALAudioSink implements AudioSink {
final int alSrcName = null != alSource ? alSource[0] : 0;
final int alBuffersLen = null != alBufferNames ? alBufferNames.length : 0;
final int ctxHash = context != null ? context.hashCode() : 0;
+ final int alFramesAvailSize = alFramesAvail != null ? alFramesAvail.size() : 0;
+ final int alFramesPlayingSize = alFramesPlaying != null ? alFramesPlaying.size() : 0;
return "ALAudioSink[init "+initialized+", playRequested "+playRequested+", device "+deviceSpecifier+", ctx "+toHexString(ctxHash)+", alSource "+alSrcName+
", chosen "+chosenFormat+
", al[chan "+ALHelpers.alChannelLayoutName(alChannelLayout)+", type "+ALHelpers.alSampleTypeName(alSampleType)+
", fmt "+toHexString(alFormat)+", soft "+hasSOFTBufferSamples+
- "], playSpeed "+playSpeed+", buffers[total "+alBuffersLen+", avail "+alFramesAvail.size()+", "+
- "queued["+alFramesPlaying.size()+", apts "+getPTS()+", "+getQueuedTime() + " ms, " + alBufferBytesQueued+" bytes], "+
+ "], playSpeed "+playSpeed+", buffers[total "+alBuffersLen+", avail "+alFramesAvailSize+", "+
+ "queued["+alFramesPlayingSize+", apts "+getPTS()+", "+getQueuedTime() + " ms, " + alBufferBytesQueued+" bytes], "+
"queue[g "+frameGrowAmount+", l "+frameLimit+"]";
}
diff --git a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
index cfecbfd8d..f09d289fa 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
@@ -46,10 +46,14 @@ import com.jogamp.opengl.GLProfile;
import jogamp.opengl.Debug;
import com.jogamp.common.net.UriQueryProps;
+import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.net.Uri;
import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.common.util.LFRingbuffer;
import com.jogamp.common.util.Ringbuffer;
+import com.jogamp.common.util.SourcedInterruptedException;
import com.jogamp.opengl.GLExtensions;
import com.jogamp.opengl.util.TimeFrameI;
import com.jogamp.opengl.util.av.AudioSink;
@@ -365,7 +369,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
event_mask = addStateEventMask(event_mask, GLMediaPlayer.State.Paused);
setState( State.Paused );
if( null != streamWorker ) {
- streamWorker.doPause();
+ streamWorker.doPause(true);
}
if( flush ) {
resetAVPTSAndFlush();
@@ -414,7 +418,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
final State _state = state;
setState( State.Paused );
if( null != streamWorker ) {
- streamWorker.doPause();
+ streamWorker.doPause(true);
}
// Adjust target ..
if( msec >= duration ) {
@@ -571,7 +575,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
this.vid = vid;
this.aid = aid;
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
try {
// StreamWorker may be used, see API-doc of StreamWorker
@@ -968,8 +972,9 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
* shall be <code>null</code> for audio only.
* @return the last processed video PTS value, maybe {@link TimeFrameI#INVALID_PTS} if video frame is invalid or n/a.
* Will be {@link TimeFrameI#END_OF_STREAM_PTS} if end of stream reached.
+ * @throws InterruptedException if waiting for next frame fails
*/
- protected abstract int getNextTextureImpl(GL gl, TextureFrame nextFrame);
+ protected abstract int getNextTextureImpl(GL gl, TextureFrame nextFrame) throws InterruptedException;
protected final int getNextSingleThreaded(final GL gl, final TextureFrame nextFrame, final boolean[] gotVFrame) throws InterruptedException {
final int pts;
@@ -1064,7 +1069,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
* {@link GLMediaPlayerImpl#updateAttributes(int, int, int, int, int, int, int, float, int, int, int, String, String) updateAttributes(..)},
* the latter decides whether StreamWorker is being used.
*/
- class StreamWorker extends Thread {
+ class StreamWorker extends InterruptSource.Thread {
private volatile boolean isRunning = false;
private volatile boolean isActive = false;
private volatile boolean isBlocked = false;
@@ -1086,13 +1091,13 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
setDaemon(true);
synchronized(this) {
start();
- while( !isRunning ) {
+ try {
this.notifyAll(); // wake-up startup-block
- try {
+ while( !isRunning && !shallStop ) {
this.wait(); // wait until started
- } catch (final InterruptedException e) {
- e.printStackTrace();
}
+ } catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
}
}
@@ -1140,18 +1145,20 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
sharedGLCtx.release();
}
}
- public final synchronized void doPause() {
+ public final synchronized void doPause(final boolean waitUntilDone) {
if( isActive ) {
shallPause = true;
- if( Thread.currentThread() != this ) {
+ if( java.lang.Thread.currentThread() != this ) {
if( isBlocked && isActive ) {
this.interrupt();
}
- while( isActive && isRunning ) {
+ if( waitUntilDone ) {
try {
- this.wait(); // wait until paused
+ while( isActive && isRunning ) {
+ this.wait(); // wait until paused
+ }
} catch (final InterruptedException e) {
- e.printStackTrace();
+ throw new InterruptedRuntimeException(e);
}
}
}
@@ -1160,14 +1167,16 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
public final synchronized void doResume() {
if( isRunning && !isActive ) {
shallPause = false;
- if( Thread.currentThread() != this ) {
- while( !isActive && !shallPause && isRunning ) {
+ if( java.lang.Thread.currentThread() != this ) {
+ try {
this.notifyAll(); // wake-up pause-block
- try {
+ while( !isActive && !shallPause && isRunning ) {
this.wait(); // wait until resumed
- } catch (final InterruptedException e) {
- e.printStackTrace();
}
+ } catch (final InterruptedException e) {
+ final InterruptedException e2 = SourcedInterruptedException.wrap(e);
+ doPause(false);
+ throw new InterruptedRuntimeException(e2);
}
}
}
@@ -1175,17 +1184,17 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
public final synchronized void doStop() {
if( isRunning ) {
shallStop = true;
- if( Thread.currentThread() != this ) {
+ if( java.lang.Thread.currentThread() != this ) {
if( isBlocked && isRunning ) {
this.interrupt();
}
- while( isRunning ) {
+ try {
this.notifyAll(); // wake-up pause-block (opt)
- try {
+ while( isRunning ) {
this.wait(); // wait until stopped
- } catch (final InterruptedException e) {
- e.printStackTrace();
}
+ } catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
}
}
@@ -1203,48 +1212,48 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
this.notifyAll(); // wake-up ctor()
}
- while( !shallStop ){
- if( shallPause ) {
- synchronized ( this ) {
- if( sharedGLCtxCurrent ) {
- postNextTextureImpl(sharedGLCtx.getGL());
- sharedGLCtx.release();
- }
- while( shallPause && !shallStop ) {
- isActive = false;
- this.notifyAll(); // wake-up doPause()
- try {
- this.wait(); // wait until resumed
- } catch (final InterruptedException e) {
- if( !shallPause ) {
- e.printStackTrace();
+ while( !shallStop ) {
+ TextureFrame nextFrame = null;
+ try {
+ if( shallPause ) {
+ synchronized ( this ) {
+ if( sharedGLCtxCurrent ) {
+ postNextTextureImpl(sharedGLCtx.getGL());
+ sharedGLCtx.release();
+ }
+ while( shallPause && !shallStop ) {
+ isActive = false;
+ this.notifyAll(); // wake-up doPause()
+ try {
+ this.wait(); // wait until resumed
+ } catch (final InterruptedException e) {
+ if( !shallPause ) {
+ throw SourcedInterruptedException.wrap(e);
+ }
}
}
+ if( sharedGLCtxCurrent ) {
+ makeCurrent(sharedGLCtx);
+ preNextTextureImpl(sharedGLCtx.getGL());
+ }
+ isActive = true;
+ this.notifyAll(); // wake-up doResume()
}
- if( sharedGLCtxCurrent ) {
- makeCurrent(sharedGLCtx);
- preNextTextureImpl(sharedGLCtx.getGL());
- }
- isActive = true;
- this.notifyAll(); // wake-up doResume()
}
- }
- if( !sharedGLCtxCurrent && null != sharedGLCtx ) {
- synchronized ( this ) {
- if( null != sharedGLCtx ) {
- makeCurrent( sharedGLCtx );
- preNextTextureImpl(sharedGLCtx.getGL());
- sharedGLCtxCurrent = true;
- }
- if( null == videoFramesFree ) {
- throw new InternalError("XXX videoFramesFree is null");
+ if( !sharedGLCtxCurrent && null != sharedGLCtx ) {
+ synchronized ( this ) {
+ if( null != sharedGLCtx ) {
+ makeCurrent( sharedGLCtx );
+ preNextTextureImpl(sharedGLCtx.getGL());
+ sharedGLCtxCurrent = true;
+ }
+ if( null == videoFramesFree ) {
+ throw new InternalError("XXX videoFramesFree is null");
+ }
}
}
- }
- if( !shallStop ) {
- TextureFrame nextFrame = null;
- try {
+ if( !shallStop ) {
isBlocked = true;
final GL gl;
if( STREAM_ID_NONE != vid ) {
@@ -1260,7 +1269,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
if( TimeFrameI.INVALID_PTS != vPTS ) {
if( null != nextFrame ) {
if( STREAM_WORKER_DELAY > 0 ) {
- Thread.sleep(STREAM_WORKER_DELAY);
+ java.lang.Thread.sleep(STREAM_WORKER_DELAY);
}
if( !videoFramesDecoded.put(nextFrame) ) {
throw new InternalError("XXX: free "+videoFramesFree+", decoded "+videoFramesDecoded+", "+GLMediaPlayerImpl.this);
@@ -1294,31 +1303,30 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
}
pauseImpl(true, GLMediaEventListener.EVENT_CHANGE_EOS);
}
- } catch (final InterruptedException e) {
- isBlocked = false;
- if( !shallStop && !shallPause ) {
- streamErr = new StreamException("InterruptedException while decoding: "+GLMediaPlayerImpl.this.toString(), e);
- }
- } catch (final Throwable t) {
- streamErr = new StreamException(t.getClass().getSimpleName()+" while decoding: "+GLMediaPlayerImpl.this.toString(), t);
- } finally {
- if( null != nextFrame ) { // put back
- videoFramesFree.put(nextFrame);
+ }
+ } catch (final InterruptedException e) {
+ if( !isBlocked ) { // !shallStop && !shallPause
+ streamErr = new StreamException("InterruptedException while decoding: "+GLMediaPlayerImpl.this.toString(),
+ SourcedInterruptedException.wrap(e));
+ }
+ isBlocked = false;
+ } catch (final Throwable t) {
+ streamErr = new StreamException(t.getClass().getSimpleName()+" while decoding: "+GLMediaPlayerImpl.this.toString(), t);
+ } finally {
+ if( null != nextFrame ) { // put back
+ videoFramesFree.put(nextFrame);
+ }
+ if( null != streamErr ) {
+ if( DEBUG ) {
+ ExceptionUtils.dumpThrowable("handled", streamErr);
}
- if( null != streamErr ) {
- if( DEBUG ) {
- final Throwable t = null != streamErr.getCause() ? streamErr.getCause() : streamErr;
- System.err.println("Caught StreamException: "+t.getMessage());
- t.printStackTrace();
- }
- // state transition incl. notification
- synchronized ( this ) {
- shallPause = true;
- isActive = false;
- this.notifyAll(); // wake-up potential do*()
- }
- pauseImpl(true, GLMediaEventListener.EVENT_CHANGE_ERR);
+ // state transition incl. notification
+ synchronized ( this ) {
+ shallPause = true;
+ isActive = false;
+ this.notifyAll(); // wake-up potential do*()
}
+ pauseImpl(true, GLMediaEventListener.EVENT_CHANGE_ERR);
}
}
}
@@ -1379,6 +1387,16 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
}
}
+ /**
+ * Called initially by {@link #initStreamImpl(int, int)}, which
+ * is called off-thread by {@link #initStream(Uri, int, int, int)}.
+ * <p>
+ * The latter catches an occurring exception and set the state delivers the error events.
+ * </p>
+ * <p>
+ * Further calls are issues off-thread by the decoder implementation.
+ * </p>
+ */
protected final void updateAttributes(int vid, final int aid, final int width, final int height, final int bps_stream,
final int bps_video, final int bps_audio, final float fps,
final int videoFrames, final int audioFrames, final int duration, final String vcodec, final String acodec) {
@@ -1413,7 +1431,12 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
this.fps = fps;
if( 0 != fps ) {
this.frame_duration = 1000f / fps;
- this.maxNullFrameCountUntilEOS = MAX_FRAMELESS_MS_UNTIL_EOS / (int)this.frame_duration;
+ final int fdurI = (int)this.frame_duration;
+ if( 0 < fdurI ) {
+ this.maxNullFrameCountUntilEOS = MAX_FRAMELESS_MS_UNTIL_EOS / fdurI;
+ } else {
+ this.maxNullFrameCountUntilEOS = MAX_FRAMELESS_UNTIL_EOS_DEFAULT;
+ }
} else {
this.frame_duration = 0;
this.maxNullFrameCountUntilEOS = MAX_FRAMELESS_UNTIL_EOS_DEFAULT;
@@ -1524,7 +1547,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
final int decVideoFrames = null != videoFramesDecoded ? videoFramesDecoded.size() : 0;
final int video_scr = video_scr_pts + (int) ( ( Platform.currentTimeMillis() - video_scr_t0 ) * playSpeed );
final String camPath = null != cameraPath ? ", camera: "+cameraPath : "";
- return "GLMediaPlayer["+state+", vSCR "+video_scr+", frames[p "+presentedFrameCount+", d "+decodedFrameCount+", t "+videoFrames+" ("+tt+" s), z "+nullFrameCount+" / "+maxNullFrameCountUntilEOS+"], "+
+ return getClass().getSimpleName()+"["+state+", vSCR "+video_scr+", frames[p "+presentedFrameCount+", d "+decodedFrameCount+", t "+videoFrames+" ("+tt+" s), z "+nullFrameCount+" / "+maxNullFrameCountUntilEOS+"], "+
"speed "+playSpeed+", "+bps_stream+" bps, hasSW "+(null!=streamWorker)+
", Texture[count "+textureCount+", free "+freeVideoFrames+", dec "+decVideoFrames+", tagt "+toHexString(textureTarget)+", ifmt "+toHexString(textureInternalFormat)+", fmt "+toHexString(textureFormat)+", type "+toHexString(textureType)+"], "+
"Video[id "+vid+", <"+vcodec+">, "+width+"x"+height+", glOrient "+isInGLOrientation+", "+fps+" fps, "+frame_duration+" fdur, "+bps_video+" bps], "+
diff --git a/src/jogl/classes/jogamp/opengl/util/av/VideoPixelFormat.java b/src/jogl/classes/jogamp/opengl/util/av/VideoPixelFormat.java
index 44d83e78d..db8da6157 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/VideoPixelFormat.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/VideoPixelFormat.java
@@ -64,7 +64,7 @@ public enum VideoPixelFormat {
XVMC_MPEG2_MC,
/** */
XVMC_MPEG2_IDCT,
- /** packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 */
+ /** packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 ( sharing Cb and Cr w/ 2 pixels ) */
UYVY422,
/** packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 */
UYYVYY411,
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 f294d5bc0..6a4257ade 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java
@@ -37,7 +37,7 @@ import java.util.List;
import java.util.Set;
import com.jogamp.opengl.GLProfile;
-
+import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.os.DynamicLibraryBundle;
import com.jogamp.common.os.DynamicLibraryBundleInfo;
import com.jogamp.common.util.RunnableExecutor;
@@ -190,7 +190,8 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
libLoaded[i] = dl.isToolLibLoaded(i);
}
if( !libLoaded[LIB_IDX_UTI] || !libLoaded[LIB_IDX_FMT] || !libLoaded[LIB_IDX_COD] ) {
- throw new RuntimeException("FFMPEG Tool library incomplete: [ avutil "+libLoaded[LIB_IDX_UTI]+", avformat "+libLoaded[LIB_IDX_FMT]+", avcodec "+libLoaded[LIB_IDX_COD]+"]");
+ System.err.println("FFMPEG Tool library incomplete: [ avutil "+libLoaded[LIB_IDX_UTI]+", avformat "+libLoaded[LIB_IDX_FMT]+", avcodec "+libLoaded[LIB_IDX_COD]+"]");
+ return null;
}
dl.claimAllLinkPermission();
try {
@@ -216,7 +217,10 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
throw new InternalError("XXX0 "+symbolNames.length+" != "+symbolCount);
}
- AccessController.doPrivileged(privInitSymbolsAction);
+ final DynamicLibraryBundle dl = AccessController.doPrivileged(privInitSymbolsAction);
+ if( null == dl ) {
+ return false;
+ }
// optional symbol name set
final Set<String> optionalSymbolNameSet = new HashSet<String>();
@@ -254,7 +258,7 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
try {
_ready = initSymbols(_versions);
} catch (final Throwable t) {
- t.printStackTrace();
+ ExceptionUtils.dumpThrowable("", t);
}
libsUFCLoaded = libLoaded[LIB_IDX_UTI] && libLoaded[LIB_IDX_FMT] && libLoaded[LIB_IDX_COD];
avUtilVersion = _versions[0];
@@ -328,6 +332,16 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
}
@Override
+ public final boolean searchToolLibInSystemPath() {
+ return true;
+ }
+
+ @Override
+ public final boolean searchToolLibSystemPathFirst() {
+ return true;
+ }
+
+ @Override
public final List<List<String>> getToolLibNames() {
final List<List<String>> libsList = new ArrayList<List<String>>();
diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
index 7df5d6a9e..b5cccdb6d 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
@@ -106,11 +106,12 @@ import jogamp.opengl.util.av.VideoPixelFormat;
* <p>
* Currently we are binary compatible w/:
* <table border="1">
- * <tr><th>libav / ffmpeg</th><th>lavc</th><th>lavf</th><th>lavu</th><th>lavr/lswr</th> <th>FFMPEG* class</th></tr>
+ * <tr><th>libav / ffmpeg</th><th>lavc</th><th>lavf</th><th>lavu</th><th>lavr/lswr</th> <th>FFMPEG* class</th></tr>
* <tr><td>0.8</td> <td>53</td> <td>53</td> <td>51</td> <td></td> <td>FFMPEGv08</td></tr>
* <tr><td>9.0 / 1.2</td> <td>54</td> <td>54</td> <td>52</td> <td>01/00</td> <td>FFMPEGv09</td></tr>
* <tr><td>10 / 2.[0-3]</td> <td>55</td> <td>55</td> <td>53/52</td> <td>01/00</td> <td>FFMPEGv10</td></tr>
- * <tr><td>11 / 2.[4-x]</td> <td>56</td> <td>56</td> <td>54</td> <td>02/01</td> <td>FFMPEGv11</td></tr>
+ * <tr><td>11 / 2.[4-8]</td> <td>56</td> <td>56</td> <td>54</td> <td>02/01</td> <td>FFMPEGv11</td></tr>
+ * <tr><td>12 / 2.[9-x]</td> <td>57</td> <td>57</td> <td>55</td> <td>02/01</td> <td>TODO</td></tr>
* </table>
* </p>
* <p>
@@ -145,17 +146,28 @@ import jogamp.opengl.util.av.VideoPixelFormat;
* <li>GNU/Linux: ffmpeg or libav are deployed in most distributions.</li>
* <li>Windows:
* <ul>
+ * <li>https://ffmpeg.org/download.html#build-windows</li>
* <li>http://ffmpeg.zeranoe.com/builds/ (ffmpeg) <i>recommended, works w/ dshow</i></li>
* <li>http://win32.libav.org/releases/ (libav)</li>
* </ul></li>
- * <li>MacOSX using Homebrew
+ * <li>MacOSX
* <ul>
- * <li>https://github.com/Homebrew/homebrew/wiki/Installation</li>
- * <li>https://trac.ffmpeg.org/wiki/CompilationGuide/MacOSX</li>
+ * <li>Building using Homebrew *
+ * <ul>
+ * <li>https://github.com/Homebrew/homebrew/wiki/Installation</li>
+ * <li>https://trac.ffmpeg.org/wiki/CompilationGuide/MacOSX<pre>
+ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
+brew install ffmpeg
+ * </pre></li>
+ * </ul></li>
+ * <li>Builds
+ * <ul>
+ * <li>https://ffmpeg.org/download.html#build-mac</li>
+ * </ul></li>
* </ul></li>
* <li>OpenIndiana/Solaris:<pre>
- * pkg set-publisher -p http://pkg.openindiana.org/sfe-encumbered.
- * pkt install pkg:/video/ffmpeg
+pkg set-publisher -p http://pkg.openindiana.org/sfe-encumbered.
+pkt install pkg:/video/ffmpeg
* </pre></li>
* </ul>
* </p>
@@ -337,12 +349,10 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
resStreamLocS = dev_video_linux + cameraPath.decode();
break;
case WINDOWS:
- resStreamLocS = cameraPath.decode();
- break;
case MACOS:
case OPENKODE:
default:
- resStreamLocS = streamLocS; // FIXME: ??
+ resStreamLocS = cameraPath.decode();
break;
}
if( null != cameraProps ) {
@@ -436,9 +446,10 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
}
break;
- case 2: if( vPixelFmt == VideoPixelFormat.YUYV422 ) {
+ case 2: if( vPixelFmt == VideoPixelFormat.YUYV422 || vPixelFmt == VideoPixelFormat.UYVY422 ) {
// YUYV422: // < packed YUV 4:2:2, 2x 16bpp, Y0 Cb Y1 Cr
- // Stuffed into RGBA half width texture
+ // UYVY422: // < packed YUV 4:2:2, 2x 16bpp, Cb Y0 Cr Y1
+ // Both stuffed into RGBA half width texture
tf = GL.GL_RGBA; tif=GL.GL_RGBA; break;
} else {
tf = GL2ES2.GL_RG; tif=GL2ES2.GL_RG; break;
@@ -606,6 +617,7 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
texWidth = vTexWidth[0] + vTexWidth[1] + vTexWidth[2]; texHeight = vH;
break;
case YUYV422: // < packed YUV 4:2:2, 2x 16bpp, Y0 Cb Y1 Cr - stuffed into RGBA half width texture
+ case UYVY422: // < packed YUV 4:2:2, 2x 16bpp, Cb Y0 Cr Y1 - stuffed into RGBA half width texture
case BGR24:
usesTexLookupShader = true;
texWidth = vTexWidth[0]; texHeight = vH;
@@ -764,6 +776,29 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
" return vec4(r, g, b, 1);\n"+
"}\n"
;
+ case UYVY422: // < packed YUV 4:2:2, 2 x 16bpp, Cb Y0 Cr Y1
+ // Stuffed into RGBA half width texture
+ return
+ "vec4 "+texLookupFuncName+"(in "+getTextureSampler2DType()+" image, in vec2 texCoord) {\n"+
+ " "+
+ " float y1,u,y2,v,y,r,g,b;\n"+
+ " vec2 tc_halfw = vec2(texCoord.x*0.5, texCoord.y);\n"+
+ " vec4 uyvy = texture2D(image, tc_halfw).rgba;\n"+
+ " u = uyvy.r;\n"+
+ " y1 = uyvy.g;\n"+
+ " v = uyvy.b;\n"+
+ " y2 = uyvy.a;\n"+
+ " y = mix( y1, y2, mod(gl_FragCoord.x, 2) ); /* avoid branching! */\n"+
+ " y = 1.1643*(y-0.0625);\n"+
+ " u = u-0.5;\n"+
+ " v = v-0.5;\n"+
+ " r = y+1.5958*v;\n"+
+ " g = y-0.39173*u-0.81290*v;\n"+
+ " b = y+2.017*u;\n"+
+ " return vec4(r, g, b, 1);\n"+
+ "}\n"
+ ;
+
case BGR24:
return
"vec4 "+texLookupFuncName+"(in "+getTextureSampler2DType()+" image, in vec2 texCoord) {\n"+
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.fp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.fp
index 22dd1e61a..516aa0f6f 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.fp
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.fp
@@ -6,10 +6,10 @@
#define mgl_FragColor gl_FragColor
#endif
-#include es_precision.glsl
+#include "es_precision.glsl"
-#include mgl_uniform.glsl
-#include mgl_varying.glsl
+#include "mgl_uniform.glsl"
+#include "mgl_varying.glsl"
#include mgl_alphatest.fp
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorTexture.fp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorTexture.fp
index 130711e19..8a610f062 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorTexture.fp
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorTexture.fp
@@ -8,14 +8,14 @@
#endif
-#include es_precision.glsl
-#include mgl_lightdef.glsl
+#include "es_precision.glsl"
+#include "mgl_lightdef.glsl"
-#include mgl_const.glsl
-#include mgl_uniform.glsl
-#include mgl_varying.glsl
+#include "mgl_const.glsl"
+#include "mgl_uniform.glsl"
+#include "mgl_varying.glsl"
-#include mgl_alphatest.fp
+#include "mgl_alphatest.fp"
const float gamma = 1.5; // FIXME
const vec3 igammav = vec3(1.0 / gamma); // FIXME
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
index a8269ad5c..fd0db7c04 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
@@ -50,15 +50,19 @@ import com.jogamp.nativewindow.NativeSurface;
import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.GLException;
import com.jogamp.opengl.GLCapabilitiesImmutable;
+import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.nio.Buffers;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
import com.jogamp.opengl.GLExtensions;
+import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.GLRendererQuirks;
import jogamp.nativewindow.windows.GDI;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
+import jogamp.opengl.GLXExtensions;
public class WindowsWGLContext extends GLContextImpl {
static final Map<String, String> extensionNameMap;
@@ -70,7 +74,8 @@ public class WindowsWGLContext extends GLContextImpl {
// Table that holds the addresses of the native C-language entry points for
// WGL extension functions.
private WGLExtProcAddressTable wglExtProcAddressTable;
- private int hasSwapIntervalSGI = 0;
+ /** 2 WGL_EXT_swap_control_tear, 1 WGL_EXT_swap_control, 0 undefined, -1 none */
+ private int hasSwapInterval = 0;
private int hasSwapGroupNV = 0;
static {
@@ -93,7 +98,7 @@ public class WindowsWGLContext extends GLContextImpl {
wglGLReadDrawableAvailable=false;
// no inner state _wglExt=null;
wglExtProcAddressTable=null;
- hasSwapIntervalSGI = 0;
+ hasSwapInterval = 0;
hasSwapGroupNV = 0;
super.resetStates(isInit);
}
@@ -198,20 +203,37 @@ public class WindowsWGLContext extends GLContextImpl {
@Override
protected long createContextARBImpl(final long share, final boolean direct, final int ctp, final int major, final int minor) {
+ if(DEBUG) {
+ System.err.println(getThreadName()+" - WindowWGLContext.createContextARBImpl: "+getGLVersion(major, minor, ctp, "@creation") +
+ ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct);
+ }
+ final boolean ctDesktopGL = 0 == ( CTX_PROFILE_ES & ctp );
+ final boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
+ final boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ;
+ final boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ;
+ if( !ctDesktopGL ) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": WindowWGLContext.createContextARBImpl: GL ES not avail "+getGLVersion(major, minor, ctp, "@creation"));
+ }
+ return 0; // n/a
+ }
if( null == getWGLExtProcAddressTable()) {
- updateGLXProcAddressTable();
+ final GLDynamicLookupHelper dlh = getGLDynamicLookupHelper(major, ctp);
+ if( null == dlh ) {
+ if(DEBUG) {
+ System.err.println(getThreadName()+" - WindowWGLContext.createContextARBImpl: Null GLDynamicLookupHelper");
+ }
+ return 0;
+ } else {
+ updateGLXProcAddressTable(null, dlh);
+ }
}
final WGLExt _wglExt = getWGLExt();
if(DEBUG) {
- System.err.println(getThreadName()+" - WindowWGLContext.createContextARBImpl: "+getGLVersion(major, minor, ctp, "@creation") +
- ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct+
+ System.err.println(getThreadName()+" - WindowWGLContext.createContextARBImpl: "+
", wglCreateContextAttribsARB: "+toHexString(wglExtProcAddressTable._addressof_wglCreateContextAttribsARB));
}
- final boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
- final boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ;
- final boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ;
-
long ctx=0;
final int idx_flags = 4;
@@ -294,6 +316,11 @@ public class WindowsWGLContext extends GLContextImpl {
"], bitmap "+glCaps.isBitmap()+" -> "+createContextARBAvailable+
"], shared "+sharedCreatedWithARB+"]");
}
+ final GLProfile glp = glCaps.getGLProfile();
+ if( glp.isGLES() ) {
+ throw new GLException(getThreadName()+": Unable to create OpenGL ES context on desktopDevice "+device+
+ ", config "+config+", "+glp+", shareWith "+toHexString(shareWithHandle));
+ }
boolean createContextARBTried = false;
// utilize the shared context's GLXExt in case it was using the ARB method and it already exists
@@ -438,8 +465,17 @@ public class WindowsWGLContext extends GLContextImpl {
}
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Ignoring {@code contextFQN}, using {@code WGL}-{@link AbstractGraphicsDevice#getUniqueID()}.
+ * </p>
+ */
@Override
- protected final void updateGLXProcAddressTable() {
+ protected final void updateGLXProcAddressTable(final String contextFQN, final GLDynamicLookupHelper dlh) {
+ if( null == dlh ) {
+ throw new GLException("No GLDynamicLookupHelper for "+this);
+ }
final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
final String key = "WGL-"+adevice.getUniqueID();
@@ -462,7 +498,7 @@ public class WindowsWGLContext extends GLContextImpl {
}
} else {
wglExtProcAddressTable = new WGLExtProcAddressTable(new GLProcAddressResolver());
- resetProcAddressTable(wglExtProcAddressTable);
+ resetProcAddressTable(wglExtProcAddressTable, dlh);
synchronized(mappedContextTypeObjectLock) {
mappedGLXProcAddress.put(key, getWGLExtProcAddressTable());
if(DEBUG) {
@@ -487,19 +523,42 @@ public class WindowsWGLContext extends GLContextImpl {
}
@Override
- protected boolean setSwapIntervalImpl(final int interval) {
- final WGLExt wglExt = getWGLExt();
- if(0==hasSwapIntervalSGI) {
+ protected final Integer setSwapIntervalImpl2(final int interval) {
+ if( !drawable.getChosenGLCapabilities().isOnscreen() ) {
+ return null;
+ }
+ if( 0 == hasSwapInterval ) {
try {
- hasSwapIntervalSGI = wglExt.isExtensionAvailable("WGL_EXT_swap_control")?1:-1;
- } catch (final Throwable t) { hasSwapIntervalSGI=1; }
+ if ( isExtensionAvailable(GLXExtensions.WGL_EXT_swap_control) ) {
+ hasSwapInterval = 1;
+ if ( isExtensionAvailable(GLXExtensions.WGL_EXT_swap_control_tear) ) {
+ hasSwapInterval = 2;
+ if(DEBUG) { System.err.println("WGLContext.setSwapInterval.2 using: "+GLXExtensions.WGL_EXT_swap_control_tear + ", " + GLXExtensions.WGL_EXT_swap_control_tear); }
+ } else {
+ hasSwapInterval = 1;
+ if(DEBUG) { System.err.println("WGLContext.setSwapInterval.1 using: "+GLXExtensions.WGL_EXT_swap_control); }
+ }
+ } else {
+ hasSwapInterval = -1;
+ if(DEBUG) { System.err.println("WGLContext.setSwapInterval.0 N/A"); }
+ }
+ } catch (final Throwable t) { hasSwapInterval=-1; if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
}
- if (hasSwapIntervalSGI>0) {
+ if ( 0 < hasSwapInterval ) { // 2 || 1
+ final int useInterval;
+ if( 1 == hasSwapInterval && 0 > interval ) {
+ useInterval = Math.abs(interval);
+ } else {
+ useInterval = interval;
+ }
try {
- return wglExt.wglSwapIntervalEXT(interval);
- } catch (final Throwable t) { hasSwapIntervalSGI=-1; }
+ final WGLExt wglExt = getWGLExt();
+ if( wglExt.wglSwapIntervalEXT(useInterval) ) {
+ return Integer.valueOf(useInterval);
+ }
+ } catch (final Throwable t) { hasSwapInterval=-1; if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
}
- return false;
+ return null;
}
private final int initSwapGroupImpl(final WGLExt wglExt) {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
index 932c81f5d..652184e7e 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -44,8 +44,6 @@ import java.nio.Buffer;
import java.nio.ShortBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.Collection;
-import java.util.HashMap;
import java.util.List;
import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
@@ -191,11 +189,10 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
} catch (final Exception jre) { /* n/a .. */ }
}
- sharedMap = new HashMap<String, SharedResourceRunner.Resource>();
-
// Init shared resources off thread
// Will be released via ShutdownHook
- sharedResourceRunner = new SharedResourceRunner(new SharedResourceImplementation());
+ sharedResourceImplementation = new SharedResourceImplementation();
+ sharedResourceRunner = new SharedResourceRunner(sharedResourceImplementation);
sharedResourceRunner.start();
}
}
@@ -215,9 +212,9 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
sharedResourceRunner.stop();
sharedResourceRunner = null;
}
- if(null != sharedMap) {
- sharedMap.clear();
- sharedMap = null;
+ if(null != sharedResourceImplementation) {
+ sharedResourceImplementation.clear();
+ sharedResourceImplementation = null;
}
defaultDevice = null;
/**
@@ -231,15 +228,15 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- public GLDynamicLookupHelper getGLDynamicLookupHelper(final String profileName) {
+ public final GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions) {
return windowsWGLDynamicLookupHelper;
}
/* pp */ static String toHexString(final long l) { return "0x"+Long.toHexString(l); }
private WindowsGraphicsDevice defaultDevice;
+ private SharedResourceImplementation sharedResourceImplementation;
private SharedResourceRunner sharedResourceRunner;
- private HashMap<String /*connection*/, SharedResourceRunner.Resource> sharedMap;
@Override
protected void enterThreadCriticalZone() {
@@ -300,26 +297,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
final boolean hasReadDrawable() { return hasARBReadDrawable; }
}
- class SharedResourceImplementation implements SharedResourceRunner.Implementation {
- @Override
- public void clear() {
- sharedMap.clear();
- }
- @Override
- public SharedResourceRunner.Resource mapPut(final AbstractGraphicsDevice device, final SharedResourceRunner.Resource resource) {
- return sharedMap.put(device.getConnection(), resource);
- }
- @Override
- public SharedResourceRunner.Resource mapGet(final AbstractGraphicsDevice device) {
- return sharedMap.get(device.getConnection());
- }
- @Override
- public Collection<SharedResourceRunner.Resource> mapValues() {
- synchronized(sharedMap) {
- return sharedMap.values();
- }
- }
-
+ class SharedResourceImplementation extends SharedResourceRunner.AImplementation {
@Override
public boolean isDeviceSupported(final AbstractGraphicsDevice device) {
return true;
@@ -465,6 +443,33 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
return null;
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory always supports native desktop OpenGL profiles.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLDesktopSupport() { return true; }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory never supports native GLES profiles.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLESSupport() { return false; }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Always returns true.
+ * </p>
+ */
+ @Override
+ public final boolean hasMajorMinorCreateContextARB() { return true; }
+
@Override
protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(final AbstractGraphicsDevice device) {
return WindowsWGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device);
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
index f88718d1b..4ffe6e7d1 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -171,24 +171,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
": error code " + GDI.GetLastError());
}
if( !caps.isBackgroundOpaque() ) {
- final long hwnd = GDI.WindowFromDC(hdc);
- final DWM_BLURBEHIND bb = DWM_BLURBEHIND.create();
- bb.setDwFlags(GDI.DWM_BB_ENABLE| GDI.DWM_BB_TRANSITIONONMAXIMIZED);
- bb.setFEnable( 1 );
- boolean ok = GDI.DwmEnableBlurBehindWindow(hwnd, bb);
- if( ok ) {
- final MARGINS m = MARGINS.create();
- m.setCxLeftWidth(-1);
- m.setCxRightWidth(-1);
- m.setCyBottomHeight(-1);
- m.setCyTopHeight(-1);
- ok = GDI.DwmExtendFrameIntoClientArea(hwnd, m);
- }
- if(DEBUG) {
- final boolean isUndecorated = GDIUtil.IsUndecorated(hwnd);
- final boolean isChild = GDIUtil.IsChild(hwnd);
- System.err.println("translucency enabled on wnd: 0x"+Long.toHexString(hwnd)+" - isUndecorated "+isUndecorated+", isChild "+isChild+", ok: "+ok);
- }
+ GDIUtil.DwmSetupTranslucency(GDI.WindowFromDC(hdc), true);
}
if (DEBUG) {
System.err.println("setPixelFormat: hdc "+toHexString(hdc) +", "+caps);
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
index 21eb6b8f3..99268f13f 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -56,6 +56,7 @@ import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.GLRendererQuirks;
import jogamp.nativewindow.windows.GDI;
+import jogamp.nativewindow.windows.GDIUtil;
import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.GLGraphicsConfigurationFactory;
@@ -349,7 +350,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
}
final GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
- final boolean isOpaque = capsChosen.isBackgroundOpaque() && GDI.DwmIsCompositionEnabled();
+ final boolean isOpaque = capsChosen.isBackgroundOpaque() && GDIUtil.DwmIsCompositionEnabled();
final int winattrbits = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen)
& ~GLGraphicsConfigurationUtil.BITMAP_BIT; // w/o BITMAP
final GLProfile glProfile = capsChosen.getGLProfile();
@@ -358,7 +359,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
if(DEBUG) {
System.err.println("updateGraphicsConfigurationARB: hdc "+toHexString(hdc)+", pfdIDCount(hdc) "+pfdIDCount+", capsChosen "+capsChosen+", "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString());
- System.err.println("\tisOpaque "+isOpaque+" (translucency requested: "+(!capsChosen.isBackgroundOpaque())+", compositioning enabled: "+GDI.DwmIsCompositionEnabled()+")");
+ System.err.println("\tisOpaque "+isOpaque+" (translucency requested: "+(!capsChosen.isBackgroundOpaque())+", compositioning enabled: "+GDIUtil.DwmIsCompositionEnabled()+")");
final int pformatsNum = null != pformats ? pformats.length : -1;
System.err.println("\textHDC "+extHDC+", chooser "+(null!=chooser)+", pformatsNum "+pformatsNum);
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
index 63b0b35c0..24f2ab8dd 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
@@ -56,6 +56,7 @@ import jogamp.nativewindow.x11.X11Lib;
import jogamp.nativewindow.x11.X11Util;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
import jogamp.opengl.GLXExtensions;
import com.jogamp.common.ExceptionUtils;
@@ -72,7 +73,7 @@ public class X11GLXContext extends GLContextImpl {
// Table that holds the addresses of the native C-language entry points for
// GLX extension functions.
private GLXExtProcAddressTable glXExtProcAddressTable;
- /** 1 MESA, 2 SGI, 0 undefined, -1 none */
+ /** 3 SGI, 2 GLX_EXT_swap_control_tear, 1 GLX_EXT_swap_control, 0 undefined, -1 none */
private int hasSwapInterval = 0;
private int hasSwapGroupNV = 0;
@@ -224,17 +225,34 @@ public class X11GLXContext extends GLContextImpl {
@Override
protected long createContextARBImpl(final long share, final boolean direct, final int ctp, final int major, final int minor) {
- updateGLXProcAddressTable();
- final GLXExt _glXExt = getGLXExt();
if(DEBUG) {
System.err.println(getThreadName()+": X11GLXContext.createContextARBImpl: "+getGLVersion(major, minor, ctp, "@creation") +
- ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct+
- ", glXCreateContextAttribsARB: "+toHexString(glXExtProcAddressTable._addressof_glXCreateContextAttribsARB));
+ ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct);
}
-
+ final boolean ctDesktopGL = 0 == ( CTX_PROFILE_ES & ctp );
final boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
final boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ;
final boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ;
+ if( !ctDesktopGL ) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": X11GLXContext.createContextARBImpl: GL ES not avail "+getGLVersion(major, minor, ctp, "@creation"));
+ }
+ return 0; // n/a
+ }
+ final GLDynamicLookupHelper dlh = getGLDynamicLookupHelper(major, ctp);
+ if( null == dlh ) {
+ if(DEBUG) {
+ System.err.println(getThreadName()+" - X11GLXContext.createContextARBImpl: Null GLDynamicLookupHelper");
+ }
+ return 0;
+ } else {
+ updateGLXProcAddressTable(null, dlh);
+ }
+ final GLXExt _glXExt = getGLXExt();
+ if(DEBUG) {
+ System.err.println(getThreadName()+": X11GLXContext.createContextARBImpl: "+
+ ", glXCreateContextAttribsARB: "+toHexString(glXExtProcAddressTable._addressof_glXCreateContextAttribsARB));
+ }
final IntBuffer attribs = Buffers.newDirectIntBuffer(ctx_arb_attribs_rom);
attribs.put(ctx_arb_attribs_idx_major + 1, major);
@@ -322,6 +340,10 @@ public class X11GLXContext extends GLContextImpl {
"], fbCfg "+config.hasFBConfig()+" -> "+createContextARBAvailable+
"], shared "+sharedCreatedWithARB+"]");
}
+ if( glp.isGLES() ) {
+ throw new GLException(getThreadName()+": Unable to create OpenGL ES context on desktopDevice "+device+
+ ", config "+config+", "+glp+", shareWith "+toHexString(shareWithHandle));
+ }
if( !config.hasFBConfig() ) {
// not able to use FBConfig -> GLX 1.1
@@ -479,8 +501,17 @@ public class X11GLXContext extends GLContextImpl {
// Should check for X errors and raise GLException
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Ignoring {@code contextFQN}, using {@code GLX}+{@link AbstractGraphicsDevice#getUniqueID()}.
+ * </p>
+ */
@Override
- protected final void updateGLXProcAddressTable() {
+ protected final void updateGLXProcAddressTable(final String contextFQN, final GLDynamicLookupHelper dlh) {
+ if( null == dlh ) {
+ throw new GLException("No GLDynamicLookupHelper for "+this);
+ }
final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
final String key = "GLX-"+adevice.getUniqueID();
@@ -498,7 +529,7 @@ public class X11GLXContext extends GLContextImpl {
}
} else {
glXExtProcAddressTable = new GLXExtProcAddressTable(new GLProcAddressResolver());
- resetProcAddressTable(getGLXExtProcAddressTable());
+ resetProcAddressTable(getGLXExtProcAddressTable(), dlh);
synchronized(mappedContextTypeObjectLock) {
mappedGLXProcAddress.put(key, getGLXExtProcAddressTable());
if(DEBUG) {
@@ -549,39 +580,67 @@ public class X11GLXContext extends GLContextImpl {
}
@Override
- protected boolean setSwapIntervalImpl(final int interval) {
- if( !drawable.getChosenGLCapabilities().isOnscreen() ) { return false; }
-
- final GLXExt glXExt = getGLXExt();
- if(0==hasSwapInterval) {
+ protected final Integer setSwapIntervalImpl2(final int interval) {
+ if( !drawable.getChosenGLCapabilities().isOnscreen() ) {
+ return null;
+ }
+ final long displayHandle = drawable.getNativeSurface().getDisplayHandle();
+ if( 0 == hasSwapInterval ) {
try {
- /** Same impl. ..
- if( glXExt.isExtensionAvailable(GLXExtensions.GLX_MESA_swap_control) ) {
- if(DEBUG) { System.err.println("X11GLXContext.setSwapInterval using: "+GLXExtensions.GLX_MESA_swap_control); }
- hasSwapInterval = 1;
- } else */
- if ( glXExt.isExtensionAvailable(GLXExtensions.GLX_SGI_swap_control) ) {
- if(DEBUG) { System.err.println("X11GLXContext.setSwapInterval using: "+GLXExtensions.GLX_SGI_swap_control); }
- hasSwapInterval = 2;
+ if ( isExtensionAvailable(GLXExtensions.GLX_EXT_swap_control) ) {
+ hasSwapInterval = 1;
+ if ( isExtensionAvailable(GLXExtensions.GLX_EXT_swap_control_tear) ) {
+ try {
+ final IntBuffer val = Buffers.newDirectIntBuffer(1);
+ GLX.glXQueryDrawable(displayHandle, drawable.getHandle(), GLX.GLX_LATE_SWAPS_TEAR_EXT, val);
+ if( 1 == val.get(0) ) {
+ hasSwapInterval = 2;
+ if(DEBUG) { System.err.println("X11GLXContext.setSwapInterval.2 using: "+GLXExtensions.GLX_EXT_swap_control_tear + ", " + GLXExtensions.GLX_EXT_swap_control_tear); }
+ } else if(DEBUG) {
+ System.err.println("X11GLXContext.setSwapInterval.2 n/a: "+GLXExtensions.GLX_EXT_swap_control_tear+", query: "+val.get(0));
+ }
+ } catch (final Throwable t) { if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
+ }
+ if(DEBUG) {
+ if( 1 == hasSwapInterval ) {
+ System.err.println("X11GLXContext.setSwapInterval.1 using: "+GLXExtensions.GLX_EXT_swap_control);
+ }
+ }
+ } else if ( isExtensionAvailable(GLXExtensions.GLX_SGI_swap_control) ) {
+ hasSwapInterval = 3;
+ if(DEBUG) { System.err.println("X11GLXContext.setSwapInterval.3 using: "+GLXExtensions.GLX_SGI_swap_control); }
} else {
hasSwapInterval = -1;
+ if(DEBUG) { System.err.println("X11GLXContext.setSwapInterval.0 N/A"); }
}
- } catch (final Throwable t) { hasSwapInterval=-1; }
+ } catch (final Throwable t) { hasSwapInterval=-1; if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
}
- /* try {
- switch( hasSwapInterval ) {
- case 1:
- return 0 == glXExt.glXSwapIntervalMESA(interval);
- case 2:
- return 0 == glXExt.glXSwapIntervalSGI(interval);
+ if (3 == hasSwapInterval) {
+ final int useInterval;
+ if( 0 > interval ) {
+ useInterval = Math.abs(interval);
+ } else {
+ useInterval = interval;
+ }
+ try {
+ final GLXExt glXExt = getGLXExt();
+ if( 0 == glXExt.glXSwapIntervalSGI(useInterval) ) {
+ return Integer.valueOf(useInterval);
+ }
+ } catch (final Throwable t) { hasSwapInterval=-1; if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
+ } else if ( 0 < hasSwapInterval ) { // 2 || 1
+ final int useInterval;
+ if( 1 == hasSwapInterval && 0 > interval ) {
+ useInterval = Math.abs(interval);
+ } else {
+ useInterval = interval;
}
- } catch (Throwable t) { hasSwapInterval = -1; } */
- if (2 == hasSwapInterval) {
try {
- return 0 == glXExt.glXSwapIntervalSGI(interval);
- } catch (final Throwable t) { hasSwapInterval=-1; }
+ GLX.glXSwapIntervalEXT(displayHandle, drawable.getHandle(), useInterval);
+ return Integer.valueOf(useInterval);
+ } catch (final Throwable t) { hasSwapInterval=-1; if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
}
- return false;
+ return null;
}
private final int initSwapGroupImpl(final GLXExt glXExt) {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index ecaf20d86..a03ce1641 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -41,8 +41,6 @@ import java.nio.Buffer;
import java.nio.ShortBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.Collection;
-import java.util.HashMap;
import java.util.List;
import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
@@ -126,11 +124,10 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
// The act of constructing them causes them to be registered
X11GLXGraphicsConfigurationFactory.registerFactory();
- sharedMap = new HashMap<String, SharedResourceRunner.Resource>();
-
// Init shared resources off thread
// Will be released via ShutdownHook
- sharedResourceRunner = new SharedResourceRunner(new SharedResourceImplementation());
+ sharedResourceImplementation = new SharedResourceImplementation();
+ sharedResourceRunner = new SharedResourceRunner(sharedResourceImplementation);
sharedResourceRunner.start();
}
}
@@ -149,9 +146,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
sharedResourceRunner.stop();
sharedResourceRunner = null;
}
- if(null != sharedMap) {
- sharedMap.clear();
- sharedMap = null;
+ if(null != sharedResourceImplementation) {
+ sharedResourceImplementation.clear();
+ sharedResourceImplementation = null;
}
defaultDevice = null;
/**
@@ -163,13 +160,13 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- public final GLDynamicLookupHelper getGLDynamicLookupHelper(final String profileName) {
+ public final GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions) {
return x11GLXDynamicLookupHelper;
}
private X11GraphicsDevice defaultDevice;
+ private SharedResourceImplementation sharedResourceImplementation;
private SharedResourceRunner sharedResourceRunner;
- private HashMap<String /* connection */, SharedResourceRunner.Resource> sharedMap;
static class SharedResource implements SharedResourceRunner.Resource {
private final String glXServerVendorName;
@@ -226,24 +223,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
final boolean isGLXMultisampleAvailable() { return glXMultisampleAvailable; }
}
- class SharedResourceImplementation implements SharedResourceRunner.Implementation {
- @Override
- public void clear() {
- sharedMap.clear();
- }
- @Override
- public SharedResourceRunner.Resource mapPut(final AbstractGraphicsDevice device, final SharedResourceRunner.Resource resource) {
- return sharedMap.put(device.getConnection(), resource);
- }
- @Override
- public SharedResourceRunner.Resource mapGet(final AbstractGraphicsDevice device) {
- return sharedMap.get(device.getConnection());
- }
- @Override
- public Collection<SharedResourceRunner.Resource> mapValues() {
- return sharedMap.values();
- }
-
+ class SharedResourceImplementation extends SharedResourceRunner.AImplementation {
@Override
public boolean isDeviceSupported(final AbstractGraphicsDevice device) {
final boolean res;
@@ -399,6 +379,33 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
return 0;
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory always supports native desktop OpenGL profiles.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLDesktopSupport() { return true; }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory never supports native GLES profiles.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLESSupport() { return false; }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Always returns true.
+ * </p>
+ */
+ @Override
+ public final boolean hasMajorMinorCreateContextARB() { return true; }
+
@Override
protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(final AbstractGraphicsDevice device) {
return X11GLXGraphicsConfigurationFactory.getAvailableCapabilities(this, device);
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
index 86349b645..8f7d710cd 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -275,21 +275,6 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
return val;
}
- static XRenderDirectFormat XVisual2XRenderMask(final long dpy, final long visual) {
- final XRenderPictFormat renderPictFmt = X11Lib.XRenderFindVisualFormat(dpy, visual);
- if(null == renderPictFmt) {
- return null;
- }
- return renderPictFmt.getDirect();
- }
- static XRenderDirectFormat XVisual2XRenderMask(final long dpy, final long visual, final XRenderPictFormat dest) {
- if( !X11Lib.XRenderFindVisualFormat(dpy, visual, dest) ) {
- return null;
- } else {
- return dest.getDirect();
- }
- }
-
static X11GLCapabilities GLXFBConfig2GLCapabilities(final X11GraphicsDevice device, final GLProfile glp, final long fbcfg,
final int winattrmask, final boolean isMultisampleAvailable) {
final IntBuffer tmp = Buffers.newDirectIntBuffer(1);