summaryrefslogtreecommitdiffstats
path: root/src/jogl
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl')
-rw-r--r--src/jogl/classes/com/jogamp/audio/windows/waveout/Mixer.java239
-rw-r--r--src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java35
-rw-r--r--src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java8
-rw-r--r--src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java44
-rw-r--r--src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLNameResolver.java9
-rw-r--r--src/jogl/classes/com/jogamp/graph/font/FontFactory.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLAnimatorControl.java3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLBase.java73
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLContext.java222
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLDrawable.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLDrawableFactory.java12
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLExtensions.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLProfile.java117
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java7
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLUniformData.java1
-rw-r--r--src/jogl/classes/com/jogamp/opengl/JoglVersion.java3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/awt/GLCanvas.java6
-rw-r--r--src/jogl/classes/com/jogamp/opengl/awt/GLJPanel.java3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java12
-rw-r--r--src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java15
-rw-r--r--src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java51
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java48
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/Animator.java23
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java8
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java13
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java4
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java4
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/PNGPixelRect.java3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java19
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java46
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShader.java4
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/ImageIOUtil.java445
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/ImageType.java1579
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java51
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java14
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java319
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java35
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java24
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java101
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java51
-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
-rw-r--r--src/jogl/native/GLDebugMessageHandler.c7
-rw-r--r--src/jogl/native/libav/ffmpeg_impl_template.c11
86 files changed, 4354 insertions, 2303 deletions
diff --git a/src/jogl/classes/com/jogamp/audio/windows/waveout/Mixer.java b/src/jogl/classes/com/jogamp/audio/windows/waveout/Mixer.java
index bbfe72b08..30b3fd278 100644
--- a/src/jogl/classes/com/jogamp/audio/windows/waveout/Mixer.java
+++ b/src/jogl/classes/com/jogamp/audio/windows/waveout/Mixer.java
@@ -36,6 +36,9 @@ import java.io.*;
import java.nio.*;
import java.util.*;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.InterruptedRuntimeException;
+
// Needed only for NIO workarounds on CVM
import java.lang.reflect.*;
@@ -43,9 +46,10 @@ public class Mixer {
// This class is a singleton
private static Mixer mixer;
- private volatile boolean shutdown;
- private volatile Object shutdownLock = new Object();
- private volatile boolean shutdownDone;
+ volatile boolean fillerAlive;
+ volatile boolean mixerAlive;
+ volatile boolean shutdown;
+ volatile Object shutdownLock = new Object();
// Windows Event object
private final long event;
@@ -63,6 +67,9 @@ public class Mixer {
private Mixer() {
event = CreateEvent();
+ fillerAlive = false;
+ mixerAlive = false;
+ shutdown = false;
new FillerThread().start();
final MixerThread m = new MixerThread();
m.setPriority(Thread.MAX_PRIORITY - 1);
@@ -118,50 +125,57 @@ public class Mixer {
shutdown = true;
SetEvent(event);
try {
- shutdownLock.wait();
+ while(fillerAlive || mixerAlive) {
+ shutdownLock.wait();
+ }
} catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
}
}
- class FillerThread extends Thread {
+ class FillerThread extends InterruptSource.Thread {
FillerThread() {
- super("Mixer Thread");
+ super(null, null, "Mixer Thread");
}
@Override
public void run() {
- while (!shutdown) {
- final List<Track> curTracks = tracks;
+ fillerAlive = true;
+ try {
+ while (!shutdown) {
+ final List<Track> curTracks = tracks;
- for (final Iterator<Track> iter = curTracks.iterator(); iter.hasNext(); ) {
- final Track track = iter.next();
+ for (final Iterator<Track> iter = curTracks.iterator(); iter.hasNext(); ) {
+ final Track track = iter.next();
+ try {
+ track.fill();
+ } catch (final IOException e) {
+ e.printStackTrace();
+ remove(track);
+ }
+ }
try {
- track.fill();
- } catch (final IOException e) {
- e.printStackTrace();
- remove(track);
+ // Run ten times per second
+ java.lang.Thread.sleep(100);
+ } catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
}
-
- try {
- // Run ten times per second
- Thread.sleep(100);
- } catch (final InterruptedException e) {
- e.printStackTrace();
- }
+ } finally {
+ fillerAlive = false;
}
}
}
- class MixerThread extends Thread {
+ class MixerThread extends InterruptSource.Thread {
// Temporary mixing buffer
// Interleaved left and right channels
float[] mixingBuffer;
private final Vec3f temp = new Vec3f();
MixerThread() {
- super("Mixer Thread");
+ super(null, null, "Mixer Thread");
if (!initializeWaveOut(event)) {
throw new InternalError("Error initializing waveout device");
}
@@ -169,108 +183,113 @@ public class Mixer {
@Override
public void run() {
- while (!shutdown) {
- // Get the next buffer
- final long mixerBuffer = getNextMixerBuffer();
- if (mixerBuffer != 0) {
- ByteBuffer buf = getMixerBufferData(mixerBuffer);
-
- if (buf == null) {
- // This is happening on CVM because
- // JNI_NewDirectByteBuffer isn't implemented
- // by default and isn't compatible with the
- // JSR-239 NIO implementation (apparently)
- buf = newDirectByteBuffer(getMixerBufferDataAddress(mixerBuffer),
- getMixerBufferDataCapacity(mixerBuffer));
- }
+ mixerAlive = true;
+ try {
+ while (!shutdown) {
+ // Get the next buffer
+ final long mixerBuffer = getNextMixerBuffer();
+ if (mixerBuffer != 0) {
+ ByteBuffer buf = getMixerBufferData(mixerBuffer);
+
+ if (buf == null) {
+ // This is happening on CVM because
+ // JNI_NewDirectByteBuffer isn't implemented
+ // by default and isn't compatible with the
+ // JSR-239 NIO implementation (apparently)
+ buf = newDirectByteBuffer(getMixerBufferDataAddress(mixerBuffer),
+ getMixerBufferDataCapacity(mixerBuffer));
+ }
- if (buf == null) {
- throw new InternalError("Couldn't wrap the native address with a direct byte buffer");
- }
+ if (buf == null) {
+ throw new InternalError("Couldn't wrap the native address with a direct byte buffer");
+ }
- // System.out.println("Mixing buffer");
+ // System.out.println("Mixing buffer");
- // If we don't have enough samples in our mixing buffer, expand it
- // FIXME: knowledge of native output rendering format
- if ((mixingBuffer == null) || (mixingBuffer.length < (buf.capacity() / 2 /* bytes / sample */))) {
- mixingBuffer = new float[buf.capacity() / 2];
- } else {
- // Zap it
- for (int i = 0; i < mixingBuffer.length; i++) {
- mixingBuffer[i] = 0.0f;
+ // If we don't have enough samples in our mixing buffer, expand it
+ // FIXME: knowledge of native output rendering format
+ if ((mixingBuffer == null) || (mixingBuffer.length < (buf.capacity() / 2 /* bytes / sample */))) {
+ mixingBuffer = new float[buf.capacity() / 2];
+ } else {
+ // Zap it
+ for (int i = 0; i < mixingBuffer.length; i++) {
+ mixingBuffer[i] = 0.0f;
+ }
}
- }
-
- // This assertion should be in place if we have stereo
- if ((mixingBuffer.length % 2) != 0) {
- final String msg = "FATAL ERROR: odd number of samples in the mixing buffer";
- System.out.println(msg);
- throw new InternalError(msg);
- }
- // Run down all of the registered tracks mixing them in
- final List<Track> curTracks = tracks;
+ // This assertion should be in place if we have stereo
+ if ((mixingBuffer.length % 2) != 0) {
+ final String msg = "FATAL ERROR: odd number of samples in the mixing buffer";
+ System.out.println(msg);
+ throw new InternalError(msg);
+ }
- for (final Iterator<Track> iter = curTracks.iterator(); iter.hasNext(); ) {
- final Track track = iter.next();
- // Consider only playing tracks
- if (track.isPlaying()) {
- // First recompute its gain
- final Vec3f pos = track.getPosition();
- final float leftGain = gain(pos, leftSpeakerPosition);
- final float rightGain = gain(pos, rightSpeakerPosition);
- // Now mix it in
- int i = 0;
- while (i < mixingBuffer.length) {
- if (track.hasNextSample()) {
- final float sample = track.nextSample();
- mixingBuffer[i++] = sample * leftGain;
- mixingBuffer[i++] = sample * rightGain;
- } else {
- // This allows tracks to stall without being abruptly cancelled
- if (track.done()) {
- remove(track);
+ // Run down all of the registered tracks mixing them in
+ final List<Track> curTracks = tracks;
+
+ for (final Iterator<Track> iter = curTracks.iterator(); iter.hasNext(); ) {
+ final Track track = iter.next();
+ // Consider only playing tracks
+ if (track.isPlaying()) {
+ // First recompute its gain
+ final Vec3f pos = track.getPosition();
+ final float leftGain = gain(pos, leftSpeakerPosition);
+ final float rightGain = gain(pos, rightSpeakerPosition);
+ // Now mix it in
+ int i = 0;
+ while (i < mixingBuffer.length) {
+ if (track.hasNextSample()) {
+ final float sample = track.nextSample();
+ mixingBuffer[i++] = sample * leftGain;
+ mixingBuffer[i++] = sample * rightGain;
+ } else {
+ // This allows tracks to stall without being abruptly cancelled
+ if (track.done()) {
+ remove(track);
+ }
+ break;
}
- break;
}
}
}
- }
- // Now that we have our data, send it down to the card
- int outPos = 0;
- for (int i = 0; i < mixingBuffer.length; i++) {
- final short val = (short) mixingBuffer[i];
- buf.put(outPos++, (byte) val);
- buf.put(outPos++, (byte) (val >> 8));
- }
- if (!prepareMixerBuffer(mixerBuffer)) {
- throw new RuntimeException("Error preparing mixer buffer");
- }
- if (!writeMixerBuffer(mixerBuffer)) {
- throw new RuntimeException("Error writing mixer buffer to device");
- }
- } else {
- // System.out.println("No mixer buffer available");
+ // Now that we have our data, send it down to the card
+ int outPos = 0;
+ for (int i = 0; i < mixingBuffer.length; i++) {
+ final short val = (short) mixingBuffer[i];
+ buf.put(outPos++, (byte) val);
+ buf.put(outPos++, (byte) (val >> 8));
+ }
+ if (!prepareMixerBuffer(mixerBuffer)) {
+ throw new RuntimeException("Error preparing mixer buffer");
+ }
+ if (!writeMixerBuffer(mixerBuffer)) {
+ throw new RuntimeException("Error writing mixer buffer to device");
+ }
+ } else {
+ // System.out.println("No mixer buffer available");
- // Wait for a buffer to become available
- if (!WaitForSingleObject(event)) {
- throw new RuntimeException("Error while waiting for event object");
- }
+ // Wait for a buffer to become available
+ if (!WaitForSingleObject(event)) {
+ throw new RuntimeException("Error while waiting for event object");
+ }
- /*
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
+ /*
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
+ }
+ */
}
- */
}
- }
-
- // Need to shut down
- shutdownWaveOut();
- synchronized(shutdownLock) {
- shutdownLock.notifyAll();
+ } finally {
+ mixerAlive = false;
+ // Need to shut down
+ shutdownWaveOut();
+ synchronized(shutdownLock) {
+ shutdownLock.notifyAll();
+ }
}
}
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java b/src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java
index 9381d318b..9f885e55d 100644
--- a/src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java
+++ b/src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java
@@ -391,35 +391,16 @@ public class BuildComposablePipeline {
final PrintWriter output = new PrintWriter(new BufferedWriter(new FileWriter(file)));
- final List<Class<?>> baseInterfaces = Arrays.asList(baseInterfaceClass.getInterfaces());
- final HashSet<Class<?>> clazzList = new HashSet<Class<?>>();
- clazzList.add(baseInterfaceClass);
- clazzList.addAll(baseInterfaces);
- final int ifNamesNumber = clazzList.size();
-
- // keep original order ..
- clazzList.clear();
- final String[] ifNames = new String[ifNamesNumber];
- {
- int i = 0;
-
- for (final Iterator<Class<?>> iter = baseInterfaces.iterator(); iter.hasNext();) {
- final Class<?> ifClass = iter.next();
- if (!clazzList.contains(ifClass)) {
- ifNames[i++] = ifClass.getName();
- clazzList.add(ifClass);
- }
- }
+ final HashSet<Class<?>> importClazzList = new HashSet<Class<?>>();
+ importClazzList.add(baseInterfaceClass);
+ final String[] ifNames = new String[] { baseInterfaceClass.getName() };
- if ( !clazzList.contains(baseInterfaceClass) ) {
- ifNames[i++] = baseInterfaceClass.getName();
- clazzList.add(baseInterfaceClass);
- }
- }
+ final List<Class<?>> baseInterfaces = Arrays.asList(baseInterfaceClass.getInterfaces());
+ importClazzList.addAll(baseInterfaces);
- clazzList.add(downstreamClass);
+ importClazzList.add(downstreamClass);
if (null != prologClassOpt) {
- clazzList.add(prologClassOpt);
+ importClazzList.add(prologClassOpt);
}
final ArrayList<String> imports = new ArrayList<String>();
@@ -427,7 +408,7 @@ public class BuildComposablePipeline {
imports.add("com.jogamp.opengl.*");
imports.add("com.jogamp.gluegen.runtime.*");
imports.add(Buffer.class.getPackage().getName()+".*");
- for (final Class<?> clasS : clazzList) {
+ for (final Class<?> clasS : importClazzList) {
imports.add(clasS.getName());
}
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java b/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java
index d6f72ee29..1c034ebfb 100644
--- a/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java
+++ b/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java
@@ -254,6 +254,14 @@ public class GLConfiguration extends ProcAddressConfiguration {
super.logRenames();
}
+ protected boolean isIgnoredExtension(final String extensionName) {
+ if( ignoredExtensions.contains(extensionName) ) {
+ return !forcedExtensions.contains(extensionName);
+ } else {
+ return false;
+ }
+ }
+
protected boolean shouldIgnoreExtension(final AliasedSymbol symbol) {
final Set<String> symExtensionNames;
// collect current-name symbol extensions
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java b/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java
index 8df4a9488..a68fc6b2a 100644
--- a/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java
+++ b/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java
@@ -112,31 +112,35 @@ public class GLEmitter extends ProcAddressEmitter {
final Set<String> extensionSet = isSemHeader ? config.getExtensionsRenamedIntoCore() : glInfo.getExtensions();
for (final String extension : extensionSet) {
- LOG.log(INFO, "<RenameExtensionIntoCore: {0} BEGIN {1}", extension, headerType);
- final Set<String> declarations = glInfo.getDeclarations(extension);
- if (declarations != null) {
- for (final Iterator<String> iterator = declarations.iterator(); iterator.hasNext();) {
- final String decl = iterator.next();
- final boolean isGLFunction = GLNameResolver.isGLFunction(decl);
- boolean isGLEnumeration = false;
- if (!isGLFunction) {
- isGLEnumeration = GLNameResolver.isGLEnumeration(decl);
- }
- if (isGLFunction || isGLEnumeration) {
- final String renamed = GLNameResolver.normalize(decl, isGLFunction);
- if (!renamed.equals(decl)) {
- if( isSemHeader ) {
- // Sem + Doc
- config.addJavaSymbolRename(decl, renamed);
- } else {
- // Doc only
- config.addJavaDocSymbolRename(decl, renamed);
+ if( isSemHeader && config.isIgnoredExtension(extension) ) {
+ LOG.log(INFO, "<RenameExtensionIntoCore: {0} IGNORED {1}>", extension, headerType);
+ } else {
+ LOG.log(INFO, "<RenameExtensionIntoCore: {0} BEGIN {1}", extension, headerType);
+ final Set<String> declarations = glInfo.getDeclarations(extension);
+ if (declarations != null) {
+ for (final Iterator<String> iterator = declarations.iterator(); iterator.hasNext();) {
+ final String decl = iterator.next();
+ final boolean isGLFunction = GLNameResolver.isGLFunction(decl);
+ boolean isGLEnumeration = false;
+ if (!isGLFunction) {
+ isGLEnumeration = GLNameResolver.isGLEnumeration(decl);
+ }
+ if (isGLFunction || isGLEnumeration) {
+ final String renamed = GLNameResolver.normalize(decl, isGLFunction);
+ if (!renamed.equals(decl)) {
+ if( isSemHeader ) {
+ // Sem + Doc
+ config.addJavaSymbolRename(decl, renamed);
+ } else {
+ // Doc only
+ config.addJavaDocSymbolRename(decl, renamed);
+ }
}
}
}
}
+ LOG.log(INFO, "RenameExtensionIntoCore: {0} END>", extension, headerType);
}
- LOG.log(INFO, "RenameExtensionIntoCore: {0} END>", extension, headerType);
}
}
diff --git a/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLNameResolver.java b/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLNameResolver.java
index d400381c8..d7e340630 100644
--- a/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLNameResolver.java
+++ b/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLNameResolver.java
@@ -50,27 +50,30 @@ public class GLNameResolver {
private static final String[] extensionsARB = { "ARB", "GL2", "OES", "KHR", "OML" };
private static final String[] extensionsVEN = { "3DFX",
"AMD",
+ "ANDROID",
"ANGLE",
"ARM",
"APPLE",
"ATI",
"EXT",
+ "FJ",
"HI",
"HP",
"IBM",
"IMG",
+ "INGR",
+ "INTEL",
"MESA",
"MESAX",
"NV",
+ "PGI",
"QCOM",
"SGI",
"SGIS",
"SGIX",
"SUN",
"VIV",
- "WIN"
- };
-
+ "WIN" };
public static final boolean isGLFunction(final String str) {
return str.startsWith("gl") || /* str.startsWith("glu") || str.startsWith("glX") || */
diff --git a/src/jogl/classes/com/jogamp/graph/font/FontFactory.java b/src/jogl/classes/com/jogamp/graph/font/FontFactory.java
index be16e030f..76badcda8 100644
--- a/src/jogl/classes/com/jogamp/graph/font/FontFactory.java
+++ b/src/jogl/classes/com/jogamp/graph/font/FontFactory.java
@@ -199,7 +199,7 @@ public class FontFactory {
throw new IOException(e);
}
} else {
- stream = IOUtil.getResource(context, fname).getInputStream();
+ stream = IOUtil.getResource(fname, context.getClassLoader(), context).getInputStream();
}
if( null != stream ) {
return FontFactory.get ( stream, true ) ;
diff --git a/src/jogl/classes/com/jogamp/opengl/GLAnimatorControl.java b/src/jogl/classes/com/jogamp/opengl/GLAnimatorControl.java
index 549efd569..38b8f770b 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLAnimatorControl.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLAnimatorControl.java
@@ -58,7 +58,8 @@ public interface GLAnimatorControl extends FPSCounter {
* Any exception thrown by this method will be ignored.
* </p>
* @param animator the {@link GLAnimatorControl}
- * @param drawable the causing {@link GLAutoDrawable}
+ * @param drawable the causing {@link GLAutoDrawable},
+ * may be {@code null} in case {@link Throwable} caused unrelated to any {@link GLAutoDrawable}.
* @param cause the uncaught exception
* @see GLAnimatorControl#setUncaughtExceptionHandler(UncaughtExceptionHandler)
* @since 2.2
diff --git a/src/jogl/classes/com/jogamp/opengl/GLBase.java b/src/jogl/classes/com/jogamp/opengl/GLBase.java
index dee5f1488..0cbcbe40f 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLBase.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLBase.java
@@ -237,6 +237,19 @@ public interface GLBase {
public boolean isGLES31Compatible();
/**
+ * Indicates whether this GL object is compatible with the core OpenGL ES3.2 functionality.
+ * <p>
+ * Return true if the underlying context is an ES3 context &ge; 3.2 or implements
+ * the extension <code>GL_ARB_ES3_2_compatibility</code>, otherwise false.
+ * </p>
+ * <p>
+ * Includes [ GL &ge; 4.5, GL &ge; 3.1 w/ GL_ARB_ES3_2_compatibility and GLES3 &ge; 3.2 ]
+ * </p>
+ * @see GLContext#isGLES32Compatible()
+ */
+ public boolean isGLES32Compatible();
+
+ /**
* Indicates whether this GL object supports GLSL.
* @see GLContext#hasGLSL()
*/
@@ -446,29 +459,43 @@ public interface GLBase {
public boolean isTextureFormatBGRA8888Available();
- /** Provides a platform-independent way to specify the minimum swap
- interval for buffer swaps. An argument of 0 disables
- sync-to-vertical-refresh completely, while an argument of 1
- causes the application to wait until the next vertical refresh
- until swapping buffers. The default, which is platform-specific,
- is usually either 0 or 1. This function is not guaranteed to
- have an effect, and in particular only affects heavyweight
- onscreen components.
-
- @see #getSwapInterval
- @throws GLException if this context is not the current
+ /**
+ * Set the swap interval of the current context and attached <i>onscreen {@link GLDrawable}</i>.
+ * <p>
+ * <i>offscreen {@link GLDrawable}</i> are ignored and {@code false} is returned.
+ * </p>
+ * <p>
+ * The {@code interval} semantics:
+ * <ul>
+ * <li><i>0</i> disables the vertical synchronization</li>
+ * <li><i>&ge;1</i> is the number of vertical refreshes before a swap buffer occurs</li>
+ * <li><i>&lt;0</i> enables <i>late swaps to occur without synchronization to the video frame</i>, a.k.a <i>EXT_swap_control_tear</i>.
+ * If supported, the absolute value is the minimum number of
+ * video frames between buffer swaps. If not supported, the absolute value is being used, see above.
+ * </li>
+ * </ul>
+ * </p>
+ * @param interval see above
+ * @return true if the operation was successful, otherwise false
+ * @throws GLException if the context is not current.
+ * @see GLContext#setSwapInterval(int)
+ * @see #getSwapInterval()
*/
- public void setSwapInterval(int interval);
+ public void setSwapInterval(int interval) throws GLException;
- /** Provides a platform-independent way to get the swap
- interval set by {@link #setSwapInterval}. <br>
-
- If the interval is not set by {@link #setSwapInterval} yet,
- -1 is returned, indicating that the platforms default
- is being used.
-
- @see #setSwapInterval
- */
+ /**
+ * Return the current swap interval.
+ * <p>
+ * If the context has not been made current at all,
+ * the default value {@code 0} is returned.
+ * </p>
+ * <p>
+ * For a valid context w/ an <o>onscreen {@link GLDrawable}</i> the default value is {@code 1},
+ * otherwise the default value is {@code 0}.
+ * </p>
+ * @see GLContext#getSwapInterval()
+ * @see #setSwapInterval(int)
+ */
public int getSwapInterval();
/**
@@ -494,12 +521,12 @@ public interface GLBase {
* for accessing it, including which class or interface contains the
* functions.
*
- * <P>
- *
+ * <p>
* Note: it is the intent to add new extensions as quickly as possible
* to the core GL API. Therefore it is unlikely that most vendors will
* use this extension mechanism, but it is being provided for
* completeness.
+ * </p>
*/
public Object getExtension(String extensionName);
diff --git a/src/jogl/classes/com/jogamp/opengl/GLContext.java b/src/jogl/classes/com/jogamp/opengl/GLContext.java
index f68c029df..606e4b4ed 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLContext.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLContext.java
@@ -198,16 +198,19 @@ public abstract class GLContext {
/** <code>GL_ARB_ES3_compatibility</code> implementation related: Context is compatible w/ ES3. Not a cache key. See {@link #isGLES3Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
protected static final int CTX_IMPL_ES3_COMPAT = 1 << 11;
- /** <code>GL_ARB_ES3_1_compatibility</code> implementation related: Context is compatible w/ ES3. Not a cache key. See {@link #isGLES31Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
+ /** <code>GL_ARB_ES3_1_compatibility</code> implementation related: Context is compatible w/ ES 3.1. Not a cache key. See {@link #isGLES31Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
protected static final int CTX_IMPL_ES31_COMPAT = 1 << 12;
+ /** <code>GL_ARB_ES3_2_compatibility</code> implementation related: Context is compatible w/ ES 3.2. Not a cache key. See {@link #isGLES32Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
+ protected static final int CTX_IMPL_ES32_COMPAT = 1 << 13;
+
/**
* Context supports basic FBO, details see {@link #hasBasicFBOSupport()}.
* Not a cache key.
* @see #hasBasicFBOSupport()
* @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)
*/
- protected static final int CTX_IMPL_FBO = 1 << 13;
+ protected static final int CTX_IMPL_FBO = 1 << 14;
/**
* Context supports <code>OES_single_precision</code>, fp32, fixed function point (FFP) compatibility entry points,
@@ -216,7 +219,7 @@ public abstract class GLContext {
* @see #hasFP32CompatAPI()
* @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)
*/
- protected static final int CTX_IMPL_FP32_COMPAT_API = 1 << 14;
+ protected static final int CTX_IMPL_FP32_COMPAT_API = 1 << 15;
private static final ThreadLocal<GLContext> currentContext = new ThreadLocal<GLContext>();
@@ -237,7 +240,6 @@ public abstract class GLContext {
protected String ctxVersionString;
protected VersionNumberString ctxVendorVersion;
protected VersionNumber ctxGLSLVersion;
- private int currentSwapInterval;
protected GLRendererQuirks glRendererQuirks;
/** Did the drawable association changed ? see {@link GLRendererQuirks#NoSetSwapIntervalPostRetarget} */
@@ -258,7 +260,6 @@ public abstract class GLContext {
ctxGLSLVersion = VersionNumber.zeroVersion;
attachedObjects.clear();
contextHandle=0;
- currentSwapInterval = -1;
glRendererQuirks = null;
drawableRetargeted = false;
}
@@ -925,6 +926,17 @@ public abstract class GLContext {
}
/**
+ * Return true if this context is an ES3 context &ge; 3.2 or implements
+ * the extension <code>GL_ARB_ES3_2_compatibility</code>, otherwise false.
+ * <p>
+ * Includes [ GL &ge; 4.5, GL &ge; 3.1 w/ GL_ARB_ES3_2_compatibility and GLES3 &ge; 3.2 ]
+ * </p>
+ */
+ public final boolean isGLES32Compatible() {
+ return 0 != ( ctxOptions & CTX_IMPL_ES32_COMPAT ) ;
+ }
+
+ /**
* @return true if impl. is a hardware rasterizer, otherwise false.
* @see #isHardwareRasterizer(AbstractGraphicsDevice, GLProfile)
* @see GLProfile#isHardwareRasterizer()
@@ -1182,8 +1194,9 @@ public abstract class GLContext {
if( 0 != ( ctxOptions & CTX_PROFILE_ES ) ) {
final int major = ctxVersion.getMajor();
return 2 == major || 3 == major;
+ } else {
+ return false;
}
- return false;
}
/**
@@ -1246,49 +1259,55 @@ public abstract class GLContext {
}
/**
- * Set the swap interval of the current context and attached drawable.
- * @param interval Should be &ge; 0. 0 disables the vertical synchronization,
- * where &ge; 1 is the number of vertical refreshes before a swap buffer occurs.
- * A value &lt; 0 is ignored.
+ * Set the swap interval of the current context and attached <i>onscreen {@link GLDrawable}</i>.
+ * <p>
+ * <i>offscreen {@link GLDrawable}</i> are ignored and {@code false} is returned.
+ * </p>
+ * <p>
+ * The {@code interval} semantics:
+ * <ul>
+ * <li><i>0</i> disables the vertical synchronization</li>
+ * <li><i>&ge;1</i> is the number of vertical refreshes before a swap buffer occurs</li>
+ * <li><i>&lt;0</i> enables <i>late swaps to occur without synchronization to the video frame</i>, a.k.a <i>EXT_swap_control_tear</i>.
+ * If supported, the absolute value is the minimum number of
+ * video frames between buffer swaps. If not supported, the absolute value is being used, see above.
+ * </li>
+ * </ul>
+ * </p>
+ * @param interval see above
* @return true if the operation was successful, otherwise false
- *
* @throws GLException if the context is not current.
+ * @see #getSwapInterval()
*/
- public final boolean setSwapInterval(final int interval) throws GLException {
- validateCurrent();
- if(0<=interval) {
- if( !drawableRetargeted || !hasRendererQuirk(GLRendererQuirks.NoSetSwapIntervalPostRetarget) ) {
- if( setSwapIntervalImpl(interval) ) {
- currentSwapInterval = interval;
- return true;
- }
- }
- }
- return false;
+ public /* abstract */ boolean setSwapInterval(final int interval) throws GLException {
+ // FIXME: Make abstract for next version - just here to *not* break SEMVER!
+ throw new InternalError("Implemented in GLContextImpl");
}
protected boolean setSwapIntervalImpl(final int interval) {
- return false;
+ // FIXME: Remove for next version - just here to *not* break SEMVER!
+ throw new InternalError("Implemented in GLContextImpl");
}
- /** Return the current swap interval.
+
+ /**
+ * Return the current swap interval.
* <p>
* If the context has not been made current at all,
- * the default value <code>-1</code> is returned.
+ * the default value {@code 0} is returned.
* </p>
* <p>
- * For a valid context the default value is <code>1</code>
- * in case of an EGL based profile (ES1 or ES2) and <code>-1</code>
- * (undefined) for desktop.
+ * For a valid context w/ an <o>onscreen {@link GLDrawable}</i> the default value is {@code 1},
+ * otherwise the default value is {@code 0}.
* </p>
+ * @see #setSwapInterval(int)
*/
- public final int getSwapInterval() {
- return currentSwapInterval;
+ public /* abstract */ int getSwapInterval() {
+ // FIXME: Make abstract for next version - just here to *not* break SEMVER!
+ throw new InternalError("Implemented in GLContextImpl");
}
- protected final void setDefaultSwapInterval() {
- if(this.isGLES()) {
- currentSwapInterval = 1;
- } else {
- currentSwapInterval = -1;
- }
+
+ protected void setDefaultSwapInterval() {
+ // FIXME: Remove for next version - just here to *not* break SEMVER!
+ throw new InternalError("Implemented in GLContextImpl");
}
public final boolean queryMaxSwapGroups(final int[] maxGroups, final int maxGroups_offset,
@@ -1492,7 +1511,7 @@ public abstract class GLContext {
/* 0.*/ { -1 },
/* 1.*/ { 0, 1 },
/* 2.*/ { 0 },
- /* 3.*/ { 0, 1 } };
+ /* 3.*/ { 0, 1, 2 } };
public static final int getMaxMajor(final int ctxProfile) {
return ( 0 != ( CTX_PROFILE_ES & ctxProfile ) ) ? ES_VERSIONS.length-1 : GL_VERSIONS.length-1;
@@ -1613,8 +1632,14 @@ public abstract class GLContext {
( ( b8 & 0x000000FF ) << 16 ) |
( ( c16 & 0x0000FFFF ) ) ;
}
+ protected static VersionNumber decomposeBits(final int bits32, final int[] ctp) {
+ final int major = ( bits32 & 0xFF000000 ) >>> 24 ;
+ final int minor = ( bits32 & 0x00FF0000 ) >>> 16 ;
+ ctp[0] = ( bits32 & 0x0000FFFF ) ;
+ return new VersionNumber(major, minor, 0);
+ }
- private static void validateProfileBits(final int bits, final String argName) {
+ protected static void validateProfileBits(final int bits, final String argName) {
int num = 0;
if( 0 != ( CTX_PROFILE_COMPAT & bits ) ) { num++; }
if( 0 != ( CTX_PROFILE_CORE & bits ) ) { num++; }
@@ -1660,7 +1685,7 @@ public abstract class GLContext {
deviceVersionsAvailableSet.remove(devKey);
}
if (DEBUG) {
- System.err.println(getThreadName() + ": createContextARB: SET mappedVersionsAvailableSet "+devKey);
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions SET "+devKey);
System.err.println(GLContext.dumpAvailableGLVersions(null).toString());
}
}
@@ -1675,38 +1700,6 @@ public abstract class GLContext {
return r.intern();
}
- /**
- * 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}
- * @return the old mapped value
- *
- * @see #createContextARBMapVersionsAvailable
- */
- protected static Integer mapAvailableGLVersion(final AbstractGraphicsDevice device,
- final int reqMajor, final int profile, final int resMajor, final int resMinor, int resCtp)
- {
- validateProfileBits(profile, "profile");
- validateProfileBits(resCtp, "resCtp");
-
- if(FORCE_NO_FBO_SUPPORT) {
- resCtp &= ~CTX_IMPL_FBO ;
- }
- if(DEBUG) {
- System.err.println("GLContext.mapAvailableGLVersion: "+device+": "+getGLVersion(reqMajor, 0, profile, null)+" -> "+getGLVersion(resMajor, resMinor, resCtp, null));
- // Thread.dumpStack();
- }
- final String objectKey = getDeviceVersionAvailableKey(device, reqMajor, profile);
- final Integer val = Integer.valueOf(composeBits(resMajor, resMinor, resCtp));
- synchronized(deviceVersionAvailable) {
- return deviceVersionAvailable.put( objectKey, val );
- }
- }
-
protected static StringBuilder dumpAvailableGLVersions(StringBuilder sb) {
if(null == sb) {
sb = new StringBuilder();
@@ -1714,19 +1707,17 @@ public abstract class GLContext {
synchronized(deviceVersionAvailable) {
final Set<String> keys = deviceVersionAvailable.keySet();
boolean needsSeparator = false;
- for(final Iterator<String> i = keys.iterator(); i.hasNext(); ) {
+ for(final Iterator<String> keyI = keys.iterator(); keyI.hasNext(); ) {
if(needsSeparator) {
sb.append(Platform.getNewline());
}
- final String key = i.next();
- sb.append(key).append(": ");
+ final String key = keyI.next();
+ sb.append("MapGLVersions ").append(key).append(": ");
final Integer valI = deviceVersionAvailable.get(key);
if(null != valI) {
- final int bits32 = valI.intValue();
- final int major = ( bits32 & 0xFF000000 ) >>> 24 ;
- final int minor = ( bits32 & 0x00FF0000 ) >>> 16 ;
- final int ctp = ( bits32 & 0x0000FFFF ) ;
- sb.append(GLContext.getGLVersion(major, minor, ctp, null));
+ final int[] ctp = { 0 };
+ final VersionNumber version = decomposeBits(valI.intValue(), ctp);
+ GLContext.getGLVersion(sb, version, ctp[0], null);
} else {
sb.append("n/a");
}
@@ -1949,15 +1940,7 @@ public abstract class GLContext {
return isGLVersionAvailable(device, 3, GLContext.CTX_PROFILE_ES, isHardware);
}
- /**
- * Returns true if a ES3 compatible profile is available,
- * i.e. either a &ge; 4.3 context or a &ge; 3.1 context supporting <code>GL_ARB_ES3_compatibility</code>,
- * otherwise false.
- * <p>
- * Includes [ GL &ge; 4.3, GL &ge; 3.1 w/ GL_ARB_ES3_compatibility and GLES3 ]
- * </p>
- */
- public static final boolean isGLES3CompatibleAvailable(final AbstractGraphicsDevice device) {
+ private static final int getGL3ctp(final AbstractGraphicsDevice device) {
final int major[] = { 0 };
final int minor[] = { 0 };
final int ctp[] = { 0 };
@@ -1970,7 +1953,19 @@ public abstract class GLContext {
if( !ok ) {
GLContext.getAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_COMPAT, major, minor, ctp);
}
- return 0 != ( ctp[0] & CTX_IMPL_ES3_COMPAT );
+ return ctp[0];
+ }
+
+ /**
+ * Returns true if a ES3 compatible profile is available,
+ * i.e. either a &ge; 4.3 context or a &ge; 3.1 context supporting <code>GL_ARB_ES3_compatibility</code>,
+ * otherwise false.
+ * <p>
+ * Includes [ GL &ge; 4.3, GL &ge; 3.1 w/ GL_ARB_ES3_compatibility and GLES3 ]
+ * </p>
+ */
+ public static final boolean isGLES3CompatibleAvailable(final AbstractGraphicsDevice device) {
+ return 0 != ( getGL3ctp(device) & CTX_IMPL_ES3_COMPAT );
}
/**
* Returns true if a ES3 &ge; 3.1 compatible profile is available,
@@ -1981,19 +1976,18 @@ public abstract class GLContext {
* </p>
*/
public static final boolean isGLES31CompatibleAvailable(final AbstractGraphicsDevice device) {
- final int major[] = { 0 };
- final int minor[] = { 0 };
- final int ctp[] = { 0 };
- boolean ok;
-
- ok = GLContext.getAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_ES, major, minor, ctp);
- if( !ok ) {
- ok = GLContext.getAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_CORE, major, minor, ctp);
- }
- if( !ok ) {
- GLContext.getAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_COMPAT, major, minor, ctp);
- }
- return 0 != ( ctp[0] & CTX_IMPL_ES31_COMPAT );
+ return 0 != ( getGL3ctp(device) & CTX_IMPL_ES31_COMPAT );
+ }
+ /**
+ * Returns true if a ES3 &ge; 3.2 compatible profile is available,
+ * i.e. either a &ge; 4.5 context or a &ge; 3.1 context supporting <code>GL_ARB_ES3_2_compatibility</code>,
+ * otherwise false.
+ * <p>
+ * Includes [ GL &ge; 4.5, GL &ge; 3.1 w/ GL_ARB_ES3_2_compatibility and GLES3 &ge; 3.2 ]
+ * </p>
+ */
+ public static final boolean isGLES32CompatibleAvailable(final AbstractGraphicsDevice device) {
+ return 0 != ( getGL3ctp(device) & CTX_IMPL_ES32_COMPAT );
}
public static boolean isGL4bcAvailable(final AbstractGraphicsDevice device, final boolean isHardware[]) {
@@ -2016,13 +2010,8 @@ public abstract class GLContext {
return isGLVersionAvailable(device, 2, CTX_PROFILE_COMPAT, isHardware);
}
- protected static String getGLVersion(final int major, final int minor, final int ctp, final String gl_version) {
+ protected static StringBuilder getGLProfile(final StringBuilder sb, final int ctp) {
boolean needColon = false;
- final StringBuilder sb = new StringBuilder();
- sb.append(major);
- sb.append(".");
- sb.append(minor);
- sb.append(" (");
needColon = appendString(sb, "ES profile", needColon, 0 != ( CTX_PROFILE_ES & ctp ));
needColon = appendString(sb, "Compat profile", needColon, 0 != ( CTX_PROFILE_COMPAT & ctp ));
needColon = appendString(sb, "Core profile", needColon, 0 != ( CTX_PROFILE_CORE & ctp ));
@@ -2035,6 +2024,7 @@ public abstract class GLContext {
needColon = appendString(sb, "ES2", needColon, 0 != ( CTX_IMPL_ES2_COMPAT & ctp ));
needColon = appendString(sb, "ES3", needColon, 0 != ( CTX_IMPL_ES3_COMPAT & ctp ));
needColon = appendString(sb, "ES31", needColon, 0 != ( CTX_IMPL_ES31_COMPAT & ctp ));
+ needColon = appendString(sb, "ES32", needColon, 0 != ( CTX_IMPL_ES32_COMPAT & ctp ));
needColon = appendString(sb, "FP32", needColon, 0 != ( CTX_IMPL_FP32_COMPAT_API & ctp ));
needColon = false;
}
@@ -2045,12 +2035,26 @@ public abstract class GLContext {
} else {
needColon = appendString(sb, "hardware", needColon, true);
}
+ return sb;
+ }
+ protected static StringBuilder getGLVersion(final StringBuilder sb, final VersionNumber version, final int ctp, final String gl_version) {
+ return getGLVersion(sb, version.getMajor(), version.getMinor(), ctp, gl_version);
+ }
+ protected static StringBuilder getGLVersion(final StringBuilder sb, final int major, final int minor, final int ctp, final String gl_version) {
+ sb.append(major);
+ sb.append(".");
+ sb.append(minor);
+ sb.append(" (");
+ getGLProfile(sb, ctp);
sb.append(")");
if(null!=gl_version) {
sb.append(" - ");
sb.append(gl_version);
}
- return sb.toString();
+ return sb;
+ }
+ protected static String getGLVersion(final int major, final int minor, final int ctp, final String gl_version) {
+ return getGLVersion(new StringBuilder(), major, minor, ctp, gl_version).toString();
}
//
diff --git a/src/jogl/classes/com/jogamp/opengl/GLDrawable.java b/src/jogl/classes/com/jogamp/opengl/GLDrawable.java
index c801ba463..a4a9d2e06 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLDrawable.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLDrawable.java
@@ -134,7 +134,7 @@ public interface GLDrawable extends NativeSurfaceHolder {
public void setRealized(boolean realized);
/**
- * Returns <code>true</code> if this drawable is realized, otherwise <code>true</code>.
+ * Returns <code>true</code> if this drawable is realized, otherwise <code>false</code>.
* <p>
* A drawable can be realized and unrealized via {@link #setRealized(boolean)}.
* </p>
diff --git a/src/jogl/classes/com/jogamp/opengl/GLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/GLDrawableFactory.java
index 7d78e3409..51da34ce0 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLDrawableFactory.java
@@ -421,6 +421,18 @@ public abstract class GLDrawableFactory {
public abstract GLRendererQuirks getRendererQuirks(AbstractGraphicsDevice device, final GLProfile glp);
/**
+ * Method returns {@code true} if underlying implementation may support native desktop OpenGL,
+ * otherwise {@code false}.
+ */
+ public abstract boolean hasOpenGLDesktopSupport();
+
+ /**
+ * Method returns {@code true} if underlying implementation may support native embedded OpenGL ES,
+ * otherwise {@code false}.
+ */
+ public abstract boolean hasOpenGLESSupport();
+
+ /**
* Returns the sole GLDrawableFactory instance for the desktop (X11, WGL, ..) if exist or null
*/
public static GLDrawableFactory getDesktopFactory() {
diff --git a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
index 1bf8071ea..23e7dec31 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
@@ -36,6 +36,7 @@ public class GLExtensions {
public static final String VERSION_1_5 = "GL_VERSION_1_5";
public static final String VERSION_2_0 = "GL_VERSION_2_0";
+ public static final String GL_KHR_debug = "GL_KHR_debug";
public static final String ARB_debug_output = "GL_ARB_debug_output";
public static final String AMD_debug_output = "GL_AMD_debug_output";
@@ -53,6 +54,7 @@ public class GLExtensions {
public static final String ARB_ES2_compatibility = "GL_ARB_ES2_compatibility";
public static final String ARB_ES3_compatibility = "GL_ARB_ES3_compatibility";
public static final String ARB_ES3_1_compatibility = "GL_ARB_ES3_1_compatibility";
+ public static final String ARB_ES3_2_compatibility = "GL_ARB_ES3_2_compatibility";
public static final String EXT_abgr = "GL_EXT_abgr";
public static final String OES_rgb8_rgba8 = "GL_OES_rgb8_rgba8";
diff --git a/src/jogl/classes/com/jogamp/opengl/GLProfile.java b/src/jogl/classes/com/jogamp/opengl/GLProfile.java
index a36a21ad5..e19535e5d 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLProfile.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLProfile.java
@@ -39,6 +39,7 @@ package com.jogamp.opengl;
import jogamp.opengl.Debug;
import jogamp.opengl.GLDrawableFactoryImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
import jogamp.opengl.DesktopGLDynamicLookupHelper;
import com.jogamp.common.ExceptionUtils;
@@ -217,7 +218,7 @@ public class GLProfile {
public Object run() {
Platform.initSingleton();
- if(TempJarCache.isInitialized()) {
+ if( TempJarCache.isInitialized(true) ) {
final ClassLoader cl = GLProfile.class.getClassLoader();
final String newtDebugClassName = "jogamp.newt.Debug";
final Class<?>[] classesFromJavaJars = new Class<?>[] { jogamp.nativewindow.Debug.class, jogamp.opengl.Debug.class, null };
@@ -242,7 +243,7 @@ public class GLProfile {
initLock.unlock();
}
if(DEBUG) {
- if( justInitialized && ( hasGL234Impl || hasGLES1Impl || hasGLES3Impl ) ) {
+ if( justInitialized && ( hasGL234Impl || hasGL234OnEGLImpl || hasGLES1Impl || hasGLES3Impl ) ) {
System.err.println(JoglVersion.getDefaultOpenGLInfo(defaultDevice, null, true));
}
}
@@ -1629,6 +1630,7 @@ public class GLProfile {
private static /*final*/ boolean hasEGLFactory;
private static /*final*/ boolean hasGLES3Impl;
private static /*final*/ boolean hasGLES1Impl;
+ private static /*final*/ boolean hasGL234OnEGLImpl;
private static /*final*/ Constructor<?> ctorGL234Impl;
private static /*final*/ Constructor<?> ctorGLES3Impl;
private static /*final*/ Constructor<?> ctorGLES1Impl;
@@ -1681,6 +1683,7 @@ public class GLProfile {
ctorGL234ProcAddr = null;
}
}
+ hasGL234OnEGLImpl = hasGL234Impl;
// depends on hasEGLFactory
{
@@ -1745,10 +1748,9 @@ public class GLProfile {
try {
desktopFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GL2);
if(null != desktopFactory) {
- final DesktopGLDynamicLookupHelper glLookupHelper = (DesktopGLDynamicLookupHelper) desktopFactory.getGLDynamicLookupHelper(GL2);
- if(null!=glLookupHelper) {
- hasDesktopGLFactory = glLookupHelper.isLibComplete() && hasGL234Impl;
- }
+ final DesktopGLDynamicLookupHelper glLookupHelper = (DesktopGLDynamicLookupHelper) desktopFactory.getGLDynamicLookupHelper(2, GLContext.CTX_PROFILE_COMPAT);
+ hasGL234Impl = null!=glLookupHelper && glLookupHelper.isLibComplete() && hasGL234Impl;
+ hasDesktopGLFactory = hasGL234Impl;
}
} catch (final LinkageError le) {
t=le;
@@ -1780,10 +1782,14 @@ public class GLProfile {
try {
eglFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GLES2);
if(null != eglFactory) {
- hasEGLFactory = true;
- // update hasGLES1Impl, hasGLES3Impl based on EGL
- hasGLES3Impl = null!=eglFactory.getGLDynamicLookupHelper(GLES2) && hasGLES3Impl;
- hasGLES1Impl = null!=eglFactory.getGLDynamicLookupHelper(GLES1) && hasGLES1Impl;
+ // update hasGLES1Impl, hasGLES3Impl, hasGL234OnEGLImpl based on library completion
+ final GLDynamicLookupHelper es2DynLookup = eglFactory.getGLDynamicLookupHelper(2, GLContext.CTX_PROFILE_ES);
+ final GLDynamicLookupHelper es1DynLookup = eglFactory.getGLDynamicLookupHelper(1, GLContext.CTX_PROFILE_ES);
+ final GLDynamicLookupHelper glXDynLookup = eglFactory.getGLDynamicLookupHelper(3, GLContext.CTX_PROFILE_CORE);
+ hasGLES3Impl = null!=es2DynLookup && es2DynLookup.isLibComplete() && hasGLES3Impl;
+ hasGLES1Impl = null!=es1DynLookup && es1DynLookup.isLibComplete() && hasGLES1Impl;
+ hasGL234OnEGLImpl = null!=glXDynLookup && glXDynLookup.isLibComplete() && hasGL234OnEGLImpl;
+ hasEGLFactory = hasGLES3Impl || hasGLES1Impl || hasGL234OnEGLImpl;
}
} catch (final LinkageError le) {
t=le;
@@ -1803,6 +1809,8 @@ public class GLProfile {
final AbstractGraphicsDevice defaultEGLDevice;
if(null == eglFactory) {
+ hasEGLFactory = false;
+ hasGL234OnEGLImpl= false;
hasGLES3Impl = false;
hasGLES1Impl = false;
defaultEGLDevice = null;
@@ -1843,6 +1851,7 @@ public class GLProfile {
System.err.println("GLProfile.init hasEGLFactory "+hasEGLFactory);
System.err.println("GLProfile.init hasGLES1Impl "+hasGLES1Impl);
System.err.println("GLProfile.init hasGLES3Impl "+hasGLES3Impl);
+ System.err.println("GLProfile.init hasGL234OnEGLImpl "+hasGL234OnEGLImpl);
System.err.println("GLProfile.init defaultDevice "+defaultDevice);
System.err.println("GLProfile.init defaultDevice Desktop "+defaultDesktopDevice);
System.err.println("GLProfile.init defaultDevice EGL "+defaultEGLDevice);
@@ -1887,7 +1896,9 @@ public class GLProfile {
return null != map.get(GL_DEFAULT);
}
+ HashMap<String, GLProfile> mappedDesktopProfiles = null;
boolean addedDesktopProfile = false;
+ HashMap<String, GLProfile> mappedEGLProfiles = null;
boolean addedEGLProfile = false;
final boolean deviceIsDesktopCompatible = hasDesktopGLFactory && desktopFactory.getIsDeviceCompatible(device);
@@ -1906,21 +1917,23 @@ public class GLProfile {
if(null != sharedResourceThread) {
initLock.removeOwner(sharedResourceThread);
}
- if (DEBUG) {
- System.err.println("GLProfile.initProfilesForDevice: "+device+": desktop Shared Ctx "+desktopSharedCtxAvail);
- }
- if(!desktopSharedCtxAvail) {
- hasDesktopGLFactory = false;
- } else if( !GLContext.getAvailableGLVersionsSet(device) ) {
- throw new InternalError("Available GLVersions not set");
+ if( desktopSharedCtxAvail ) {
+ if( !GLContext.getAvailableGLVersionsSet(device) ) {
+ throw new InternalError("Available GLVersions not set for "+device);
+ }
+ mappedDesktopProfiles = computeProfileMap(device, false /* desktopCtxUndef*/, false /* esCtxUndef */);
+ addedDesktopProfile = mappedDesktopProfiles.size() > 0;
+ if (DEBUG) {
+ System.err.println("GLProfile.initProfilesForDevice: "+device+": desktop Shared Ctx "+desktopSharedCtxAvail+
+ ", profiles: "+(addedDesktopProfile ? mappedDesktopProfiles.size() : 0));
+ }
}
- addedDesktopProfile = computeProfileMap(device, false /* desktopCtxUndef*/, false /* esCtxUndef */);
}
final boolean deviceIsEGLCompatible = hasEGLFactory && eglFactory.getIsDeviceCompatible(device);
// also test GLES1, GLES2 and GLES3 on desktop, since we have implementations / emulations available.
- if( deviceIsEGLCompatible && ( hasGLES3Impl || hasGLES1Impl ) ) {
+ if( deviceIsEGLCompatible ) {
// 1st pretend we have all EGL profiles ..
computeProfileMap(device, true /* desktopCtxUndef*/, true /* esCtxUndef */);
@@ -1934,18 +1947,17 @@ public class GLProfile {
if(null != sharedResourceThread) {
initLock.removeOwner(sharedResourceThread);
}
- if(!eglSharedCtxAvail) {
- // Remark: On Windows there is a libEGL.dll delivered w/ Chrome 15.0.874.121m and Firefox 8.0.1
- // but it seems even EGL.eglInitialize(eglDisplay, null, null)
- // fails in some scenarios (eg VirtualBox 4.1.6) w/ EGL error 0x3001 (EGL_NOT_INITIALIZED).
- hasEGLFactory = false;
- hasGLES3Impl = false;
- hasGLES1Impl = false;
+ if( eglSharedCtxAvail ) {
+ if( !GLContext.getAvailableGLVersionsSet(device) ) {
+ throw new InternalError("Available GLVersions not set for "+device);
+ }
+ mappedEGLProfiles = computeProfileMap(device, false /* desktopCtxUndef*/, false /* esCtxUndef */);
+ addedEGLProfile = mappedEGLProfiles.size() > 0;
}
if (DEBUG) {
- System.err.println("GLProfile.initProfilesForDevice: "+device+": egl Shared Ctx "+eglSharedCtxAvail);
+ System.err.println("GLProfile.initProfilesForDevice: "+device+": egl Shared Ctx "+eglSharedCtxAvail+
+ ", profiles: "+(addedEGLProfile ? mappedEGLProfiles.size() : 0));
}
- addedEGLProfile = computeProfileMap(device, false /* desktopCtxUndef*/, false /* esCtxUndef */);
}
if( !addedDesktopProfile && !addedEGLProfile ) {
@@ -1959,13 +1971,22 @@ public class GLProfile {
System.err.println("GLProfile: hasGLES1Impl "+hasGLES1Impl);
System.err.println("GLProfile: hasGLES3Impl "+hasGLES3Impl);
}
+ } else {
+ final HashMap<String, GLProfile> mappedAllProfiles = new HashMap<String, GLProfile>();
+ if( addedEGLProfile ) {
+ mappedAllProfiles.putAll(mappedEGLProfiles);
+ }
+ if( addedDesktopProfile ) {
+ mappedAllProfiles.putAll(mappedDesktopProfiles);
+ }
+ setProfileMap(device, mappedAllProfiles); // union
}
GLContext.setAvailableGLVersionsSet(device, true);
if (DEBUG) {
- System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": added profile(s): desktop "+addedDesktopProfile+", egl "+addedEGLProfile);
- System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": "+glAvailabilityToString(device));
+ System.err.println("GLProfile.initProfilesForDevice: "+device.getUniqueID()+": added profile(s): desktop "+addedDesktopProfile+", egl "+addedEGLProfile);
+ System.err.println("GLProfile.initProfilesForDevice: "+device.getUniqueID()+": "+glAvailabilityToString(device));
if(addedDesktopProfile) {
dumpGLInfo(desktopFactory, device);
final List<GLCapabilitiesImmutable> availCaps = desktopFactory.getAvailableCapabilities(device);
@@ -1996,6 +2017,9 @@ public class GLProfile {
}
} else {
System.err.println("GLProfile.dumpGLInfo: shared context n/a");
+ System.err.println(device.getClass().getSimpleName()+"[type "+
+ device.getType()+", connection "+device.getConnection()+"]:");
+ System.err.println(GLProfile.glAvailabilityToString(device, null, "\t", 1).toString());
}
}
@@ -2026,9 +2050,9 @@ public class GLProfile {
sb.append("]");
}
- private static boolean computeProfileMap(final AbstractGraphicsDevice device, final boolean desktopCtxUndef, final boolean esCtxUndef) {
+ private static HashMap<String, GLProfile> computeProfileMap(final AbstractGraphicsDevice device, final boolean desktopCtxUndef, final boolean esCtxUndef) {
if (DEBUG) {
- System.err.println("GLProfile.init map "+device.getConnection()+", desktopCtxUndef "+desktopCtxUndef+", esCtxUndef "+esCtxUndef);
+ System.err.println("GLProfile.init map "+device.getUniqueID()+", desktopCtxUndef "+desktopCtxUndef+", esCtxUndef "+esCtxUndef);
}
final boolean isHardwareRasterizer[] = new boolean[1];
GLProfile defaultGLProfileAny = null;
@@ -2050,22 +2074,22 @@ public class GLProfile {
}
_mappedProfiles.put(profile, glProfile);
if (DEBUG) {
- System.err.println("GLProfile.init map "+glProfile+" on device "+device.getConnection());
+ System.err.println("GLProfile.init map "+glProfile+" on device "+device.getUniqueID());
}
if( null == defaultGLProfileHW && isHardwareRasterizer[0] ) {
defaultGLProfileHW=glProfile;
if (DEBUG) {
- System.err.println("GLProfile.init map defaultHW "+glProfile+" on device "+device.getConnection());
+ System.err.println("GLProfile.init map defaultHW "+glProfile+" on device "+device.getUniqueID());
}
} else if( null == defaultGLProfileAny ) {
defaultGLProfileAny=glProfile;
if (DEBUG) {
- System.err.println("GLProfile.init map defaultAny "+glProfile+" on device "+device.getConnection());
+ System.err.println("GLProfile.init map defaultAny "+glProfile+" on device "+device.getUniqueID());
}
}
} else {
if (DEBUG) {
- System.err.println("GLProfile.init map *** no mapping for "+profile+" on device "+device.getConnection());
+ System.err.println("GLProfile.init map *** no mapping for "+profile+" on device "+device.getUniqueID());
}
}
}
@@ -2075,13 +2099,14 @@ public class GLProfile {
_mappedProfiles.put(GL_DEFAULT, defaultGLProfileAny);
}
setProfileMap(device, _mappedProfiles);
- return _mappedProfiles.size() > 0;
+ return _mappedProfiles;
}
/**
* Returns the profile implementation
*/
private static String computeProfileImpl(final AbstractGraphicsDevice device, final String profile, final boolean desktopCtxUndef, final boolean esCtxUndef, final boolean isHardwareRasterizer[]) {
+ final boolean hasAnyGL234Impl = hasGL234Impl || hasGL234OnEGLImpl;
final boolean hardwareRasterizer[] = new boolean[1];
if ( GL2ES1 == profile ) {
final boolean gles1Available;
@@ -2093,7 +2118,7 @@ public class GLProfile {
gles1Available = false;
gles1HWAvailable = false;
}
- if(hasGL234Impl) {
+ if( hasAnyGL234Impl ) {
final boolean gl3bcAvailable = GLContext.isGL3bcAvailable(device, hardwareRasterizer);
final boolean gl3bcHWAvailable = gl3bcAvailable && hardwareRasterizer[0] ;
final boolean gl2Available = GLContext.isGL2Available(device, hardwareRasterizer);
@@ -2132,7 +2157,7 @@ public class GLProfile {
gles3Available = false;
gles3HWAvailable = false;
}
- if( hasGL234Impl ) {
+ if( hasAnyGL234Impl ) {
final boolean gl4bcAvailable = GLContext.isGL4bcAvailable(device, hardwareRasterizer);
final boolean gl4bcHWAvailable = gl4bcAvailable && hardwareRasterizer[0] ;
final boolean gl3Available = GLContext.isGL3Available(device, hardwareRasterizer);
@@ -2179,7 +2204,7 @@ public class GLProfile {
final boolean es3HardwareRasterizer[] = new boolean[1];
final boolean gles3Available = hasGLES3Impl && ( esCtxUndef || GLContext.isGLES3Available(device, es3HardwareRasterizer) );
final boolean gles3HWAvailable = gles3Available && es3HardwareRasterizer[0] ;
- if( hasGL234Impl ) {
+ if( hasAnyGL234Impl ) {
final boolean gl4bcAvailable = GLContext.isGL4bcAvailable(device, hardwareRasterizer);
final boolean gl4bcHWAvailable = gl4bcAvailable && hardwareRasterizer[0] ;
final boolean glAnyHWAvailable = gl4bcHWAvailable ||
@@ -2200,7 +2225,7 @@ public class GLProfile {
}
}
} else if(GL2GL3 == profile) {
- if(hasGL234Impl) {
+ if( hasAnyGL234Impl ) {
final boolean gl4Available = GLContext.isGL4Available(device, hardwareRasterizer);
final boolean gl4HWAvailable = gl4Available && hardwareRasterizer[0] ;
final boolean gl3Available = GLContext.isGL3Available(device, hardwareRasterizer);
@@ -2232,15 +2257,15 @@ public class GLProfile {
return GL2;
}
}
- } else if(GL4bc == profile && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL4bcAvailable(device, isHardwareRasterizer))) {
+ } else if(GL4bc == profile && hasAnyGL234Impl && ( desktopCtxUndef || GLContext.isGL4bcAvailable(device, isHardwareRasterizer))) {
return desktopCtxUndef ? GL4bc : GLContext.getAvailableGLProfileName(device, 4, GLContext.CTX_PROFILE_COMPAT);
- } else if(GL4 == profile && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL4Available(device, isHardwareRasterizer))) {
+ } else if(GL4 == profile && hasAnyGL234Impl && ( desktopCtxUndef || GLContext.isGL4Available(device, isHardwareRasterizer))) {
return desktopCtxUndef ? GL4 : GLContext.getAvailableGLProfileName(device, 4, GLContext.CTX_PROFILE_CORE);
- } else if(GL3bc == profile && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL3bcAvailable(device, isHardwareRasterizer))) {
+ } else if(GL3bc == profile && hasAnyGL234Impl && ( desktopCtxUndef || GLContext.isGL3bcAvailable(device, isHardwareRasterizer))) {
return desktopCtxUndef ? GL3bc : GLContext.getAvailableGLProfileName(device, 3, GLContext.CTX_PROFILE_COMPAT);
- } else if(GL3 == profile && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL3Available(device, isHardwareRasterizer))) {
+ } else if(GL3 == profile && hasAnyGL234Impl && ( desktopCtxUndef || GLContext.isGL3Available(device, isHardwareRasterizer))) {
return desktopCtxUndef ? GL3 : GLContext.getAvailableGLProfileName(device, 3, GLContext.CTX_PROFILE_CORE);
- } else if(GL2 == profile && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL2Available(device, isHardwareRasterizer))) {
+ } else if(GL2 == profile && hasAnyGL234Impl && ( desktopCtxUndef || GLContext.isGL2Available(device, isHardwareRasterizer))) {
return desktopCtxUndef ? GL2 : GLContext.getAvailableGLProfileName(device, 2, GLContext.CTX_PROFILE_COMPAT);
} else if(GLES3 == profile && hasGLES3Impl && ( esCtxUndef || GLContext.isGLES3Available(device, isHardwareRasterizer))) {
return esCtxUndef ? GLES3 : GLContext.getAvailableGLProfileName(device, 3, GLContext.CTX_PROFILE_ES);
diff --git a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
index 55c02d92a..7898566f3 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
@@ -287,6 +287,7 @@ public class GLRendererQuirks {
* <li>EGL_VERSION 1.4</li>
* <li>GL_VENDOR NVIDIA Corporation</li>
* <li>GL_VERSION OpenGL ES 3.0 331.38 (probably w/ 1st NV EGL lib on x86)</li>
+ * <li>GL_VERSION OpenGL ES 3.1 NVIDIA 355.06 (unstable)</li>
* <li>Platform X11</li>
* <li>CPU Family {@link Platform.CPUFamily#X86}</li>
* </ul>
@@ -393,7 +394,7 @@ public class GLRendererQuirks {
* </p>
*/
public static final int NeedSharedObjectSync = 20;
-
+
/**
* No reliable ARB_create_context implementation,
* even if driver claims otherwise.
@@ -401,8 +402,8 @@ public class GLRendererQuirks {
* Some drivers wrongly claim to support ARB_create_context.
* However, the creation of such context fails:
* <pre>
- * com.jogamp.opengl.GLException: AWT-EventQueue-0: WindowsWGLContex.createContextImpl ctx !ARB, profile > GL2
- * requested (OpenGL >= 3.0.1). Requested: GLProfile[GL3bc/GL3bc.hw], current: 2.1 (Compat profile, FBO, hardware)
+ * com.jogamp.opengl.GLException: AWT-EventQueue-0: WindowsWGLContex.createContextImpl ctx !ARB, profile > GL2
+ * requested (OpenGL >= 3.0.1). Requested: GLProfile[GL3bc/GL3bc.hw], current: 2.1 (Compat profile, FBO, hardware)
* - 2.1.8787
* </pre>
* </p>
diff --git a/src/jogl/classes/com/jogamp/opengl/GLUniformData.java b/src/jogl/classes/com/jogamp/opengl/GLUniformData.java
index 44f7f29c7..55a2e0cf1 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLUniformData.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLUniformData.java
@@ -84,6 +84,7 @@ public class GLUniformData {
public IntBuffer intBufferValue() { return (IntBuffer)data; };
public FloatBuffer floatBufferValue() { return (FloatBuffer)data; };
+ @SuppressWarnings("deprecation")
public StringBuilder toString(StringBuilder sb) {
if(null == sb) {
sb = new StringBuilder();
diff --git a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
index 7589b3776..560d99025 100644
--- a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
+++ b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
@@ -144,8 +144,7 @@ public class JoglVersion extends JogampVersion {
}
sb.append(VersionUtil.SEPERATOR).append(Platform.getNewline());
- sb.append(device.getClass().getSimpleName()).append("[type ")
- .append(device.getType()).append(", connection ").append(device.getConnection()).append("]: ").append(Platform.getNewline());
+ sb.append(device.toString()).append(':').append(Platform.getNewline());
if( withAvailabilityInfo ) {
GLProfile.glAvailabilityToString(device, sb, "\t", 1);
}
diff --git a/src/jogl/classes/com/jogamp/opengl/awt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/awt/GLCanvas.java
index 5f59f7e6d..6af7bcda4 100644
--- a/src/jogl/classes/com/jogamp/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/com/jogamp/opengl/awt/GLCanvas.java
@@ -157,12 +157,12 @@ import jogamp.opengl.awt.AWTTilePainter;
* <li><pre>sun.awt.noerasebackground=true</pre></li>
* </ul>
*
- * <p>
- * <a name="contextSharing"><h5>OpenGL Context Sharing</h5></a>
+ * <h5><a name="contextSharing">OpenGL Context Sharing</a></h5>
+ *
* To share a {@link GLContext} see the following note in the documentation overview:
* <a href="../../../../overview-summary.html#SHARING">context sharing</a>
* as well as {@link GLSharedContextSetter}.
- * </p>
+ *
*/
@SuppressWarnings("serial")
diff --git a/src/jogl/classes/com/jogamp/opengl/awt/GLJPanel.java b/src/jogl/classes/com/jogamp/opengl/awt/GLJPanel.java
index 5bf4c106c..20dc71958 100644
--- a/src/jogl/classes/com/jogamp/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/com/jogamp/opengl/awt/GLJPanel.java
@@ -98,6 +98,7 @@ import jogamp.opengl.awt.AWTTilePainter;
import jogamp.opengl.awt.Java2D;
import jogamp.opengl.util.glsl.GLSLTextureRaster;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.common.util.PropertyAccess;
import com.jogamp.common.util.awt.AWTEDTExecutor;
import com.jogamp.common.util.locks.LockFactory;
@@ -395,7 +396,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
*/
public final boolean initializeBackend(final boolean offthread) {
if( offthread ) {
- new Thread(getThreadName()+"-GLJPanel_Init") {
+ new InterruptSource.Thread(null, null, getThreadName()+"-GLJPanel_Init") {
public void run() {
if( !isInitialized ) {
initializeBackendImpl();
diff --git a/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java b/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java
index 8f033a8b8..5e6338b5c 100644
--- a/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java
@@ -47,7 +47,7 @@ public final class CgDynamicLibraryBundleInfo implements DynamicLibraryBundleInf
public Object run() {
Platform.initSingleton();
- if(TempJarCache.isInitialized()) {
+ if( TempJarCache.isInitialized(true) ) {
// only: jogl-cg.jar -> jogl-cg-natives-<os.and.arch>.jar [atomic JAR files only]
JNILibLoaderBase.addNativeJarLibs(new Class<?>[] { jogamp.opengl.cg.CgPackagePlaceholder.class }, null);
}
@@ -99,6 +99,16 @@ public final class CgDynamicLibraryBundleInfo implements DynamicLibraryBundleInf
}
@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>>();
final List<String> libsCg = new ArrayList<String>();
diff --git a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
index 7f630f9d5..73244cb13 100644
--- a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
@@ -28,6 +28,7 @@
package com.jogamp.opengl.math;
import java.nio.FloatBuffer;
+import java.util.Locale;
import com.jogamp.opengl.GLException;
@@ -1738,7 +1739,6 @@ public final class FloatUtil {
* @param a 4x4 matrix in column-major order
* @param b 4x4 matrix in column-major order
* @param d result a*b in column-major order
- * @deprecated use on of the float[] variants
*/
public static void multMatrix(final FloatBuffer a, final FloatBuffer b, final float[] d) {
final int a_off = a.position();
@@ -1758,7 +1758,6 @@ public final class FloatUtil {
* Multiply matrix: [a] = [a] x [b]
* @param a 4x4 matrix in column-major order (also result)
* @param b 4x4 matrix in column-major order
- * @deprecated use on of the float[] variants
*/
public static void multMatrix(final FloatBuffer a, final FloatBuffer b) {
final int a_off = a.position();
@@ -1831,7 +1830,6 @@ public final class FloatUtil {
* @param m_in 4x4 matrix in column-major order
* @param v_in 4-component column-vector
* @param v_out m_in * v_in
- * @deprecated use on of the float[] variants
*/
public static void multMatrixVec(final FloatBuffer m_in, final float[] v_in, final float[] v_out) {
final int m_in_off = m_in.position();
@@ -1900,7 +1898,6 @@ public final class FloatUtil {
* @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
* @param row row number to print
* @return matrix row string representation
- * @deprecated use on of the float[] variants
*/
public static StringBuilder matrixRowToString(StringBuilder sb, final String f,
final FloatBuffer a, final int aOffset,
@@ -1911,11 +1908,11 @@ public final class FloatUtil {
final int a0 = aOffset + a.position();
if(rowMajorOrder) {
for(int c=0; c<columns; c++) {
- sb.append( String.format( f+" ", a.get( a0 + row*columns + c ) ) );
+ sb.append( String.format((Locale)null, f+" ", a.get( a0 + row*columns + c ) ) );
}
} else {
for(int r=0; r<columns; r++) {
- sb.append( String.format( f+" ", a.get( a0 + row + r*rows ) ) );
+ sb.append( String.format((Locale)null, f+" ", a.get( a0 + row + r*rows ) ) );
}
}
return sb;
@@ -1939,11 +1936,11 @@ public final class FloatUtil {
}
if(rowMajorOrder) {
for(int c=0; c<columns; c++) {
- sb.append( String.format( f+" ", a[ aOffset + row*columns + c ] ) );
+ sb.append( String.format((Locale)null, f+" ", a[ aOffset + row*columns + c ] ) );
}
} else {
for(int r=0; r<columns; r++) {
- sb.append( String.format( f+" ", a[ aOffset + row + r*rows ] ) );
+ sb.append( String.format((Locale)null, f+" ", a[ aOffset + row + r*rows ] ) );
}
}
return sb;
@@ -1959,7 +1956,6 @@ public final class FloatUtil {
* @param columns
* @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
* @return matrix string representation
- * @deprecated use on of the float[] variants
*/
public static StringBuilder matrixToString(StringBuilder sb, final String rowPrefix, final String f,
final FloatBuffer a, final int aOffset, final int rows, final int columns, final boolean rowMajorOrder) {
@@ -2012,7 +2008,6 @@ public final class FloatUtil {
* @param columns
* @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
* @return side by side representation
- * @deprecated use on of the float[] variants
*/
public static StringBuilder matrixToString(StringBuilder sb, final String rowPrefix, final String f,
final FloatBuffer a, final int aOffset, final FloatBuffer b, final int bOffset,
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
index 58b5bbcb9..5e90c4035 100644
--- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
+++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
@@ -62,6 +62,7 @@ import jogamp.opengl.GLDrawableHelper;
import jogamp.opengl.GLDrawableImpl;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Canvas;
@@ -113,13 +114,12 @@ public class GLCanvas extends Canvas implements GLAutoDrawable, GLSharedContextS
private final GLCapabilitiesImmutable capsRequested;
private final GLCapabilitiesChooser capsChooser;
- private volatile Rectangle clientArea;
+ private volatile Rectangle clientAreaPixels, clientAreaWindow;
private volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
private volatile GLContextImpl context; // volatile: avoid locking for read-only access
/* Native window surface */
private final boolean useX11GTK;
- private volatile long gdkWindow; // either GDK child window ..
private volatile long x11Window; // .. or X11 child window (for GL rendering)
private final AbstractGraphicsScreen screen;
@@ -153,7 +153,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable, GLSharedContextS
@Override
public void run() {
if (sendReshape) {
- helper.reshape(GLCanvas.this, 0, 0, clientArea.width, clientArea.height);
+ helper.reshape(GLCanvas.this, 0, 0, clientAreaPixels.width, clientAreaPixels.height);
sendReshape = false;
}
helper.display(GLCanvas.this);
@@ -242,9 +242,6 @@ public class GLCanvas extends Canvas implements GLAutoDrawable, GLSharedContextS
if( 0 != x11Window) {
SWTAccessor.destroyX11Window(screen.getDevice(), x11Window);
x11Window = 0;
- } else if( 0 != gdkWindow) {
- SWTAccessor.destroyGDKWindow(gdkWindow);
- gdkWindow = 0;
}
screen.getDevice().close();
} catch (final Throwable re) {
@@ -348,7 +345,8 @@ public class GLCanvas extends Canvas implements GLAutoDrawable, GLSharedContextS
SWTAccessor.setRealized(this, true);
- clientArea = GLCanvas.this.getClientArea();
+ clientAreaPixels = SWTAccessor.getClientAreaInPixels(this);
+ clientAreaWindow = getClientArea();
/* Get the nativewindow-Graphics Device associated with this control (which is determined by the parent Composite).
* Note: SWT is owner of the native handle, hence closing operation will be a NOP. */
@@ -376,11 +374,14 @@ public class GLCanvas extends Canvas implements GLAutoDrawable, GLSharedContextS
this.capsChooser = capsChooser;
// post create .. when ready
- gdkWindow = 0;
x11Window = 0;
drawable = null;
context = null;
+ // Bug 1362 fix or workaround: Seems SWT/GTK3 at least performs lazy initialization
+ // Minimal action required: setBackground of the parent canvas before reparenting!
+ setBackground(new Color(parent.getDisplay(), 255, 255, 255));
+
final Listener listener = new Listener () {
@Override
public void handleEvent (final Event event) {
@@ -421,17 +422,17 @@ public class GLCanvas extends Canvas implements GLAutoDrawable, GLSharedContextS
@Override
public final int getSurfaceWidth(final ProxySurface s) {
- return clientArea.width;
+ return clientAreaPixels.width;
}
@Override
public final int getSurfaceHeight(final ProxySurface s) {
- return clientArea.height;
+ return clientAreaPixels.height;
}
@Override
public String toString() {
- return "SWTCanvasUpstreamSurfaceHook[upstream: "+GLCanvas.this.toString()+", "+clientArea.width+"x"+clientArea.height+"]";
+ return "SWTCanvasUpstreamSurfaceHook[upstream: "+GLCanvas.this.toString()+", "+clientAreaPixels.width+"x"+clientAreaPixels.height+" [pixel], "+clientAreaWindow.width+"x"+clientAreaWindow.height+" [win]]";
}
/**
@@ -447,25 +448,27 @@ public class GLCanvas extends Canvas implements GLAutoDrawable, GLSharedContextS
};
protected final void updateSizeCheck() {
- final Rectangle oClientArea = clientArea;
- final Rectangle nClientArea = GLCanvas.this.getClientArea();
- if ( nClientArea != null &&
- ( nClientArea.width != oClientArea.width || nClientArea.height != oClientArea.height )
+ final Rectangle oClientAreaPixels = clientAreaPixels;
+ final Rectangle nClientAreaPixels = SWTAccessor.getClientAreaInPixels(this);
+
+ if ( nClientAreaPixels != null &&
+ ( nClientAreaPixels.width != oClientAreaPixels.width || nClientAreaPixels.height != oClientAreaPixels.height )
) {
- clientArea = nClientArea; // write back new value
+ clientAreaPixels = nClientAreaPixels; // write back new value
+ clientAreaWindow = getClientArea();
final GLDrawableImpl _drawable = drawable;
final boolean drawableOK = null != _drawable && _drawable.isRealized();
if(DEBUG) {
final long dh = drawableOK ? _drawable.getHandle() : 0;
- System.err.println(getThreadName()+": GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+nClientArea.x+"/"+nClientArea.y+" "+nClientArea.width+"x"+nClientArea.height+" - drawableHandle "+toHexString(dh));
+ System.err.println(getThreadName()+": GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+nClientAreaPixels.x+"/"+nClientAreaPixels.y+" "+nClientAreaPixels.width+"x"+nClientAreaPixels.height+" - drawableHandle "+toHexString(dh));
}
if( drawableOK ) {
if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
final RecursiveLock _lock = lock;
_lock.lock();
try {
- final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, nClientArea.width, nClientArea.height);
+ final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, nClientAreaPixels.width, nClientAreaPixels.height);
if(_drawable != _drawableNew) {
// write back
drawable = _drawableNew;
@@ -476,9 +479,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable, GLSharedContextS
}
}
if(0 != x11Window) {
- SWTAccessor.resizeX11Window(screen.getDevice(), clientArea, x11Window);
- } else if(0 != gdkWindow) {
- SWTAccessor.resizeGDKWindow(clientArea, gdkWindow);
+ SWTAccessor.resizeX11Window(screen.getDevice(), clientAreaPixels, x11Window);
}
sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
}
@@ -548,7 +549,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable, GLSharedContextS
return res;
}
private final void createDrawableImpl() {
- final Rectangle nClientArea = clientArea;
+ final Rectangle nClientArea = clientAreaPixels;
if(0 >= nClientArea.width || 0 >= nClientArea.height) {
if(DEBUG) {
System.err.println(getThreadName()+": SWT.GLCanvas.validate.X "+toHexString(hashCode())+": drawable could not be created: size < 0x0");
@@ -573,7 +574,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable, GLSharedContextS
if( VisualIDHolder.VID_UNDEFINED != visualID ) {
// gdkWindow = SWTAccessor.createCompatibleGDKChildWindow(this, visualID, clientArea.width, clientArea.height);
// nativeWindowHandle = SWTAccessor.gdk_window_get_xwindow(gdkWindow);
- x11Window = SWTAccessor.createCompatibleX11ChildWindow(screen, this, visualID, clientArea.width, clientArea.height);
+ x11Window = SWTAccessor.createCompatibleX11ChildWindow(screen, this, visualID, clientAreaPixels.width, clientAreaPixels.height);
nativeWindowHandle = x11Window;
} else {
throw new GLException("Could not choose valid visualID: "+toHexString(visualID)+", "+this);
@@ -669,12 +670,12 @@ public class GLCanvas extends Canvas implements GLAutoDrawable, GLSharedContextS
@Override
public int getSurfaceWidth() {
- return clientArea.width;
+ return clientAreaPixels.width;
}
@Override
public int getSurfaceHeight() {
- return clientArea.height;
+ return clientAreaPixels.height;
}
@Override
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java b/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
index 76d64963f..9e9cc8e44 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
@@ -56,7 +56,7 @@ import com.jogamp.opengl.util.AnimatorBase.UncaughtAnimatorException;
class AWTAnimatorImpl implements AnimatorBase.AnimatorImpl {
// For efficient rendering of Swing components, in particular when
// they overlap one another
- private final List<JComponent> lightweights = new ArrayList<JComponent>();
+ private final List<JComponent> lightweights = new ArrayList<JComponent>();
private final Map<RepaintManager,RepaintManager> repaintManagers = new IdentityHashMap<RepaintManager,RepaintManager>();
private final Map<JComponent,Rectangle> dirtyRegions = new IdentityHashMap<JComponent,Rectangle>();
@@ -64,34 +64,40 @@ class AWTAnimatorImpl implements AnimatorBase.AnimatorImpl {
public void display(final ArrayList<GLAutoDrawable> drawables,
final boolean ignoreExceptions,
final boolean printExceptions) throws UncaughtAnimatorException {
- for (int i=0; i<drawables.size(); i++) {
- final GLAutoDrawable drawable = drawables.get(i);
- if (drawable instanceof JComponent) {
- // Lightweight components need a more efficient drawing
- // scheme than simply forcing repainting of each one in
- // turn since drawing one can force another one to be
- // drawn in turn
- lightweights.add((JComponent)drawable);
- } else {
- try {
+ boolean hasException = false;
+ for (int i=0; !hasException && i<drawables.size(); i++) {
+ GLAutoDrawable drawable = null;
+ boolean catch1 = true;
+ try {
+ drawable = drawables.get(i);
+ catch1 = false;
+ if (drawable instanceof JComponent) {
+ // Lightweight components need a more efficient drawing
+ // scheme than simply forcing repainting of each one in
+ // turn since drawing one can force another one to be
+ // drawn in turn
+ lightweights.add((JComponent)drawable);
+ } else {
drawable.display();
- } catch (final Throwable t) {
- if (ignoreExceptions) {
- if (printExceptions) {
- t.printStackTrace();
- }
- } else {
- throw new UncaughtAnimatorException(drawable, t);
+ }
+ } catch (final Throwable t) {
+ if( catch1 && t instanceof IndexOutOfBoundsException ) {
+ // concurrent pulling of GLAutoDrawables ..
+ hasException = true;
+ } else if ( ignoreExceptions ) {
+ if ( printExceptions ) {
+ t.printStackTrace();
}
+ } else {
+ throw new UncaughtAnimatorException(drawable, t);
}
}
}
-
if (lightweights.size() > 0) {
try {
SwingUtilities.invokeAndWait(drawWithRepaintManagerRunnable);
- } catch (final Exception e) {
- e.printStackTrace();
+ } catch (final Throwable t) {
+ t.printStackTrace();
}
lightweights.clear();
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/Animator.java b/src/jogl/classes/com/jogamp/opengl/util/Animator.java
index 066709316..10b0b6b5a 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/Animator.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/Animator.java
@@ -40,6 +40,9 @@
package com.jogamp.opengl.util;
+import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.SourcedInterruptedException;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLException;
@@ -174,6 +177,9 @@ public class Animator extends AnimatorBase {
try {
Animator.this.wait();
} catch (final InterruptedException e) {
+ caughtException = new UncaughtAnimatorException(null, SourcedInterruptedException.wrap(e));
+ stopIssued = true;
+ break; // end pause loop
}
if (wasPaused) {
// resume from pause -> reset counter
@@ -209,8 +215,7 @@ public class Animator extends AnimatorBase {
}
} catch(final ThreadDeath td) {
if(DEBUG) {
- System.err.println("Animator caught: "+td.getClass().getName()+": "+td.getMessage());
- td.printStackTrace();
+ ExceptionUtils.dumpThrowable("", td);
}
caughtThreadDeath = td;
}
@@ -222,8 +227,7 @@ public class Animator extends AnimatorBase {
if( null == caughtException ) {
caughtException = dre;
} else {
- System.err.println("Animator.setExclusiveContextThread: caught: "+dre.getMessage());
- dre.printStackTrace();
+ ExceptionUtils.dumpThrowable("(setExclusiveContextThread)", dre);
}
}
}
@@ -233,8 +237,7 @@ public class Animator extends AnimatorBase {
if(DEBUG) {
System.err.println("Animator stop on " + animThread.getName() + ": " + toString());
if( null != caughtException ) {
- System.err.println("Animator caught: "+caughtException.getMessage());
- caughtException.printStackTrace();
+ ExceptionUtils.dumpThrowable("", caughtException);
}
}
stopIssued = false;
@@ -291,13 +294,7 @@ public class Animator extends AnimatorBase {
runnable = new MainLoop();
}
fpsCounter.resetFPSCounter();
- final String threadName = getThreadName()+"-"+baseName;
- Thread thread;
- if(null==threadGroup) {
- thread = new Thread(runnable, threadName);
- } else {
- thread = new Thread(threadGroup, runnable, threadName);
- }
+ final Thread thread = new InterruptSource.Thread(threadGroup, runnable, getThreadName()+"-"+baseName);
thread.setDaemon(false); // force to be non daemon, regardless of parent thread
if(DEBUG) {
final Thread ct = Thread.currentThread();
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
index aafdf63f8..c2da68cd9 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
@@ -33,6 +33,7 @@ import jogamp.opengl.FPSCounterImpl;
import java.io.PrintStream;
import java.util.ArrayList;
+import java.util.Locale;
import com.jogamp.opengl.GLAnimatorControl;
import com.jogamp.opengl.GLAutoDrawable;
@@ -40,6 +41,7 @@ import com.jogamp.opengl.GLException;
import com.jogamp.opengl.GLProfile;
import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptedRuntimeException;
/**
* Base implementation of GLAnimatorControl<br>
@@ -150,7 +152,7 @@ public abstract class AnimatorBase implements GLAnimatorControl {
*/
protected final synchronized void initImpl(final boolean force) {
if( force || null == impl ) {
- final String seqSuffix = String.format("#%02d", seqInstanceNumber++);
+ final String seqSuffix = String.format((Locale)null, "#%02d", seqInstanceNumber++);
if( useAWTAnimatorImpl( modeBits ) ) {
try {
impl = (AnimatorImpl) awtAnimatorImplClazz.newInstance();
@@ -596,7 +598,9 @@ public abstract class AnimatorBase implements GLAnimatorControl {
notifyAll();
try {
wait(pollPeriod);
- } catch (final InterruptedException ie) { }
+ } catch (final InterruptedException ie) {
+ throw new InterruptedRuntimeException(ie);
+ }
remaining -= System.currentTimeMillis() - t1 ;
nok = waitCondition.eval();
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java b/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java
index 6cded29d9..d8c8465d9 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java
@@ -48,12 +48,19 @@ class DefaultAnimatorImpl implements AnimatorBase.AnimatorImpl {
public void display(final ArrayList<GLAutoDrawable> drawables,
final boolean ignoreExceptions,
final boolean printExceptions) throws UncaughtAnimatorException {
- for (int i=0; i<drawables.size(); i++) {
- final GLAutoDrawable drawable = drawables.get(i);
+ boolean hasException = false;
+ for (int i=0; !hasException && i<drawables.size(); i++) {
+ boolean catch1 = true;
+ GLAutoDrawable drawable = null;
try {
+ drawable = drawables.get(i);
+ catch1 = false;
drawable.display();
} catch (final Throwable t) {
- if (ignoreExceptions) {
+ if( catch1 && t instanceof IndexOutOfBoundsException ) {
+ // concurrent pulling of GLAutoDrawables ..
+ hasException = true;
+ } else if (ignoreExceptions) {
if (printExceptions) {
t.printStackTrace();
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java b/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java
index c82f63898..0e3497bd4 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java
@@ -262,6 +262,8 @@ public class GLPixelBuffer {
case GL.GL_UNSIGNED_SHORT_5_5_5_1:
pixFmt = PixelFormat.ABGR1555;
break;
+ case GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV:
+ // fall through intended
case GL.GL_UNSIGNED_BYTE:
pixFmt = PixelFormat.RGBA8888;
break;
@@ -280,6 +282,8 @@ public class GLPixelBuffer {
case GL2GL3.GL_UNSIGNED_INT_8_8_8_8:
pixFmt = PixelFormat.ARGB8888;
break;
+ case GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV:
+ // fall through intended
case GL.GL_UNSIGNED_BYTE:
pixFmt = PixelFormat.BGRA8888;
break;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
index cc3462f99..3fa856a47 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
@@ -245,8 +245,8 @@ public class GLReadBufferUtil {
readTexture.updateImage(gl, readTextureData);
} else {
readTexture.updateSubImage(gl, readTextureData, 0,
- 0, 0, // src offset
- 0, 0, // dst offset
+ inX, inY, // dst offset
+ 0, 0, // src offset
width, height);
}
readPixelBuffer.rewind();
diff --git a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
index 196acf9ab..5383f91be 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
@@ -920,7 +920,6 @@ public final class PMVMatrix implements GLMatrixFunc {
* or {@link #glGetFrustum() Frustum get} methods.
* </p>
*
- * @deprecated Function is exposed for debugging purposes only.
* @see #DIRTY_INVERSE_MODELVIEW
* @see #DIRTY_INVERSE_TRANSPOSED_MODELVIEW
* @see #DIRTY_FRUSTUM
@@ -941,7 +940,6 @@ public final class PMVMatrix implements GLMatrixFunc {
* or {@link #glGetFrustum() Frustum get} methods.
* </p>
*
- * @deprecated Function is exposed for debugging purposes only.
* @see #clearAllUpdateRequests()
* @see #DIRTY_INVERSE_MODELVIEW
* @see #DIRTY_INVERSE_TRANSPOSED_MODELVIEW
diff --git a/src/jogl/classes/com/jogamp/opengl/util/PNGPixelRect.java b/src/jogl/classes/com/jogamp/opengl/util/PNGPixelRect.java
index f28774afa..1dded7882 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/PNGPixelRect.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/PNGPixelRect.java
@@ -78,7 +78,8 @@ public class PNGPixelRect extends PixelRectangle.GenericPixelRect {
public static PNGPixelRect read(final InputStream in,
final PixelFormat ddestFmt, final boolean destDirectBuffer, final int destMinStrideInBytes,
final boolean destIsGLOriented) throws IOException {
- final PngReader pngr = new PngReader(new BufferedInputStream(in), null);
+ final BufferedInputStream bin = (in instanceof BufferedInputStream) ? (BufferedInputStream)in : new BufferedInputStream(in);
+ final PngReader pngr = new PngReader(bin, null);
final ImageInfo imgInfo = pngr.imgInfo;
final PngChunkPLTE plte = pngr.getMetadata().getPLTE();
final PngChunkTRNS trns = pngr.getMetadata().getTRNS();
diff --git a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
index 662cf74b7..c2de32372 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
@@ -205,22 +205,29 @@ public interface GLMediaPlayer extends TextureSequence {
* {@link Uri#scheme Uri scheme} name {@value} for camera input. E.g. <code>camera:/0</code>
* for the 1st camera device.
* <p>
- * The {@link Uri#path Uri path} is being used to identify the camera (<i>ID</i>),
+ * The {@link Uri#path Uri path} is being used to identify the camera (<i>&lt;id&gt;</i>),
* where the root fwd-slash is being cut-off.
* </p>
* <p>
- * The <i>ID</i> is usually an integer value indexing the camera
+ * The <i>&lt;id&gt;</i> is usually an integer value indexing the camera
* ranging from [0..<i>max-number</i>].
* </p>
* <p>
+ * The <i>&lt;somewhere&gt;</i> is usually empty, since it would imply a networking camera protocol.
+ * </p>
+ * <p>
* The {@link Uri#query Uri query} is used to pass options to the camera
* using <i>;</i> as the separator. The latter avoids trouble w/ escaping.
* </p>
* <pre>
- * camera:/<id>
- * camera://somewhere/<id>
- * camera://somewhere/<id>?width=640;height=480;rate=15
- * camera://somewhere/<id>?size=640x480;rate=15
+ * camera:/&lt;id&gt;
+ * camera:/&lt;id&gt;?width=640;height=480;rate=15
+ * camera:/&lt;id&gt;?size=640x480;rate=15
+ * camera://&lt;somewhere&gt;/&lt;id&gt;
+ * camera://&lt;somewhere&gt;/&lt;id&gt;?width=640;height=480;rate=15
+ * camera://&lt;somewhere&gt;/&lt;id&gt;?size=640x480;rate=15
+ * camera:///&lt;id&gt;?width=640;height=480;rate=15
+ * camera:///&lt;id&gt;?size=640x480;rate=15
* </pre>
* <pre>
* Uri: [scheme:][//authority][path][?query][#fragment]
diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
index e6f5aaa2e..38bac06cc 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
@@ -40,6 +40,7 @@
package com.jogamp.opengl.util.awt;
import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.common.util.PropertyAccess;
import com.jogamp.opengl.GLExtensions;
import com.jogamp.opengl.util.*;
@@ -915,7 +916,7 @@ public class TextRenderer {
// Run this on another thread than the AWT event queue to
// make sure the call to Animator.stop() completes before
// exiting
- new Thread(new Runnable() {
+ new InterruptSource.Thread(null, new Runnable() {
@Override
public void run() {
anim.stop();
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
index e5ef3b268..532db3a7a 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
@@ -148,9 +148,9 @@ public class ShaderCode {
switch (type) {
case GL2ES2.GL_VERTEX_SHADER:
case GL2ES2.GL_FRAGMENT_SHADER:
- case GL3.GL_GEOMETRY_SHADER:
- case GL3.GL_TESS_CONTROL_SHADER:
- case GL3.GL_TESS_EVALUATION_SHADER:
+ case GL3ES3.GL_GEOMETRY_SHADER:
+ case GL3ES3.GL_TESS_CONTROL_SHADER:
+ case GL3ES3.GL_TESS_EVALUATION_SHADER:
case GL3ES3.GL_COMPUTE_SHADER:
break;
default:
@@ -179,9 +179,9 @@ public class ShaderCode {
switch (type) {
case GL2ES2.GL_VERTEX_SHADER:
case GL2ES2.GL_FRAGMENT_SHADER:
- case GL3.GL_GEOMETRY_SHADER:
- case GL3.GL_TESS_CONTROL_SHADER:
- case GL3.GL_TESS_EVALUATION_SHADER:
+ case GL3ES3.GL_GEOMETRY_SHADER:
+ case GL3ES3.GL_TESS_CONTROL_SHADER:
+ case GL3ES3.GL_TESS_EVALUATION_SHADER:
case GL3ES3.GL_COMPUTE_SHADER:
break;
default:
@@ -386,11 +386,11 @@ public class ShaderCode {
return binary?SUFFIX_VERTEX_BINARY:SUFFIX_VERTEX_SOURCE;
case GL2ES2.GL_FRAGMENT_SHADER:
return binary?SUFFIX_FRAGMENT_BINARY:SUFFIX_FRAGMENT_SOURCE;
- case GL3.GL_GEOMETRY_SHADER:
+ case GL3ES3.GL_GEOMETRY_SHADER:
return binary?SUFFIX_GEOMETRY_BINARY:SUFFIX_GEOMETRY_SOURCE;
- case GL3.GL_TESS_CONTROL_SHADER:
+ case GL3ES3.GL_TESS_CONTROL_SHADER:
return binary?SUFFIX_TESS_CONTROL_BINARY:SUFFIX_TESS_CONTROL_SOURCE;
- case GL3.GL_TESS_EVALUATION_SHADER:
+ case GL3ES3.GL_TESS_EVALUATION_SHADER:
return binary?SUFFIX_TESS_EVALUATION_BINARY:SUFFIX_TESS_EVALUATION_SOURCE;
case GL3ES3.GL_COMPUTE_SHADER:
return binary?SUFFIX_COMPUTE_BINARY:SUFFIX_COMPUTE_SOURCE;
@@ -785,11 +785,11 @@ public class ShaderCode {
return "VERTEX_SHADER";
case GL2ES2.GL_FRAGMENT_SHADER:
return "FRAGMENT_SHADER";
- case GL3.GL_GEOMETRY_SHADER:
+ case GL3ES3.GL_GEOMETRY_SHADER:
return "GEOMETRY_SHADER";
- case GL3.GL_TESS_CONTROL_SHADER:
+ case GL3ES3.GL_TESS_CONTROL_SHADER:
return "TESS_CONTROL_SHADER";
- case GL3.GL_TESS_EVALUATION_SHADER:
+ case GL3ES3.GL_TESS_EVALUATION_SHADER:
return "TESS_EVALUATION_SHADER";
case GL3ES3.GL_COMPUTE_SHADER:
return "COMPUTE_SHADER";
@@ -1098,7 +1098,15 @@ public class ShaderCode {
while ((line = reader.readLine()) != null) {
lineno++;
if (line.startsWith("#include ")) {
- final String includeFile = line.substring(9).trim();
+ final String includeFile;
+ {
+ String s = line.substring(9).trim();
+ // Bug 1283: Remove shader include filename quotes if exists at start and end only
+ if( s.startsWith("\"") && s.endsWith("\"")) {
+ s = s.substring(1, s.length()-1);
+ }
+ includeFile = s;
+ }
URLConnection nextConn = null;
// Try relative of current shader location
@@ -1106,7 +1114,7 @@ public class ShaderCode {
nextConn = IOUtil.openURL(relUri.toURL(), "ShaderCode.relativeOf ");
if (nextConn == null) {
// Try relative of class and absolute
- nextConn = IOUtil.getResource(context, includeFile);
+ nextConn = IOUtil.getResource(includeFile, context.getClassLoader(), context);
}
if (nextConn == null) {
// Fail
@@ -1158,7 +1166,7 @@ public class ShaderCode {
* @see IOUtil#getResource(Class, String)
*/
public static CharSequence readShaderSource(final Class<?> context, final String path, final boolean mutableStringBuilder) throws IOException {
- final URLConnection conn = IOUtil.getResource(context, path);
+ final URLConnection conn = IOUtil.getResource(path, context.getClassLoader(), context);
if (conn == null) {
return null;
}
@@ -1204,7 +1212,7 @@ public class ShaderCode {
* @see IOUtil#getResource(Class, String)
*/
public static ByteBuffer readShaderBinary(final Class<?> context, final String path) throws IOException {
- final URLConnection conn = IOUtil.getResource(context, path);
+ final URLConnection conn = IOUtil.getResource(path, context.getClassLoader(), context);
if (conn == null) {
return null;
}
@@ -1330,9 +1338,9 @@ public class ShaderCode {
// GLSL [ 1.30 .. 1.50 [ needs at least fragement float default precision!
switch ( shaderType ) {
case GL2ES2.GL_VERTEX_SHADER:
- case GL3.GL_GEOMETRY_SHADER:
- case GL3.GL_TESS_CONTROL_SHADER:
- case GL3.GL_TESS_EVALUATION_SHADER:
+ case GL3ES3.GL_GEOMETRY_SHADER:
+ case GL3ES3.GL_TESS_CONTROL_SHADER:
+ case GL3ES3.GL_TESS_EVALUATION_SHADER:
defaultPrecision = gl3_default_precision_vp_gp; break;
case GL2ES2.GL_FRAGMENT_SHADER:
defaultPrecision = gl3_default_precision_fp; break;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShader.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShader.java
index f5dec1cab..376afb8ce 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShader.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShader.java
@@ -52,7 +52,7 @@ public abstract class CompileShader {
final String justName = basename(resourceName);
outName = justName.substring(0, justName.length() - suffixLen) +
ShaderCode.getFileSuffix(true, type);
- final URL resourceURL = IOUtil.getResource(null, resourceName).getURL();
+ final URL resourceURL = IOUtil.getResource(resourceName, this.getClass().getClassLoader(), null).getURL();
final String dirName = dirname(resourceURL.getPath());
outName = dirName + File.separator + "bin" + File.separator +
@@ -64,7 +64,7 @@ public abstract class CompileShader {
public void processOneShader(final String resourceName, final String outName, final int type)
throws IOException, UnsupportedEncodingException, InterruptedException
{
- final URL resourceURL = IOUtil.getResource(null, resourceName).getURL();
+ final URL resourceURL = IOUtil.getResource(resourceName, this.getClass().getClassLoader(), null).getURL();
final String dirName = dirname(resourceURL.getPath());
final CharSequence shader = ShaderCode.readShaderSource(null, resourceName, false);
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/ImageIOUtil.java b/src/jogl/classes/com/jogamp/opengl/util/texture/ImageIOUtil.java
deleted file mode 100644
index 12cb13b10..000000000
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/ImageIOUtil.java
+++ /dev/null
@@ -1,445 +0,0 @@
-/**
- * Copyright 2014 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice, this list
- * of conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-package com.jogamp.opengl.util.texture;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Utilities for image input and output
- *
- */
-public class ImageIOUtil {
-
- /**
- * Determines the file suffix (i.e the image format) of the given InputStream. The given
- * InputStream must return true from markSupported() and support a minimum of 32 bytes
- * of read-ahead.
- *
- * @param stream stream to check
- * @return the file suffix if any, otherwise <code>null</code>
- * @throws java.io.IOException if an I/O exception occurred
- */
- public static String getFileSuffix(InputStream stream) throws IOException {
- if (stream == null) {
- throw new IOException("Stream was null");
- }
- if (!(stream instanceof BufferedInputStream)) {
- stream = new BufferedInputStream(stream);
- }
- if (!stream.markSupported()) {
- throw new IOException("Can not get non-destructively the image format");
- }
- if (stream.available() < 32) {
- throw new IOException("Not enough bytes to read in order to get the image format");
- }
- try {
- stream.mark(32);
- final byte[] b = new byte[32];
- stream.read(b);
- return getFileSuffix(b);
- } finally {
- stream.reset();
- }
-
- }
-
- /**
- * Determines the file suffix (i.e the image format) of the given bytes from the header
- * of a file.
- *
- * @param stream stream to check
- * @return the file suffix if any, otherwise <code>null</code>
- * @throws java.io.IOException if an I/O exception occurred
- */
- public static String getFileSuffix(final byte[] b) {
- /**
- * http://www.faqs.org/faqs/jpeg-faq/part1/
- * http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=54989
- */
- if ( (b[0] == 0xff && b[1] == 0xd8 /* && b[2] == 0xff */) ||
- (b[0] == 0x4A && b[1] == 0x46 && b[2] == 0x49 && b[3] == 0x46)/* JFIF */ ||
- (b[0] == 0x45 && b[1] == 0x78 && b[2] == 0x69 && b[3] == 0x66)/* EXIF */) {
- return TextureIO.JPG;
- }
- /**
- * http://www.libpng.org/pub/png/spec/1.1/PNG-Rationale.html#R.PNG-file-signature
- */
- if (b[0] == 0x89 && b[1] == 0x50 && b[2] == 0x4E && b[3] == 0x47 && /* 'P' 'N' 'G', ascii code */
- b[4] == 0x0D && b[5] == 0x0A && b[6] == 0x1A && b[7] == 0x0A) {
- return TextureIO.PNG;
- }
- /**
- * Apple Icon Image
- *
- * 'i' 'c' 'n' 's' ascii code
- */
- if (b[0] == 0x69 && b[1] == 0x63 && b[2] == 0x6E && b[3] == 0x73) {
- return "icns";
- }
- /**
- * http://www.w3.org/Graphics/GIF/spec-gif87a.txt http://www.w3.org/Graphics/GIF/spec-gif89a.txt
- *
- * GIF87A or GIF89A ascii code
- */
- if (b[0] == 0x47 && b[1] == 0x49 && b[2] == 0x46 && b[3] == 0x38 && (b[4] == 0x37 || b[4] == 0x39) &&
- b[5] == 0x61) {
- return TextureIO.GIF;
- }
- /**
- * http://www.fileformat.info/format/bmp/spec/e27073c25463436f8a64fa789c886d9c/view.htm
- *
- * BM ascii code
- */
- if (b[0] == 0x42 && b[1] == 0x4d) {
- return "bmp";
- }
- if (b[0] == 0x3A && b[1] == 0xDE && b[2] == 0x68 && b[3] == 0xB1) {
- return "dcx";
- }
- if (b[0] == 0x0A && b[1] == 0x05 && b[2] == 0x01 && b[3] == 0x08) {
- return "pcx";
- }
- /**
- * http://netpbm.sourceforge.net/doc/ppm.html
- */
- if (b[0] == 0x50 && (b[1] == 0x33 /* plain */|| b[1] == 0x36)) {
- return TextureIO.PPM;
- }
- if (b[0] == 0x38 && b[1] == 0x42 && b[2] == 0x50 && b[3] == 0x53 && b[4] == 0x00 && b[5] == 0x01 &&
- b[6] == 0x00 && b[7] == 0x00 && b[8] == 0x00 && b[9] == 0x00) {
- // Adobe PhotoShop
- return "psd";
- }
- /**
- * http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf
- *
- * intentionally detects only the little endian tiff images ("II" in the spec)
- */
- if (b[0] == 0x49 && b[1] == 0x49 && b[2] == 0x2A && b[3] == 0x00) {
- return TextureIO.TIFF;
- }
- /**
- * http://paulbourke.net/dataformats/sgirgb/sgiversion.html
- *
- * "474 saved as a short" 474 = 0x01DA
- */
- if (b[0] == 0x01 && b[1] == 0xDA /* && b[2] == 0x01 && b[3] == 0x01 && b[4] == 0x00 && b[5] == 0x03 */) {
- return TextureIO.SGI_RGB;
- }
- /**
- * 'D' 'D' 'S' ' ' ascii code
- */
- if (b[0] == 0x44 && b[1] == 0x44 && b[2] == 0x53 && b[3] == 0x20) {
- return TextureIO.DDS;
- }
- /**
- * http://netpbm.sourceforge.net/doc/pam.html
- */
- if (b[0] == 0x50 && b[1] == 0x37) {
- return TextureIO.PAM;
- }
- /**
- * http://netpbm.sourceforge.net/doc/pgm.html
- */
- if (b[0] == 0x50 && (b[1] == 0x32 /* plain */|| b[1] == 0x35)) {
- return "pgm";
- }
- /**
- * http://netpbm.sourceforge.net/doc/pbm.html
- */
- if (b[0] == 0x50 && (b[1] == 0x31 /* plain */|| b[1] == 0x34)) {
- return "pbm";
- }
- if (b[0] == 0x3D && b[1] == 0x02) {
- return "3d2";
- }
- if (b[0] == 0x33 && b[1] == 0x44 && b[2] == 0x4D && b[3] == 0x46) {
- return "3dmf";
- }
- if (b[0] == 0x2A && b[1] == 0x2A && b[2] == 0x54 && b[3] == 0x49 && b[4] == 0x39 && b[5] == 0x32 &&
- b[6] == 0x2A && b[7] == 0x2A && b[8] == 0x01 && b[9] == 0x00 && b[10] == 0x58 &&
- b[11] == 0x6E && b[12] == 0x56 && b[13] == 0x69) {
- return "92i";
- }
- if (b[0] == 0x41 && b[1] == 0x4D && b[2] == 0x46 && b[3] == 0x46) {
- return "amff";
- }
- if (b[0] == 0x4A && b[1] == 0x47 && (b[2] == 0x03 || b[2] == 0x04) && b[3] == 0x0E && b[4] == 0x00 &&
- b[5] == 0x00 && b[6] == 0x00) {
- return "art";
- }
- if (b[0] == 0x73 && b[1] == 0x72 && b[2] == 0x63 && b[3] == 0x64 && b[4] == 0x6F && b[5] == 0x63 &&
- b[6] == 0x69 && b[7] == 0x64 && b[8] == 0x3A) {
- return "cals";
- }
- if (b[0] == 0x07 && b[1] == 0x20 && b[2] == 0x4D && b[3] == 0x4D) {
- return "cam";
- }
- if (b[0] == 0x20 && b[1] == 0x77 && b[2] == 0x00 && b[3] == 0x02) {
- return "cbd";
- }
- if (b[0] == 0x45 && b[1] == 0x59 && b[2] == 0x45 && b[3] == 0x53) {
- return "ce2";
- }
- if (b[0] == 0x80 && b[1] == 0x2A && b[2] == 0x5F && b[3] == 0xD7 && b[4] == 0x00 && b[5] == 0x00 &&
- b[6] == 0x08 && b[7] == 0x00 && b[8] == 0x00 && b[9] == 0x00 && b[10] == 0x04 &&
- b[11] == 0x00 && b[12] == 0x00 && b[13] == 0x00) {
- return "cin";
- }
- if (b[0] == 0x43 && b[1] == 0x61 && b[2] == 0x6C && b[3] == 0x69 && b[4] == 0x67 && b[5] == 0x61 &&
- b[6] == 0x72 && b[7] == 0x69) {
- return "cob";
- }
- if (b[0] == 0x43 && b[1] == 0x50 && b[2] == 0x54 && b[3] == 0x46 && b[4] == 0x49 && b[5] == 0x4C &&
- b[6] == 0x45) {
- return "cpt";
- }
- if (b[0] == 0x43 && b[1] == 0x41 && b[2] == 0x4C && b[3] == 0x41 && b[4] == 0x4D && b[5] == 0x55 &&
- b[6] == 0x53 && b[7] == 0x43 && b[8] == 0x56 && b[9] == 0x47) {
- return "cvg";
- }
- if (b[0] == 0x56 && b[1] == 0x69 && b[2] == 0x73 && b[3] == 0x74 && b[4] == 0x61 && b[5] == 0x20 &&
- b[6] == 0x44 && b[7] == 0x45 && b[8] == 0x4D && b[9] == 0x20 && b[10] == 0x46 &&
- b[11] == 0x69 && b[12] == 0x6C && b[13] == 0x65) {
- return "dem";
- }
- if (b[0] == 0x42 && b[1] == 0x4D && b[2] == 0x36) {
- return "dib";
- }
- if (b[0] == 0x53 && b[1] == 0x44 && b[2] == 0x50 && b[3] == 0x58) {
- return "dpx";
- }
- if (b[0] == 0x01 && b[1] == 0xFF && b[2] == 0x02 && b[3] == 0x04 && b[4] == 0x03 && b[5] == 0x02) {
- return "drw";
- }
- if (b[0] == 0x41 && b[1] == 0x43 && b[2] == 0x31 && b[3] == 0x30) {
- return "dwg";
- }
- if (b[0] == 0x65 && b[1] == 0x02 && b[2] == 0x01 && b[3] == 0x02) {
- return "ecw";
- }
- if (b[0] == 0x01 && b[1] == 0x00 && b[2] == 0x00 && b[3] == 0x00 && b[4] == 0x58 && b[5] == 0x00 &&
- b[6] == 0x00 && b[7] == 0x00) {
- return "emf";
- }
- if (b[0] == 0xD0 && b[1] == 0xCF && b[2] == 0x11 && b[3] == 0xE0 && b[4] == 0xA1 && b[5] == 0xB1 &&
- b[6] == 0x1A && b[7] == 0xE1 && b[8] == 0x00) {
- return "fpx";
- }
- if (b[0] == 0x53 && b[1] == 0x49 && b[2] == 0x4D && b[3] == 0x50 && b[4] == 0x4C && b[5] == 0x45 &&
- b[6] == 0x20 && b[7] == 0x20 && b[8] == 0x3D) {
- return "fts";
- }
- if (b[0] == 0x48 && b[1] == 0x50 && b[2] == 0x48 && b[3] == 0x50 && b[4] == 0x34 && b[5] == 0x38 &&
- b[6] == 0x2D && b[7] == 0x45 && b[8] == 0x1E && b[9] == 0x2B) {
- return "gro";
- }
- if (b[0] == 0x6E && b[1] == 0x63 && b[2] == 0x6F && b[3] == 0x6C && b[4] == 0x73) {
- return "hdr";
- }
- if (b[0] == 0x35 && b[1] == 0x4B && b[2] == 0x50 && b[3] == 0x35 && b[4] == 0x31 && b[5] == 0x5D &&
- b[6] == 0x2A && b[7] == 0x67 && b[8] == 0x72 && b[9] == 0x72 && b[10] == 0x80 &&
- b[11] == 0x83 && b[12] == 0x85 && b[13] == 0x63) {
- return "hru";
- }
- if (b[0] == 0xEB && b[1] == 0x3C && b[2] == 0x90 && b[3] == 0x2A) {
- return "img";
- }
- if (b[0] == 0x65 && b[1] == 0x6C && b[2] == 0x6D && b[3] == 0x6F) {
- return "infini-d";
- }
- if (b[0] == 0x49 && b[1] == 0x57 && b[2] == 0x43 && b[3] == 0x01) {
- return "iwc";
- }
- if (b[0] == 0x80 && b[1] == 0x3E && b[2] == 0x44 && b[3] == 0x53 && b[4] == 0x43 && b[5] == 0x49 &&
- b[6] == 0x4D) {
- return "j6i";
- }
- if (b[0] == 0x4A && b[1] == 0x49 && b[2] == 0x46 && b[3] == 0x39 && b[4] == 0x39 && b[5] == 0x61) {
- return "jif";
- }
- if (b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x00 && b[3] == 0x0C && b[4] == 0x6A && b[5] == 0x50 &&
- b[6] == 0x20 && b[7] == 0x20 && b[8] == 0x0D && b[9] == 0x0A && b[10] == 0x87 &&
- b[11] == 0x0A) {
- return "jp2";
- }
- if (b[0] == 0x4D && b[1] == 0x4D && b[2] == 0x00 && b[3] == 0x2A) {
- return "kdc";
- }
- if (b[0] == 0x36 && b[1] == 0x34 && b[2] == 0x4C && b[3] == 0x41 && b[4] == 0x4E && b[5] == 0x20 &&
- b[6] == 0x49 && b[7] == 0x44 && b[8] == 0x42 && b[9] == 0x4C && b[10] == 0x4F &&
- b[11] == 0x43 && b[12] == 0x4B) {
- return "l64";
- }
- if (b[0] == 0x46 && b[1] == 0x4F && b[2] == 0x52 && b[3] == 0x4D) {
- return "lbm";
- }
- if (b[0] == 0x49 && b[1] == 0x49 && b[2] == 0x2A && b[3] == 0x00 && b[4] == 0x08 && b[5] == 0x00 &&
- b[6] == 0x00 && b[7] == 0x00 && b[8] == 0x0E && b[9] == 0x00 && b[10] == 0x00 &&
- b[11] == 0x01 && b[12] == 0x04 && b[13] == 0x00) {
- return "ldf";
- }
- if (b[0] == 0x57 && b[1] == 0x56 && b[2] == 0x02 && b[3] == 0x00 && b[4] == 0x47 && b[5] == 0x45 &&
- b[6] == 0x00 && b[7] == 0x0E) {
- return "lwf";
- }
- if (b[0] == 0x37 && b[1] == 0x00 && b[2] == 0x00 && b[3] == 0x10 && b[4] == 0x42 && b[5] == 0x00 &&
- b[6] == 0x00 && b[7] == 0x10 && b[8] == 0x00 && b[9] == 0x00 && b[10] == 0x00 &&
- b[11] == 0x00 && b[12] == 0x39 && b[13] == 0x64) {
- return "mbm";
- }
- if (b[0] == 0x4D && b[1] == 0x47 && b[2] == 0x4C) {
- return "mgl";
- }
- if (b[0] == 0x7B && b[1] == 0x0A && b[2] == 0x20 && b[3] == 0x20 && b[4] == 0x43 && b[5] == 0x72 &&
- b[6] == 0x65 && b[7] == 0x61 && b[8] == 0x74 && b[9] == 0x65 && b[10] == 0x64) {
- return "mif";
- }
- if (b[0] == 0x8A && b[1] == 0x4D && b[2] == 0x4E && b[3] == 0x47 && b[4] == 0x0D && b[5] == 0x0A &&
- b[6] == 0x1A && b[7] == 0x0A) {
- return "mng";
- }
- if (b[0] == 0x4D && b[1] == 0x50 && b[2] == 0x46) {
- return "mpw";
- }
- if (b[0] == 0x44 && b[1] == 0x61 && b[2] == 0x6E && b[3] == 0x4D) {
- return "msp";
- }
- if (b[0] == 0x43 && b[1] == 0x36 && b[2] == 0x34) {
- return "n64";
- }
- if (b[0] == 0x6E && b[1] == 0x6E && b[2] == 0x0A && b[3] == 0x00 && b[4] == 0x5E && b[5] == 0x00) {
- return "ncr";
- }
- if (b[0] == 0x6E && b[1] == 0x66 && b[2] == 0x66) {
- return "nff";
- }
- if (b[0] == 0x4E && b[1] == 0x47 && b[2] == 0x47 && b[3] == 0x00 && b[4] == 0x01 && b[5] == 0x00) {
- return "ngg";
- }
- if (b[0] == 0x4E && b[1] == 0x4C && b[2] == 0x4D && b[3] == 0x20 && b[4] == 0x01 && b[5] == 0x02 &&
- b[6] == 0x00) {
- return "nlm";
- }
- if (b[0] == 0x4E && b[1] == 0x4F && b[2] == 0x4C && b[3] == 0x00 && b[4] == 0x01 && b[5] == 0x00 &&
- b[6] == 0x06 && b[7] == 0x01 && b[8] == 0x03 && b[9] == 0x00) {
- return "nol";
- }
- if (b[0] == 0x41 && b[1] == 0x48) {
- return "pal";
- }
- if (b[0] == 0x50 && b[1] == 0x41 && b[2] == 0x58) {
- return "pax";
- }
- if (b[0] == 0x63 && b[1] == 0x52 && b[2] == 0x01 && b[3] == 0x01 && b[4] == 0x38 && b[5] == 0x09 &&
- b[6] == 0x3D && b[7] == 0x00) {
- return "pcd";
- }
- if (b[0] == 0x1B && b[1] == 0x45 && b[2] == 0x1B && b[3] == 0x26 && b[4] == 0x6C && b[5] == 0x30 &&
- b[6] == 0x4F && b[7] == 0x1B && b[8] == 0x26 && b[9] == 0x6C && b[10] == 0x30 &&
- b[11] == 0x45 && b[12] == 0x1B && b[13] == 0x26) {
- return "pcl";
- }
- if (b[0] == 0x50 && b[1] == 0x49 && b[2] == 0x58 && b[3] == 0x20) {
- return "pix";
- }
- if (b[0] == 0x50 && b[1] == 0x4F && b[2] == 0x4C && b[3] == 0x20 && b[4] == 0x46 && b[5] == 0x6F &&
- b[6] == 0x72 && b[7] == 0x6D && b[8] == 0x61 && b[9] == 0x74) {
- return "pol";
- }
- // Paint Shop Pro
- if (b[0] == 0x7E && b[1] == 0x42 && b[2] == 0x4B && b[3] == 0x00) {
- return "psp";
- }
- if (b[0] == 0x50 && b[1] == 0x61 && b[2] == 0x69 && b[3] == 0x6E && b[4] == 0x74 && b[5] == 0x20 &&
- b[6] == 0x53 && b[7] == 0x68 && b[8] == 0x6F && b[9] == 0x70 && b[10] == 0x20 &&
- b[11] == 0x50 && b[12] == 0x72 && b[13] == 0x6F && b[14] == 0x20 && b[15] == 0x49 &&
- b[16] == 0x6D && b[17] == 0x61 && b[18] == 0x67 && b[19] == 0x65 && b[20] == 0x20 &&
- b[21] == 0x46 && b[22] == 0x69 && b[23] == 0x6C && b[24] == 0x65) {
- return "psp";
- }
- if (b[0] == 0x51 && b[1] == 0x4C && b[2] == 0x49 && b[3] == 0x49 && b[4] == 0x46 && b[5] == 0x41 &&
- b[6] == 0x58) {
- return "qfx";
- }
- if (b[0] == 0x6D && b[1] == 0x6F && b[2] == 0x6F && b[3] == 0x76) {
- return "qtm";
- }
- if (b[0] == 0x46 && b[1] == 0x4F && b[2] == 0x52 && b[3] == 0x4D && b[4] == 0x41 && b[5] == 0x54 &&
- b[6] == 0x3D) {
- return "rad";
- }
- if (b[0] == 0x59 && b[1] == 0xA6 && b[2] == 0x6A && b[3] == 0x95) {
- return "ras";
- }
- if (b[0] == 0x52 && b[1] == 0x49 && b[2] == 0x58 && b[3] == 0x33) {
- return "rix";
- }
- if (b[0] == 0x23 && b[1] == 0x20 && b[2] == 0x24 && b[3] == 0x49 && b[4] == 0x64 && b[5] == 0x3A &&
- b[6] == 0x20) {
- return "sid";
- }
- if (b[0] == 0x41 && b[1] == 0x75 && b[2] == 0x74 && b[3] == 0x6F && b[4] == 0x43 && b[5] == 0x41 &&
- b[6] == 0x44 && b[7] == 0x20 && b[8] == 0x53 && b[9] == 0x6C && b[10] == 0x69 &&
- b[11] == 0x64 && b[12] == 0x65) {
- return "sld";
- }
- if (b[0] == 0x53 && b[1] == 0x74 && b[2] == 0x6F && b[3] == 0x72 && b[4] == 0x6D && b[5] == 0x33 &&
- b[6] == 0x44) {
- return "sod";
- }
- if (b[0] == 0xFA && b[1] == 0xDE && b[2] == 0xBA && b[3] == 0xBE && b[4] == 0x01 && b[5] == 0x01) {
- return "wic";
- }
- if (b[0] == 0xD3 && b[1] == 0x23 && b[2] == 0x00 && b[3] == 0x00 && b[4] == 0x03 && b[5] == 0x00 &&
- b[6] == 0x00 && b[7] == 0x00) {
- return "wlm";
- }
- if (b[0] == 0xD7 && b[1] == 0xCD && b[2] == 0xC6 && b[3] == 0x9A) {
- return "wmf";
- }
- if (b[0] == 0xFF && b[1] == 0x57 && b[2] == 0x50 && b[3] == 0x43 && b[4] == 0x10) {
- return "wpg";
- }
- if (b[0] == 0x23 && b[1] == 0x56 && b[2] == 0x52 && b[3] == 0x4D && b[4] == 0x4C && b[5] == 0x20 &&
- b[6] == 0x56 && b[7] == 0x32 && b[8] == 0x2E && b[9] == 0x30) {
- return "wrl";
- }
- if (b[0] == 0x23 && b[1] == 0x64 && b[2] == 0x65 && b[3] == 0x66 && b[4] == 0x69 && b[5] == 0x6E &&
- b[6] == 0x65) {
- return "xbm";
- }
- if (b[0] == 0x2F && b[1] == 0x2A && b[2] == 0x20 && b[3] == 0x58 && b[4] == 0x50 && b[5] == 0x4D &&
- b[6] == 0x20 && b[7] == 0x2A && b[8] == 0x2F) {
- return "xpm";
- }
- return null;
- }
-}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java b/src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java
index 0f51c2e14..e485e5452 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java
@@ -77,7 +77,7 @@ public class ImageSequence implements TextureSequence {
}
public final void addFrame(final GL gl, final Class<?> context, final String imageResourcePath, final String imageSuffix) throws IOException {
- final URLConnection urlConn = IOUtil.getResource(context, imageResourcePath);
+ final URLConnection urlConn = IOUtil.getResource(imageResourcePath, context.getClassLoader(), context);
if(null != urlConn) {
final TextureData texData = TextureIO.newTextureData(GLProfile.getGL2ES2(), urlConn.getInputStream(), false, imageSuffix);
final Texture tex = new Texture(getTextureTarget());
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/ImageType.java b/src/jogl/classes/com/jogamp/opengl/util/texture/ImageType.java
new file mode 100644
index 000000000..8a3bae554
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/ImageType.java
@@ -0,0 +1,1579 @@
+/**
+ * Copyright 2014 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl.util.texture;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Image type classification.
+ * <p>
+ * Allows to classify the {@link ImageType} of an {@link InputStream} via {@link #ImageType(InputStream)}
+ * or to simply define one {@link ImageType} via {@link #ImageType(String)}.
+ * </p>
+ * @since 2.3.2
+ */
+public class ImageType {
+ /**
+ * Minimum number of bytes to determine the image data type, i.e. {@value} bytes.
+ */
+ public static final int MAGIC_MAX_SIZE = 25;
+
+ /**
+ * Constant which can be used as a file suffix to indicate a JPEG stream, value {@value}.
+ * <ul>
+ * <li>{@code http://www.faqs.org/faqs/jpeg-faq/part1/}</li>
+ * <li>{@code http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=54989}</li>
+ * </ul>
+ */
+ public static final String T_JPG = "jpg";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a PNG stream, value {@value}.
+ * <ul>
+ * <li>{@code http://www.libpng.org/pub/png/spec/1.1/PNG-Rationale.html#R.PNG-file-signature}</li>
+ * </ul>
+ */
+ public static final String T_PNG = "png";
+
+ /**
+ * Constant which can be used as a file suffix to indicate an Apple Icon Image stream, value {@value}.
+ * <p>
+ * {@code 'i' 'c' 'n' 's' ascii code}
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_ICNS = "icns";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Microsoft Windows Icon stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code https://msdn.microsoft.com/en-us/library/ms997538.aspx}</li>
+ * </ul>
+ */
+ public static final String T_ICO = "ico";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Microsoft Windows Cursor stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_CUR = "cur";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a GIF stream, value {@value}.
+ * <p>
+ * {@code GIF87A or GIF89A ascii code}
+ * </p>
+ * <ul>
+ * <li>{@code http://www.w3.org/Graphics/GIF/spec-gif87a.txt http://www.w3.org/Graphics/GIF/spec-gif89a.txt}</li>
+ * </ul>
+ */
+ public static final String T_GIF = "gif";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a GIF stream, value {@value}.
+ * <p>
+ * {@code BM ascii code}
+ * </p>
+ * <p>
+ * FIXME: Collision or supertype of {@link #T_DIB}?
+ * </p>
+ * <ul>
+ * <li>{@code http://www.fileformat.info/format/bmp/spec/e27073c25463436f8a64fa789c886d9c/view.htm}</li>
+ * </ul>
+ */
+ public static final String T_BMP = "bmp";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * FIXME: Collision or subtype of {@link #T_BMP}?
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_DIB = "dib";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_DCX = "dcx";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_PCX = "pcx";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a PAM stream, NetPbm magic 6 - binary RGB.
+ * <ul>
+ * <li>{@code http://netpbm.sourceforge.net/doc/ppm.html}</li>
+ * </ul>
+ */
+ public static final String T_PPM = "ppm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Adobe PhotoShop stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_PSD = "psd";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a TIFF stream, value {@value}.
+ * <p>
+ * Intentionally detects only the little endian tiff images ("II" in the spec).
+ * </p>
+ * <p>
+ * FIXME: Collision or supertype of {@link #T_LDF}?
+ * </p>
+ * <ul>
+ * <li>{@code http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf}</li>
+ * </ul>
+ */
+ public static final String T_TIFF = "tiff";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * FIXME: Collision or subtype of {@link #T_TIFF}?
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_LDF = "ldf";
+
+ /**
+ * Constant which can be used as a file suffix to indicate an SGI RGB stream, value {@value}.
+ * <p>
+ * "474 saved as a short" 474 = 0x01DA
+ * </p>
+ * <ul>
+ * <li>{@code http://paulbourke.net/dataformats/sgirgb/sgiversion.html}</li>
+ * </ul>
+ */
+ public static final String T_SGI_RGB = "rgb";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a DirectDraw Surface stream, value {@value}.
+ * <p>
+ * 'D' 'D' 'S' ' ' ascii code
+ * </p>
+ * <ul>
+ * <li>{@code https://msdn.microsoft.com/en-us/library/windows/desktop/bb943991%28v=vs.85%29.aspx#File_Layout1}</li>
+ * </ul>
+ */
+ public static final String T_DDS = "dds";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Portable Arbitrary Map stream, NetPbm magic 7 - binary RGB and RGBA.
+ * <ul>
+ * <li>{@code http://netpbm.sourceforge.net/doc/pam.html}</li>
+ * </ul>
+ */
+ public static final String T_PAM = "pam";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a PGM stream, NetPbm magic 5 - binary grayscale.
+ * <ul>
+ * <li>{@code http://netpbm.sourceforge.net/doc/pgm.html}</li>
+ * </ul>
+ */
+ public static final String T_PGM = "pgm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a PGM stream, NetPbm magic 4 - binary monochrome.
+ * <ul>
+ * <li>{@code http://netpbm.sourceforge.net/doc/pbm.html}</li>
+ * </ul>
+ */
+ public static final String T_PBM = "pbm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_3D2 = "3d2";
+
+ /**
+ * Constant which can be used as a file suffix to indicate an Apple QuickDraw 3D 3DMF stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_3DMF = "3dmf";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Texas Instruments TI-92 Bitmap stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_92I = "92i";
+
+ /**
+ * Constant which can be used as a file suffix to indicate an Amiga metafile stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_AMFF = "amff";
+
+ /**
+ * Constant which can be used as a file suffix to indicate an America Online Art stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_ART = "art";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a United States Department of Defence Continuous Acquisition and Life-cycle Support Raster stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code http://www.fileformat.info/format/cals/egff.htm}</li>
+ * </ul>
+ */
+ public static final String T_CALS = "cals";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_CAM = "cam";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_CBD = "cbd";
+
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_CE2 = "ce2";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Kodak Cineon System stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code http://www.cineon.com/ff_draft.php}</li>
+ * </ul>
+ */
+ public static final String T_CIN = "cin";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_COB = "cob";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Corel Photo Paint stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_CPT = "cpt";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_CVG = "cvg";
+
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_DEM = "dem";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Digital Picture Exchange stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_DPX = "dpx";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_DRW = "drw";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Autocad drawing stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_DWG = "dwg";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Hexagon Geospatial Enhanced Compression Wavelet stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_ECW = "ecw";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Microsoft Windows Enhanced metafile stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_EMF = "emf";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a FlashPix stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_FPX = "fpx";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_FTS = "fts";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_GRO = "gro";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_HDR = "hdr";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_HRU = "hru";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_IMG = "img";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_INFINI_D = "infini-d";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_IWC = "iwc";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_J6I = "j6i";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_JIF = "jif";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a JPEG-2000 stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_JP2 = "jp2";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_KDC = "kdc";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_L64 = "l64";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * FIXME: Collision or supertype of {@link #T_RAD}?
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_LBM = "lbm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * FIXME: Collision or subtype of {@link #T_LBM}?
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_RAD = "rad";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_LWF = "lwf";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_MBM = "mbm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_MGL = "mgl";
+
+ /**
+ * Constant which can be used as a file suffix to indicate an Imagemagick stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_MIF = "mif";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Multiple-image Network Graphics stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_MNG = "mng";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_MPW = "mpw";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_MSP = "msp";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_N64 = "n64";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_NCR = "ncr";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_NFF = "nff";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_NGG = "ngg";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_NLM = "nlm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_NOL = "nol";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_PAL = "pal";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_PAX = "pax";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_PCD = "pcd";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_PCL = "pcl";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Softimage pic stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code http://paulbourke.net/dataformats/softimagepic/}</li>
+ * </ul>
+ */
+ public static final String T_PIC = "pic";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_PIX = "pix";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_POL = "pol";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a PaintShop Pro stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_PSP = "psp";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_QFX = "qfx";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_QTM = "qtm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Sun Raster stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_RAS = "ras";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_RIX = "rix";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_SID = "sid";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_SLD = "sld";
+
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_SOD = "sod";
+
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_WIC = "wic";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_WLM = "wlm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_WMF = "wmf";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Wordperfect Graphics vectors stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_WPG = "wpg";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_WRL = "wrl";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_XBM = "xbm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a X PixMap stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_XPM = "xpm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Targa stream, value {@value}.
+ * <ul>
+ * <li>{@code }</li>
+ * </ul>
+ */
+ public static final String T_TGA = "tga";
+
+ /**
+ * The determined unique type, e.g. {@link #T_PNG}, {@link #T_JPG}, etc.
+ * <p>
+ * Maybe {@code null} if undetermined, i.e. {@link #isDefined()} returns {@code false}.
+ * </p>
+ */
+ public final String type;
+
+ /**
+ * The optionally read header of size {@link #MAGIC_MAX_SIZE} bytes as used to determine the {@link #type},
+ * i.e. {@link #ImageType(InputStream)}.
+ * <p>
+ * May be {@code null}, if {@link #type} has been determined otherwise, i.e {@link #ImageType(String)}.
+ * </p>
+ * <p>
+ * The header is <i>not</i> being used for {@link #hashCode()} and {@link #equals(Object)}!
+ * </p>
+ */
+ public final byte[] header;
+
+ private final int hash;
+
+ /**
+ * Creates instance based on given stream.
+ * @param stream stream to parse, {@link InputStream#available()} must be &ge; {@link #MAGIC_MAX_SIZE}
+ * @throws java.io.IOException if an I/O exception occurred
+ */
+ public ImageType(final InputStream stream) throws IOException {
+ final byte[] _header = new byte[MAGIC_MAX_SIZE];
+ type = Util.getFileSuffix(stream, _header);
+ this.header = _header;
+ this.hash = null != this.type ? this.type.hashCode() : 0;
+ }
+ /**
+ * Creates instance based on the given type.
+ * @param type must be one of {@link #T_PNG}, {@link #T_JPG}, etc.
+ */
+ public ImageType(final String type) {
+ this.header = null;
+ this.type = type;
+ this.hash = this.type.hashCode();
+ }
+ /** Returns {@code true} if {@link #type} is determined, i.e. not {@code null}, otherwise {@code false}. */
+ public final boolean isDefined() { return null != type; }
+
+ @Override
+ public final int hashCode() {
+ return hash;
+ }
+ @Override
+ public boolean equals(final Object o) {
+ if( o == this ) {
+ return true;
+ } else if( o instanceof ImageType ) {
+ final ImageType t = (ImageType)o;
+ return this.type.equals(t.type);
+ } else {
+ return false;
+ }
+ }
+ @Override
+ public String toString() { return "ImageType["+type+"]"; }
+
+ /**
+ * Static utility functions for {@link ImageType}
+ * to determine the {@link ImageType#type}.
+ * @since 2.3.2
+ */
+ public static class Util {
+ /**
+ * Determines the file suffix (i.e the image format) of the given InputStream. The given
+ * InputStream must return true from markSupported() and support a minimum of {@link #MAGIC_MAX_SIZE} bytes
+ * of read-ahead.
+ *
+ * @param stream stream to parse, {@link InputStream#available()} must be &ge; {@link #MAGIC_MAX_SIZE}
+ * @return the file suffix if any, otherwise <code>null</code>
+ * @throws java.io.IOException if an I/O exception occurred
+ */
+ public static String getFileSuffix(final InputStream stream) throws IOException {
+ return getFileSuffix(stream, new byte[MAGIC_MAX_SIZE]);
+ }
+ /**
+ * Determines the file suffix (i.e the image format) of the given InputStream. The given
+ * InputStream must return true from markSupported() and support a minimum of {@link #MAGIC_MAX_SIZE} bytes
+ * of read-ahead.
+ *
+ * @param stream stream to parse, {@link InputStream#available()} must be &ge; {@link #MAGIC_MAX_SIZE}
+ * @param b byte array sink, size must be &ge; {@link #MAGIC_MAX_SIZE}
+ * @return the file suffix if any, otherwise <code>null</code>
+ * @throws java.io.IOException if an I/O exception occurred
+ */
+ public static String getFileSuffix(InputStream stream, final byte[] b) throws IOException {
+ if (stream == null) {
+ throw new IOException("Stream was null");
+ }
+ if (!(stream instanceof BufferedInputStream)) {
+ stream = new BufferedInputStream(stream);
+ }
+ if (!stream.markSupported()) {
+ throw new IOException("Mark not supported");
+ }
+ if (stream.available() < MAGIC_MAX_SIZE) {
+ throw new IOException("Requires "+MAGIC_MAX_SIZE+" bytes, has "+stream.available()+" bytes");
+ }
+ try {
+ stream.mark(MAGIC_MAX_SIZE);
+ final int bytesRead = stream.read(b);
+ if( MAGIC_MAX_SIZE > bytesRead ) {
+ throw new IOException("Could not read "+MAGIC_MAX_SIZE+" bytes, read "+bytesRead+" bytes");
+ }
+ return getFileSuffix(b);
+ } finally {
+ stream.reset();
+ }
+
+ }
+
+ /**
+ * Determines the file suffix (i.e the image format) of the given bytes from the header
+ * of a file.
+ *
+ * @param b byte array to parse, size must be &ge; {@link #MAGIC_MAX_SIZE}
+ * @return the file suffix if any, otherwise <code>null</code>
+ * @throws java.io.IOException if an I/O exception occurred
+ */
+ public static String getFileSuffix(final byte[] b) {
+ if( b.length < MAGIC_MAX_SIZE ) {
+ throw new IllegalArgumentException("byte array must be >= "+MAGIC_MAX_SIZE+", has "+b.length);
+ }
+ final byte b0 = b[0];
+ final byte b1 = b[1];
+ final byte b2 = b[2];
+ final byte b3 = b[3];
+ final byte b4 = b[4];
+ final byte b5 = b[5];
+
+ // T_TGA: NO Signature!
+
+ if (b0 == (byte)0x00) {
+ if (b1 == (byte)0x00 && b2 == (byte)0x00 && b3 == (byte)0x0C &&
+ b4 == (byte)0x6A && b5 == (byte)0x50 &&
+ b[6] == (byte)0x20 && b[7] == (byte)0x20 && b[8] == (byte)0x0D && b[9] == (byte)0x0A && b[10] == (byte)0x87 &&
+ b[11] == (byte)0x0A) {
+ return T_JP2;
+ }
+ else if (b1 == (byte)0x01) {
+ return T_ICO;
+ }
+ else if (b1 == (byte)0x02) {
+ return T_CUR;
+ }
+ }
+ else if (b0 == (byte)0x01) {
+ if (b1 == (byte)0xDA /* && b2 == (byte)0x01 && b3 == (byte)0x01 && b4 == (byte)0x00 && b5 == (byte)0x03 */) {
+ return T_SGI_RGB;
+ }
+ else if (b1 == (byte)0xFF && b2 == (byte)0x02 && b3 == (byte)0x04 &&
+ b4 == (byte)0x03 && b5 == (byte)0x02) {
+ return T_DRW;
+ }
+ else if (b1 == (byte)0x00 && b2 == (byte)0x00 && b3 == (byte)0x00 &&
+ b4 == (byte)0x58 && b5 == (byte)0x00 &&
+ b[6] == (byte)0x00 && b[7] == (byte)0x00) {
+ return T_EMF;
+ }
+ }
+ else if (b0 == (byte)0x07 && b1 == (byte)0x20 && b2 == (byte)0x4D && b3 == (byte)0x4D) {
+ return T_CAM;
+ }
+ else if (b0 == (byte)0x0A && b1 == (byte)0x05 && b2 == (byte)0x01 && b3 == (byte)0x08) {
+ return T_PCX;
+ }
+ else if (b0 == (byte)0x1B && b1 == (byte)0x45 && b2 == (byte)0x1B && b3 == (byte)0x26 &&
+ b4 == (byte)0x6C && b5 == (byte)0x30 &&
+ b[6] == (byte)0x4F && b[7] == (byte)0x1B && b[8] == (byte)0x26 && b[9] == (byte)0x6C && b[10] == (byte)0x30 &&
+ b[11] == (byte)0x45 && b[12] == (byte)0x1B && b[13] == (byte)0x26) {
+ return T_PCL;
+ }
+ else if (b0 == (byte)0x20 && b1 == (byte)0x77 && b2 == (byte)0x00 && b3 == (byte)0x02) {
+ return T_CBD;
+ }
+ else if (b0 == (byte)0x23) {
+ if (b1 == (byte)0x20 && b2 == (byte)0x24 && b3 == (byte)0x49 &&
+ b4 == (byte)0x64 && b5 == (byte)0x3A &&
+ b[6] == (byte)0x20) {
+ return T_SID;
+ }
+ else if (b1 == (byte)0x56 && b2 == (byte)0x52 && b3 == (byte)0x4D &&
+ b4 == (byte)0x4C && b5 == (byte)0x20 &&
+ b[6] == (byte)0x56 && b[7] == (byte)0x32 && b[8] == (byte)0x2E && b[9] == (byte)0x30) {
+ return T_WRL;
+ }
+ else if (b1 == (byte)0x64 && b2 == (byte)0x65 && b3 == (byte)0x66 &&
+ b4 == (byte)0x69 && b5 == (byte)0x6E &&
+ b[6] == (byte)0x65) {
+ return T_XBM;
+ }
+ }
+ else if (b0 == (byte)0x2A && b1 == (byte)0x2A && b2 == (byte)0x54 && b3 == (byte)0x49 &&
+ b4 == (byte)0x39 && b5 == (byte)0x32 &&
+ b[6] == (byte)0x2A && b[7] == (byte)0x2A && b[8] == (byte)0x01 && b[9] == (byte)0x00 && b[10] == (byte)0x58 &&
+ b[11] == (byte)0x6E && b[12] == (byte)0x56 && b[13] == (byte)0x69) {
+ return T_92I;
+ }
+ else if (b0 == (byte)0x2F && b1 == (byte)0x2A && b2 == (byte)0x20 && b3 == (byte)0x58 &&
+ b4 == (byte)0x50 && b5 == (byte)0x4D &&
+ b[6] == (byte)0x20 && b[7] == (byte)0x2A && b[8] == (byte)0x2F) {
+ return T_XPM;
+ }
+ else if (b0 == (byte)0x33 && b1 == (byte)0x44 && b2 == (byte)0x4D && b3 == (byte)0x46) {
+ return T_3DMF;
+ }
+ else if (b0 == (byte)0x35 && b1 == (byte)0x4B && b2 == (byte)0x50 && b3 == (byte)0x35 &&
+ b4 == (byte)0x31 && b5 == (byte)0x5D &&
+ b[6] == (byte)0x2A && b[7] == (byte)0x67 && b[8] == (byte)0x72 && b[9] == (byte)0x72 && b[10] == (byte)0x80 &&
+ b[11] == (byte)0x83 && b[12] == (byte)0x85 && b[13] == (byte)0x63) {
+ return T_HRU;
+ }
+ else if (b0 == (byte)0x36 && b1 == (byte)0x34 && b2 == (byte)0x4C && b3 == (byte)0x41 &&
+ b4 == (byte)0x4E && b5 == (byte)0x20 &&
+ b[6] == (byte)0x49 && b[7] == (byte)0x44 && b[8] == (byte)0x42 && b[9] == (byte)0x4C && b[10] == (byte)0x4F &&
+ b[11] == (byte)0x43 && b[12] == (byte)0x4B) {
+ return T_L64;
+ }
+ else if (b0 == (byte)0x37 && b1 == (byte)0x00 && b2 == (byte)0x00 && b3 == (byte)0x10 &&
+ b4 == (byte)0x42 && b5 == (byte)0x00 &&
+ b[6] == (byte)0x00 && b[7] == (byte)0x10 && b[8] == (byte)0x00 && b[9] == (byte)0x00 && b[10] == (byte)0x00 &&
+ b[11] == (byte)0x00 && b[12] == (byte)0x39 && b[13] == (byte)0x64) {
+ return T_MBM;
+ }
+ else if (b0 == (byte)0x38 && b1 == (byte)0x42 && b2 == (byte)0x50 && b3 == (byte)0x53 &&
+ b4 == (byte)0x00 && b5 == (byte)0x01 &&
+ b[6] == (byte)0x00 && b[7] == (byte)0x00 && b[8] == (byte)0x00 && b[9] == (byte)0x00) {
+ return T_PSD;
+ }
+ else if (b0 == (byte)0x3A && b1 == (byte)0xDE && b2 == (byte)0x68 && b3 == (byte)0xB1) {
+ return T_DCX;
+ }
+ else if (b0 == (byte)0x3D && b1 == (byte)0x02) {
+ return T_3D2;
+ }
+ else if (b0 == (byte)0x41) {
+ if (b1 == (byte)0x43 && b2 == (byte)0x31 && b3 == (byte)0x30) {
+ return T_DWG;
+ }
+ else if (b1 == (byte)0x48) {
+ return T_PAL;
+ }
+ else if (b1 == (byte)0x4D && b2 == (byte)0x46 && b3 == (byte)0x46) {
+ return T_AMFF;
+ }
+ else if (b1 == (byte)0x75 && b2 == (byte)0x74 && b3 == (byte)0x6F &&
+ b4 == (byte)0x43 && b5 == (byte)0x41 &&
+ b[6] == (byte)0x44 && b[7] == (byte)0x20 && b[8] == (byte)0x53 && b[9] == (byte)0x6C && b[10] == (byte)0x69 &&
+ b[11] == (byte)0x64 && b[12] == (byte)0x65) {
+ return T_SLD;
+ }
+ }
+ else if (b0 == (byte)0x42 && b1 == (byte)0x4D) {
+ if (b2 == (byte)0x36) {
+ // FIXME: Collision or subtype of T_BMP?
+ return T_DIB;
+ } else {
+ return T_BMP;
+ }
+ }
+ else if (b0 == (byte)0x43) {
+ if (b1 == (byte)0x36 && b2 == (byte)0x34) {
+ return T_N64;
+ }
+ else if (b1 == (byte)0x41 && b2 == (byte)0x4C && b3 == (byte)0x41 &&
+ b4 == (byte)0x4D && b5 == (byte)0x55 &&
+ b[6] == (byte)0x53 && b[7] == (byte)0x43 && b[8] == (byte)0x56 && b[9] == (byte)0x47) {
+ return T_CVG;
+ }
+ else if (b1 == (byte)0x50 && b2 == (byte)0x54 && b3 == (byte)0x46 &&
+ b4 == (byte)0x49 && b5 == (byte)0x4C &&
+ b[6] == (byte)0x45) {
+ return T_CPT;
+ }
+ else if (b1 == (byte)0x61 && b2 == (byte)0x6C && b3 == (byte)0x69 &&
+ b4 == (byte)0x67 && b5 == (byte)0x61 &&
+ b[6] == (byte)0x72 && b[7] == (byte)0x69) {
+ return T_COB;
+ }
+ }
+ else if (b0 == (byte)0x44) {
+ if (b1 == (byte)0x44 && b2 == (byte)0x53 && b3 == (byte)0x20) {
+ return T_DDS;
+ }
+ else if (b1 == (byte)0x61 && b2 == (byte)0x6E && b3 == (byte)0x4D) {
+ return T_MSP;
+ }
+ }
+ else if (b0 == (byte)0x45) {
+ if (b1 == (byte)0x59 && b2 == (byte)0x45 && b3 == (byte)0x53) {
+ return T_CE2;
+ }
+ else if (b1 == (byte)0x78 && b2 == (byte)0x69 && b3 == (byte)0x66) { /* EXIF */
+ /**
+ * (b0 == (byte)0x45 && b1 == (byte)0x78 && b2 == (byte)0x69 && b3 == (byte)0x66) || // EXIF
+ * (b0 == (byte)0x4A && b1 == (byte)0x46 && b2 == (byte)0x49 && b3 == (byte)0x46) || // JFIF
+ * (b0 == (byte)0xff && b1 == (byte)0xd8 ) // && b2 == (byte)0xff
+ */
+ return T_JPG;
+ }
+ }
+ else if (b0 == (byte)0x46 && b1 == (byte)0x4F && b2 == (byte)0x52 && b3 == (byte)0x4D) {
+ if (b4 == (byte)0x41 && b5 == (byte)0x54 && b[6] == (byte)0x3D) {
+ // FIXME: Collision or subtype of T_LBM?
+ return T_RAD;
+ } else {
+ return T_LBM;
+ }
+ }
+ else if (b0 == (byte)0x47 && b1 == (byte)0x49 && b2 == (byte)0x46 && b3 == (byte)0x38 &&
+ (b4 == (byte)0x37 || b4 == (byte)0x39) && b5 == (byte)0x61) {
+ return T_GIF;
+ }
+ else if (b0 == (byte)0x48 && b1 == (byte)0x50 && b2 == (byte)0x48 && b3 == (byte)0x50 &&
+ b4 == (byte)0x34 && b5 == (byte)0x38 &&
+ b[6] == (byte)0x2D && b[7] == (byte)0x45 && b[8] == (byte)0x1E && b[9] == (byte)0x2B) {
+ return T_GRO;
+ }
+ else if (b0 == (byte)0x49) {
+ if (b1 == (byte)0x49 && b2 == (byte)0x2A && b3 == (byte)0x00) {
+ if (b4 == (byte)0x08 && b5 == (byte)0x00 &&
+ b[6] == (byte)0x00 && b[7] == (byte)0x00 && b[8] == (byte)0x0E && b[9] == (byte)0x00 && b[10] == (byte)0x00 &&
+ b[11] == (byte)0x01 && b[12] == (byte)0x04 && b[13] == (byte)0x00) {
+ // FIXME: Collision or subtype of T_TIFF?
+ return T_LDF;
+ } else {
+ return T_TIFF;
+ }
+ }
+ else if (b1 == (byte)0x57 && b2 == (byte)0x43 && b3 == (byte)0x01) {
+ return T_IWC;
+ }
+ }
+ else if (b0 == (byte)0x4A) {
+ if (b1 == (byte)0x46 && b2 == (byte)0x49 && b3 == (byte)0x46) { /* JFIF */
+ /**
+ * (b0 == (byte)0x45 && b1 == (byte)0x78 && b2 == (byte)0x69 && b3 == (byte)0x66) || // EXIF
+ * (b0 == (byte)0x4A && b1 == (byte)0x46 && b2 == (byte)0x49 && b3 == (byte)0x46) || // JFIF
+ * (b0 == (byte)0xff && b1 == (byte)0xd8 ) // && b2 == (byte)0xff
+ */
+ return T_JPG;
+ }
+ else if (b1 == (byte)0x47 && (b2 == (byte)0x03 || b2 == (byte)0x04) && b3 == (byte)0x0E &&
+ b4 == (byte)0x00 && b5 == (byte)0x00 &&
+ b[6] == (byte)0x00) {
+ return T_ART;
+ }
+ else if (b1 == (byte)0x49 && b2 == (byte)0x46 && b3 == (byte)0x39 &&
+ b4 == (byte)0x39 && b5 == (byte)0x61) {
+ return T_JIF;
+ }
+ }
+ else if (b0 == (byte)0x4D) {
+ if (b1 == (byte)0x47 && b2 == (byte)0x4C) {
+ return T_MGL;
+ }
+ else if (b1 == (byte)0x4D && b2 == (byte)0x00 && b3 == (byte)0x2A) {
+ return T_KDC;
+ }
+ else if (b1 == (byte)0x50 && b2 == (byte)0x46) {
+ return T_MPW;
+ }
+ }
+ else if (b0 == (byte)0x4E) {
+ if (b1 == (byte)0x47 && b2 == (byte)0x47 && b3 == (byte)0x00 &&
+ b4 == (byte)0x01 && b5 == (byte)0x00) {
+ return T_NGG;
+ }
+ else if (b1 == (byte)0x4C && b2 == (byte)0x4D && b3 == (byte)0x20 &&
+ b4 == (byte)0x01 && b5 == (byte)0x02 &&
+ b[6] == (byte)0x00) {
+ return T_NLM;
+ }
+ else if (b1 == (byte)0x4F && b2 == (byte)0x4C && b3 == (byte)0x00 &&
+ b4 == (byte)0x01 && b5 == (byte)0x00 &&
+ b[6] == (byte)0x06 && b[7] == (byte)0x01 && b[8] == (byte)0x03 && b[9] == (byte)0x00) {
+ return T_NOL;
+ }
+ }
+ else if (b0 == (byte)0x50) {
+ if (b1 == (byte)0x31 /* plain */|| b1 == (byte)0x34) {
+ return T_PBM;
+ }
+ else if (b1 == (byte)0x32 /* plain */|| b1 == (byte)0x35) {
+ return T_PGM;
+ }
+ else if (b1 == (byte)0x33 /* plain */|| b1 == (byte)0x36) {
+ return T_PPM;
+ }
+ else if (b1 == (byte)0x37) {
+ return T_PAM;
+ }
+ else if (b1 == (byte)0x41 && b2 == (byte)0x58) {
+ return T_PAX;
+ }
+ else if (b1 == (byte)0x49 && b2 == (byte)0x58 && b3 == (byte)0x20) {
+ return T_PIX;
+ }
+ else if (b1 == (byte)0x4F && b2 == (byte)0x4C && b3 == (byte)0x20 &&
+ b4 == (byte)0x46 && b5 == (byte)0x6F &&
+ b[6] == (byte)0x72 && b[7] == (byte)0x6D && b[8] == (byte)0x61 && b[9] == (byte)0x74) {
+ return T_POL;
+ }
+ else if (b1 == (byte)0x61 && b2 == (byte)0x69 && b3 == (byte)0x6E &&
+ b4 == (byte)0x74 && b5 == (byte)0x20 &&
+ b[6] == (byte)0x53 && b[7] == (byte)0x68 && b[8] == (byte)0x6F && b[9] == (byte)0x70 && b[10] == (byte)0x20 &&
+ b[11] == (byte)0x50 && b[12] == (byte)0x72 && b[13] == (byte)0x6F && b[14] == (byte)0x20 && b[15] == (byte)0x49 &&
+ b[16] == (byte)0x6D && b[17] == (byte)0x61 && b[18] == (byte)0x67 && b[19] == (byte)0x65 && b[20] == (byte)0x20 &&
+ b[21] == (byte)0x46 && b[22] == (byte)0x69 && b[23] == (byte)0x6C && b[24] == (byte)0x65) {
+ return T_PSP;
+ }
+ }
+ else if (b0 == (byte)0x51 && b1 == (byte)0x4C && b2 == (byte)0x49 && b3 == (byte)0x49 &&
+ b4 == (byte)0x46 && b5 == (byte)0x41 &&
+ b[6] == (byte)0x58) {
+ return T_QFX;
+ }
+ else if (b0 == (byte)0x52 && b1 == (byte)0x49 && b2 == (byte)0x58 && b3 == (byte)0x33) {
+ return T_RIX;
+ }
+ else if (b0 == (byte)0x53) {
+ if (b1 == (byte)0x44 && b2 == (byte)0x50 && b3 == (byte)0x58) {
+ return T_DPX;
+ }
+ else if (b1 == (byte)0x49 && b2 == (byte)0x4D && b3 == (byte)0x50 &&
+ b4 == (byte)0x4C && b5 == (byte)0x45 &&
+ b[6] == (byte)0x20 && b[7] == (byte)0x20 && b[8] == (byte)0x3D) {
+ return T_FTS;
+ }
+ else if (b1 == (byte)0x74 && b2 == (byte)0x6F && b3 == (byte)0x72 &&
+ b4 == (byte)0x6D && b5 == (byte)0x33 &&
+ b[6] == (byte)0x44) {
+ return T_SOD;
+ }
+ else if (b1 == (byte)0x80 && b2 == (byte)0xf6 && b3 == (byte)0x34) {
+ return T_PIC;
+ }
+ }
+ else if (b0 == (byte)0x56 && b1 == (byte)0x69 && b2 == (byte)0x73 && b3 == (byte)0x74 &&
+ b4 == (byte)0x61 && b5 == (byte)0x20 &&
+ b[6] == (byte)0x44 && b[7] == (byte)0x45 && b[8] == (byte)0x4D && b[9] == (byte)0x20 && b[10] == (byte)0x46 &&
+ b[11] == (byte)0x69 && b[12] == (byte)0x6C && b[13] == (byte)0x65) {
+ return T_DEM;
+ }
+ else if (b0 == (byte)0x57 && b1 == (byte)0x56 && b2 == (byte)0x02 && b3 == (byte)0x00 &&
+ b4 == (byte)0x47 && b5 == (byte)0x45 &&
+ b[6] == (byte)0x00 && b[7] == (byte)0x0E) {
+ return T_LWF;
+ }
+ else if (b0 == (byte)0x59 && b1 == (byte)0xA6 && b2 == (byte)0x6A && b3 == (byte)0x95) {
+ return T_RAS;
+ }
+ else if (b0 == (byte)0x63 && b1 == (byte)0x52 && b2 == (byte)0x01 && b3 == (byte)0x01 &&
+ b4 == (byte)0x38 && b5 == (byte)0x09 &&
+ b[6] == (byte)0x3D && b[7] == (byte)0x00) {
+ return T_PCD;
+ }
+ else if (b0 == (byte)0x65) {
+ if (b1 == (byte)0x02 && b2 == (byte)0x01 && b3 == (byte)0x02) {
+ return T_ECW;
+ }
+ else if (b1 == (byte)0x6C && b2 == (byte)0x6D && b3 == (byte)0x6F) {
+ return T_INFINI_D;
+ }
+ }
+ else if (b0 == (byte)0x69 && b1 == (byte)0x63 && b2 == (byte)0x6E && b3 == (byte)0x73) {
+ return T_ICNS;
+ }
+ else if (b0 == (byte)0x6D && b1 == (byte)0x6F && b2 == (byte)0x6F && b3 == (byte)0x76) {
+ return T_QTM;
+ }
+ else if (b0 == (byte)0x6E) {
+ if (b1 == (byte)0x63 && b2 == (byte)0x6F && b3 == (byte)0x6C &&
+ b4 == (byte)0x73) {
+ return T_HDR;
+ }
+ else if (b1 == (byte)0x66 && b2 == (byte)0x66) {
+ return T_NFF;
+ }
+ else if (b1 == (byte)0x6E && b2 == (byte)0x0A && b3 == (byte)0x00 &&
+ b4 == (byte)0x5E && b5 == (byte)0x00) {
+ return T_NCR;
+ }
+ }
+ else if (b0 == (byte)0x73 && b1 == (byte)0x72 && b2 == (byte)0x63 && b3 == (byte)0x64 &&
+ b4 == (byte)0x6F && b5 == (byte)0x63 &&
+ b[6] == (byte)0x69 && b[7] == (byte)0x64 && b[8] == (byte)0x3A) {
+ return T_CALS;
+ }
+ else if (b0 == (byte)0x7B && b1 == (byte)0x0A && b2 == (byte)0x20 && b3 == (byte)0x20 &&
+ b4 == (byte)0x43 && b5 == (byte)0x72 &&
+ b[6] == (byte)0x65 && b[7] == (byte)0x61 && b[8] == (byte)0x74 && b[9] == (byte)0x65 && b[10] == (byte)0x64) {
+ return T_MIF;
+ }
+ else if (b0 == (byte)0x7E && b1 == (byte)0x42 && b2 == (byte)0x4B && b3 == (byte)0x00) {
+ return T_PSP;
+ }
+ else if (b0 == (byte)0x80) {
+ if (b1 == (byte)0x2A && b2 == (byte)0x5F && b3 == (byte)0xD7 &&
+ b4 == (byte)0x00 && b5 == (byte)0x00 &&
+ b[6] == (byte)0x08 && b[7] == (byte)0x00 && b[8] == (byte)0x00 && b[9] == (byte)0x00 && b[10] == (byte)0x04 &&
+ b[11] == (byte)0x00 && b[12] == (byte)0x00 && b[13] == (byte)0x00) {
+ return T_CIN;
+ }
+ else if (b1 == (byte)0x3E && b2 == (byte)0x44 && b3 == (byte)0x53 &&
+ b4 == (byte)0x43 && b5 == (byte)0x49 &&
+ b[6] == (byte)0x4D) {
+ return T_J6I;
+ }
+ }
+ else if (b0 == (byte)0x89 && b1 == (byte)0x50 && b2 == (byte)0x4E && b3 == (byte)0x47 && /* 'P' 'N' 'G', ascii code */
+ b4 == (byte)0x0D && b5 == (byte)0x0A && b[6] == (byte)0x1A && b[7] == (byte)0x0A) {
+ // -119, 80, 78, 71, 13, 10, 26, 10
+ return T_PNG;
+ }
+ else if (b0 == (byte)0x8A && b1 == (byte)0x4D && b2 == (byte)0x4E && b3 == (byte)0x47 &&
+ b4 == (byte)0x0D && b5 == (byte)0x0A &&
+ b[6] == (byte)0x1A && b[7] == (byte)0x0A) {
+ return T_MNG;
+ }
+ else if (b0 == (byte)0xD0 && b1 == (byte)0xCF && b2 == (byte)0x11 && b3 == (byte)0xE0 &&
+ b4 == (byte)0xA1 && b5 == (byte)0xB1 &&
+ b[6] == (byte)0x1A && b[7] == (byte)0xE1 && b[8] == (byte)0x00) {
+ return T_FPX;
+ }
+ else if (b0 == (byte)0xD3 && b1 == (byte)0x23 && b2 == (byte)0x00 && b3 == (byte)0x00 &&
+ b4 == (byte)0x03 && b5 == (byte)0x00 &&
+ b[6] == (byte)0x00 && b[7] == (byte)0x00) {
+ return T_WLM;
+ }
+ else if (b0 == (byte)0xD7 && b1 == (byte)0xCD && b2 == (byte)0xC6 && b3 == (byte)0x9A) {
+ return T_WMF;
+ }
+ else if (b0 == (byte)0xEB && b1 == (byte)0x3C && b2 == (byte)0x90 && b3 == (byte)0x2A) {
+ return T_IMG;
+ }
+ else if (b0 == (byte)0xFA && b1 == (byte)0xDE && b2 == (byte)0xBA && b3 == (byte)0xBE &&
+ b4 == (byte)0x01 && b5 == (byte)0x01) {
+ return T_WIC;
+ }
+ else if (b0 == (byte)0xFF) {
+ if (b1 == (byte)0xD8 /* && b2 == (byte)0xff */) {
+ /**
+ * (b0 == (byte)0x45 && b1 == (byte)0x78 && b2 == (byte)0x69 && b3 == (byte)0x66) || // EXIF
+ * (b0 == (byte)0x4A && b1 == (byte)0x46 && b2 == (byte)0x49 && b3 == (byte)0x46) || // JFIF
+ * (b0 == (byte)0xff && b1 == (byte)0xd8 ) // && b2 == (byte)0xff
+ */
+ return T_JPG;
+ }
+ else if (b1 == (byte)0x57 && b2 == (byte)0x50 && b3 == (byte)0x43 && b4 == (byte)0x10) {
+ return T_WPG;
+ }
+ }
+ return null;
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
index 18a7527b6..bdaa2d792 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
@@ -163,8 +163,10 @@ import com.jogamp.opengl.util.texture.spi.*;
* @author Chris Campbell, Kenneth Russell, et.al.
*/
public class Texture {
- /** The GL target type. */
+ /** The GL target type for this texture. */
private int target;
+ /** The image GL target type for this texture, or its sub-components if cubemap. */
+ private int imageTarget;
/** The GL texture ID. */
private int texID;
/** The width of the texture. */
@@ -190,7 +192,8 @@ public class Texture {
@Override
public String toString() {
- return "Texture[target 0x"+Integer.toHexString(target)+", name "+texID+", "+
+ final String targetS = target == imageTarget ? Integer.toHexString(target) : Integer.toHexString(target) + " - image "+Integer.toHexString(imageTarget);
+ return "Texture[target "+targetS+", name "+texID+", "+
imgWidth+"/"+texWidth+" x "+imgHeight+"/"+texHeight+", y-flip "+mustFlipVertically+
", "+estimatedMemorySize+" bytes]";
}
@@ -206,7 +209,9 @@ public class Texture {
private static final boolean disableTexRect = Debug.isPropertyDefined("jogl.texture.notexrect", true);
public Texture(final GL gl, final TextureData data) throws GLException {
- texID = 0;
+ this.texID = 0;
+ this.target = 0;
+ this.imageTarget = 0;
updateImage(gl, data);
}
@@ -217,8 +222,9 @@ public class Texture {
* GL2.GL_TEXTURE_RECTANGLE
*/
public Texture(final int target) {
- texID = 0;
+ this.texID = 0;
this.target = target;
+ this.imageTarget = target;
}
/**
@@ -250,11 +256,14 @@ public class Texture {
final boolean mustFlipVertically) {
this.texID = textureID;
this.target = target;
+ this.imageTarget = target;
this.mustFlipVertically = mustFlipVertically;
this.texWidth = texWidth;
this.texHeight = texHeight;
- aspectRatio = (float) imgWidth / (float) imgHeight;
- setImageSize(imgWidth, imgHeight, target);
+ this.aspectRatio = (float) imgWidth / (float) imgHeight;
+ this.imgWidth = imgWidth;
+ this.imgHeight = imgHeight;
+ this.updateTexCoords();
}
/**
@@ -344,8 +353,6 @@ public class Texture {
/**
* Returns the OpenGL "target" of this texture.
- *
- * @return the OpenGL target of this texture
* @see com.jogamp.opengl.GL#GL_TEXTURE_2D
* @see com.jogamp.opengl.GL2#GL_TEXTURE_RECTANGLE_ARB
*/
@@ -354,6 +361,15 @@ public class Texture {
}
/**
+ * Returns the image OpenGL "target" of this texture, or its sub-components if cubemap.
+ * @see com.jogamp.opengl.GL#GL_TEXTURE_2D
+ * @see com.jogamp.opengl.GL2#GL_TEXTURE_RECTANGLE_ARB
+ */
+ public int getImageTarget() {
+ return imageTarget;
+ }
+
+ /**
* Returns the width of the allocated OpenGL texture in pixels.
* Note that the texture width will be greater than or equal to the
* width of the image contained within.
@@ -438,7 +454,7 @@ public class Texture {
* @return the texture coordinates corresponding to the specified sub-image
*/
public TextureCoords getSubImageTexCoords(final int x1, final int y1, final int x2, final int y2) {
- if (target == GL2.GL_TEXTURE_RECTANGLE_ARB) {
+ if (GL2.GL_TEXTURE_RECTANGLE_ARB == imageTarget) {
if (mustFlipVertically) {
return new TextureCoords(x1, texHeight - y1, x2, texHeight - y2);
} else {
@@ -616,17 +632,17 @@ public class Texture {
texHeight = nextPowerOfTwo(imgHeight);
texTarget = GL.GL_TEXTURE_2D;
}
-
texParamTarget = texTarget;
- setImageSize(imgWidth, imgHeight, texTarget);
+ imageTarget = texTarget;
+ updateTexCoords();
if (targetOverride != 0) {
// Allow user to override auto detection and skip bind step (for
// cubemap construction)
- texTarget = targetOverride;
if (this.target == 0) {
throw new GLException("Override of target failed; no target specified yet");
}
+ texTarget = targetOverride;
texParamTarget = this.target;
gl.glBindTexture(texParamTarget, texID);
} else {
@@ -977,17 +993,8 @@ public class Texture {
return ret;
}
- /**
- * Updates the actual image dimensions; usually only called from
- * <code>updateImage</code>.
- */
- private void setImageSize(final int width, final int height, final int target) {
- imgWidth = width;
- imgHeight = height;
- updateTexCoords();
- }
private void updateTexCoords() {
- if (target == GL2.GL_TEXTURE_RECTANGLE_ARB) {
+ if ( GL2.GL_TEXTURE_RECTANGLE_ARB == imageTarget ) {
if (mustFlipVertically) {
coords = new TextureCoords(0, imgHeight, imgWidth, 0);
} else {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java
index 615d8c24f..5799f95a6 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java
@@ -83,6 +83,9 @@ public class TextureData {
protected GLProfile glProfile;
protected ColorSpace pixelCS = ColorSpace.RGB;
+ // TODO: final, and set via ctor for 2.4.X
+ /* pp */ ImageType srcImageType;
+
/**
* Constructs a new TextureData object with the specified parameters
* and data contained in the given Buffer. The optional Flusher can
@@ -341,6 +344,14 @@ public class TextureData {
/** Used only by subclasses */
protected TextureData(final GLProfile glp) { this.glProfile = glp; this.pixelAttributes = GLPixelAttributes.UNDEF; }
+ /**
+ * Returns the source {@link ImageType} if applicable and known, otherwise {@code null}.
+ * @since 2.3.2
+ */
+ public final ImageType getSourceImageType() {
+ return srcImageType;
+ }
+
/** Returns the width in pixels of the texture data. */
public int getWidth() { return width; }
/** Returns the height in pixels of the texture data. */
@@ -501,8 +512,9 @@ public class TextureData {
@Override
public String toString() {
+ final String optImageType = null != srcImageType ? ", "+srcImageType : "";
return "TextureData["+width+"x"+height+", y-flip "+mustFlipVertically+", internFormat 0x"+Integer.toHexString(internalFormat)+", "+
- pixelAttributes+", border "+border+", estSize "+estimatedMemorySize+", alignment "+alignment+", rowlen "+rowLength;
+ pixelAttributes+", border "+border+", estSize "+estimatedMemorySize+", alignment "+alignment+", rowlen "+rowLength+optImageType;
}
//----------------------------------------------------------------------
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
index 80b195642..2ac7c796d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
@@ -52,8 +52,10 @@ import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import com.jogamp.nativewindow.util.Dimension;
import com.jogamp.nativewindow.util.DimensionImmutable;
@@ -72,6 +74,7 @@ import com.jogamp.common.util.IOUtil;
import com.jogamp.opengl.util.GLPixelStorageModes;
import com.jogamp.opengl.util.PNGPixelRect;
import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes;
+import com.jogamp.opengl.util.texture.ImageType;
import com.jogamp.opengl.util.texture.spi.DDSImage;
import com.jogamp.opengl.util.texture.spi.JPEGImage;
import com.jogamp.opengl.util.texture.spi.NetPbmTextureWriter;
@@ -134,44 +137,60 @@ import com.jogamp.opengl.util.texture.spi.TextureWriter;
public class TextureIO {
/** Constant which can be used as a file suffix to indicate a
- DirectDraw Surface file. */
- public static final String DDS = "dds";
+ DirectDraw Surface file, value {@value}.
+ <p>Alias for {@link ImageType#T_DDS}.</p>
+ */
+ public static final String DDS = ImageType.T_DDS;
- /** Constant which can be used as a file suffix to indicate an SGI
- RGB file. */
+ /**
+ * Constant which can be used as a file suffix to indicate an SGI RGB file, value {@value}.
+ * <p>
+ * Same semantics as {@link ImageType#SGI_RGB} and {@link #SGI_RGB}.
+ * </p>
+ */
public static final String SGI = "sgi";
- /** Constant which can be used as a file suffix to indicate an SGI
- RGB file. */
- public static final String SGI_RGB = "rgb";
+ /** Constant which can be used as a file suffix to indicate an SGI RGB file, value {@value}.
+ <p>Alias for {@link ImageType#T_SGI_RGB}. </p>
+ */
+ public static final String SGI_RGB = ImageType.T_SGI_RGB;
- /** Constant which can be used as a file suffix to indicate a GIF
- file. */
- public static final String GIF = "gif";
+ /** Constant which can be used as a file suffix to indicate a GIF file, value {@value}.
+ <p>Alias for {@link ImageType#T_GIF}.</p>
+ */
+ public static final String GIF = ImageType.T_GIF;
- /** Constant which can be used as a file suffix to indicate a JPEG
- file. */
- public static final String JPG = "jpg";
+ /** Constant which can be used as a file suffix to indicate a JPEG file, value {@value}.
+ <p>Alias for {@link ImageType#T_JPG}.</p>
+ */
+ public static final String JPG = ImageType.T_JPG;
- /** Constant which can be used as a file suffix to indicate a PNG
- file. */
- public static final String PNG = "png";
+ /** Constant which can be used as a file suffix to indicate a PNG file, value {@value}.
+ <p>Alias for {@link ImageType#T_PNG}.</p>
+ */
+ public static final String PNG = ImageType.T_PNG;
- /** Constant which can be used as a file suffix to indicate a Targa
- file. */
- public static final String TGA = "tga";
+ /** Constant which can be used as a file suffix to indicate a Targa file, value {@value}.
+ <p>Alias for {@link ImageType#T_TGA}.</p>
+ */
+ public static final String TGA = ImageType.T_TGA;
- /** Constant which can be used as a file suffix to indicate a TIFF
- file. */
- public static final String TIFF = "tiff";
+ /** Constant which can be used as a file suffix to indicate a TIFF file, value {@value}.
+ <p>Alias for {@link ImageType#T_TIFF}.</p>
+ */
+ public static final String TIFF = ImageType.T_TIFF;
/** Constant which can be used as a file suffix to indicate a PAM
- file, NetPbm magic 7 - binary RGB and RGBA. Write support only. */
- public static final String PAM = "pam";
+ file, NetPbm magic 7 - binary RGB and RGBA. Write support only, value {@value}.
+ <p>Alias for {@link ImageType#T_PAM}.</p>
+ */
+ public static final String PAM = ImageType.T_PAM;
/** Constant which can be used as a file suffix to indicate a PAM
- file, NetPbm magic 6 - binary RGB. Write support only. */
- public static final String PPM = "ppm";
+ file, NetPbm magic 6 - binary RGB. Write support only, value {@value}.
+ <p>Alias for {@link ImageType#T_PPM}.</p>
+ */
+ public static final String PPM = ImageType.T_PPM;
private static final boolean DEBUG = Debug.debug("TextureIO");
@@ -677,16 +696,27 @@ public class TextureIO {
//
/**
- * Adds a TextureProvider to support reading of a new file format.
+ * Adds a {@link TextureProvider} to support reading of a new file format.
* <p>
* The last provider added, will be the first provider to be tested.
* </p>
+ * <p>
+ * The {@link TextureProvider} is being mapped to its supporting {@link ImageType}s
+ * allowing an O(1) association, if {@link TextureProvider#}
+ * </p>
*/
public static void addTextureProvider(final TextureProvider provider) {
// Must always add at the front so the ImageIO provider is last,
// so we don't accidentally use it instead of a user's possibly
// more optimal provider
textureProviders.add(0, provider);
+
+ final ImageType[] imageTypes = provider.getImageTypes();
+ if( null != imageTypes ) {
+ for(int i=0; i<imageTypes.length; i++) {
+ imageType2TextureProvider.put(imageTypes[i], provider);
+ }
+ }
}
/**
@@ -736,6 +766,7 @@ public class TextureIO {
//
private static List<TextureProvider> textureProviders = new ArrayList<TextureProvider>();
+ private static Map<ImageType,TextureProvider> imageType2TextureProvider = new HashMap<ImageType,TextureProvider>();
private static List<TextureWriter> textureWriters = new ArrayList<TextureWriter>();
static {
@@ -787,32 +818,6 @@ public class TextureIO {
}
// Implementation methods
- private static TextureData newTextureDataImpl(final GLProfile glp, final File file,
- final int internalFormat,
- final int pixelFormat,
- final boolean mipmap,
- String fileSuffix) throws IOException {
- if (file == null) {
- throw new IOException("File was null");
- }
-
- fileSuffix = toLowerCase(fileSuffix);
-
- for (final Iterator<TextureProvider> iter = textureProviders.iterator(); iter.hasNext(); ) {
- final TextureProvider provider = iter.next();
- final TextureData data = provider.newTextureData(glp, file,
- internalFormat,
- pixelFormat,
- mipmap,
- fileSuffix);
- if (data != null) {
- return data;
- }
- }
-
- throw new IOException("No suitable reader for given file "+file.getAbsolutePath());
- }
-
private static TextureData newTextureDataImpl(final GLProfile glp, InputStream stream,
final int internalFormat,
final int pixelFormat,
@@ -822,70 +827,97 @@ public class TextureIO {
throw new IOException("Stream was null");
}
- fileSuffix = toLowerCase(fileSuffix);
-
// Note: use of BufferedInputStream works around 4764639/4892246
if (!(stream instanceof BufferedInputStream)) {
stream = new BufferedInputStream(stream);
}
+ // First attempt to use an ImageType mapped TextureProvider for O(1)
+ // using stream parsed data, ignoring the given fileSuffix!
+ try {
+ final ImageType imageType = new ImageType(stream);
+ if( imageType.isDefined() ) {
+ final TextureProvider mappedProvider = imageType2TextureProvider.get(imageType);
+ if( null != mappedProvider ) {
+ final TextureData data = mappedProvider.newTextureData(glp, stream,
+ internalFormat,
+ pixelFormat,
+ mipmap,
+ imageType.type);
+ if (data != null) {
+ data.srcImageType = imageType;
+ return data;
+ }
+ }
+ }
+ } catch (final IOException ioe) {
+ if(DEBUG) {
+ System.err.println("Caught "+ioe.getMessage());
+ ioe.printStackTrace();
+ }
+ }
+
+ fileSuffix = toLowerCase(fileSuffix);
+
for (final Iterator<TextureProvider> iter = textureProviders.iterator(); iter.hasNext(); ) {
final TextureProvider provider = iter.next();
final TextureData data = provider.newTextureData(glp, stream,
- internalFormat,
- pixelFormat,
- mipmap,
- fileSuffix);
+ internalFormat,
+ pixelFormat,
+ mipmap,
+ fileSuffix);
if (data != null) {
+ final ImageType[] imageTypes = provider.getImageTypes();
+ data.srcImageType = null != imageTypes ? imageTypes[0] : null;
return data;
}
}
throw new IOException("No suitable reader for given stream");
}
-
+ private static TextureData newTextureDataImpl(final GLProfile glp, final File file,
+ final int internalFormat,
+ final int pixelFormat,
+ final boolean mipmap,
+ final String fileSuffix) throws IOException {
+ if (file == null) {
+ throw new IOException("File was null");
+ }
+ final InputStream stream = new BufferedInputStream(new FileInputStream(file));
+ try {
+ return newTextureDataImpl( glp, stream, internalFormat, pixelFormat, mipmap,
+ (fileSuffix != null) ? fileSuffix : IOUtil.getFileSuffix(file) );
+ } catch(final IOException ioe) {
+ throw new IOException(ioe.getMessage()+", given file "+file.getAbsolutePath(), ioe);
+ } finally {
+ stream.close();
+ }
+ }
private static TextureData newTextureDataImpl(final GLProfile glp, final URL url,
final int internalFormat,
final int pixelFormat,
final boolean mipmap,
- String fileSuffix) throws IOException {
+ final String fileSuffix) throws IOException {
if (url == null) {
throw new IOException("URL was null");
}
-
- fileSuffix = toLowerCase(fileSuffix);
-
- for (final Iterator<TextureProvider> iter = textureProviders.iterator(); iter.hasNext(); ) {
- final TextureProvider provider = iter.next();
- final TextureData data = provider.newTextureData(glp, url,
- internalFormat,
- pixelFormat,
- mipmap,
- fileSuffix);
- if (data != null) {
- return data;
- }
+ final InputStream stream = new BufferedInputStream(url.openStream());
+ try {
+ return newTextureDataImpl(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix);
+ } catch(final IOException ioe) {
+ throw new IOException(ioe.getMessage()+", given URL "+url, ioe);
+ } finally {
+ stream.close();
}
-
- throw new IOException("No suitable reader for given URL "+url);
}
//----------------------------------------------------------------------
- // DDS provider -- supports files only for now
+ // DDS image provider
static class DDSTextureProvider implements TextureProvider {
+ private static final ImageType[] imageTypes = new ImageType[] { new ImageType(ImageType.T_DDS) };
@Override
- public TextureData newTextureData(final GLProfile glp, final File file,
- final int internalFormat,
- final int pixelFormat,
- final boolean mipmap,
- final String fileSuffix) throws IOException {
- if (DDS.equals(fileSuffix) ||
- DDS.equals(IOUtil.getFileSuffix(file))) {
- final DDSImage image = DDSImage.read(file);
- return newTextureData(glp, image, internalFormat, pixelFormat, mipmap);
- }
-
- return null;
+ public final ImageType[] getImageTypes() {
+ return imageTypes;
}
@Override
@@ -894,8 +926,8 @@ public class TextureIO {
final int pixelFormat,
final boolean mipmap,
final String fileSuffix) throws IOException {
- if (DDS.equals(fileSuffix) ||
- DDS.equals(ImageIOUtil.getFileSuffix(stream))) {
+ if (ImageType.T_DDS.equals(fileSuffix) ||
+ ImageType.T_DDS.equals(ImageType.Util.getFileSuffix(stream))) {
final byte[] data = IOUtil.copyStream2ByteArray(stream);
final ByteBuffer buf = ByteBuffer.wrap(data);
final DDSImage image = DDSImage.read(buf);
@@ -905,20 +937,6 @@ public class TextureIO {
return null;
}
- @Override
- public TextureData newTextureData(final GLProfile glp, final URL url,
- final int internalFormat,
- final int pixelFormat,
- final boolean mipmap,
- final String fileSuffix) throws IOException {
- final InputStream stream = new BufferedInputStream(url.openStream());
- try {
- return newTextureData(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix);
- } finally {
- stream.close();
- }
- }
-
private TextureData newTextureData(final GLProfile glp, final DDSImage image,
int internalFormat,
int pixelFormat,
@@ -1003,47 +1021,14 @@ public class TextureIO {
}
//----------------------------------------------------------------------
- // Base class for SGI RGB and TGA image providers
- static abstract class StreamBasedTextureProvider implements TextureProvider {
- @Override
- public TextureData newTextureData(final GLProfile glp, final File file,
- final int internalFormat,
- final int pixelFormat,
- final boolean mipmap,
- final String fileSuffix) throws IOException {
- final InputStream inStream = new BufferedInputStream(new FileInputStream(file));
- try {
- // The SGIImage and TGAImage implementations use InputStreams
- // anyway so there isn't much point in having a separate code
- // path for files
- return newTextureData(glp, inStream,
- internalFormat,
- pixelFormat,
- mipmap,
- ((fileSuffix != null) ? fileSuffix : IOUtil.getFileSuffix(file)));
- } finally {
- inStream.close();
- }
- }
-
+ // SGI RGB image provider
+ static class SGITextureProvider implements TextureProvider {
+ private static final ImageType[] imageTypes = new ImageType[] { new ImageType(ImageType.T_SGI_RGB) };
@Override
- public TextureData newTextureData(final GLProfile glp, final URL url,
- final int internalFormat,
- final int pixelFormat,
- final boolean mipmap,
- final String fileSuffix) throws IOException {
- final InputStream stream = new BufferedInputStream(url.openStream());
- try {
- return newTextureData(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix);
- } finally {
- stream.close();
- }
+ public final ImageType[] getImageTypes() {
+ return imageTypes;
}
- }
- //----------------------------------------------------------------------
- // SGI RGB image provider
- static class SGITextureProvider extends StreamBasedTextureProvider {
@Override
public TextureData newTextureData(final GLProfile glp, final InputStream stream,
int internalFormat,
@@ -1051,9 +1036,9 @@ public class TextureIO {
final boolean mipmap,
final String fileSuffix) throws IOException {
if (SGI.equals(fileSuffix) ||
- SGI_RGB.equals(fileSuffix) ||
- SGI.equals(ImageIOUtil.getFileSuffix(stream)) ||
- SGI_RGB.equals(ImageIOUtil.getFileSuffix(stream))) {
+ ImageType.T_SGI_RGB.equals(fileSuffix) ||
+ SGI.equals(ImageType.Util.getFileSuffix(stream)) ||
+ ImageType.T_SGI_RGB.equals(ImageType.Util.getFileSuffix(stream))) {
final SGIImage image = SGIImage.read(stream);
if (pixelFormat == 0) {
pixelFormat = image.getFormat();
@@ -1080,14 +1065,20 @@ public class TextureIO {
//----------------------------------------------------------------------
// TGA (Targa) image provider
- static class TGATextureProvider extends StreamBasedTextureProvider {
+ static class TGATextureProvider implements TextureProvider {
+ private static final ImageType[] imageTypes = new ImageType[] { new ImageType(ImageType.T_TGA) };
+ @Override
+ public final ImageType[] getImageTypes() {
+ return imageTypes;
+ }
+
@Override
public TextureData newTextureData(final GLProfile glp, final InputStream stream,
int internalFormat,
int pixelFormat,
final boolean mipmap,
final String fileSuffix) throws IOException {
- if (TGA.equals(fileSuffix)) {
+ if (ImageType.T_TGA.equals(fileSuffix)) {
final TGAImage image = TGAImage.read(glp, stream);
if (pixelFormat == 0) {
pixelFormat = image.getGLFormat();
@@ -1118,15 +1109,21 @@ public class TextureIO {
//----------------------------------------------------------------------
// PNG image provider
- static class PNGTextureProvider extends StreamBasedTextureProvider {
+ static class PNGTextureProvider implements TextureProvider {
+ private static final ImageType[] imageTypes = new ImageType[] { new ImageType(ImageType.T_PNG) };
+ @Override
+ public final ImageType[] getImageTypes() {
+ return imageTypes;
+ }
+
@Override
public TextureData newTextureData(final GLProfile glp, final InputStream stream,
int internalFormat,
int pixelFormat,
final boolean mipmap,
final String fileSuffix) throws IOException {
- if (PNG.equals(fileSuffix) ||
- PNG.equals(ImageIOUtil.getFileSuffix(stream))) {
+ if (ImageType.T_PNG.equals(fileSuffix) ||
+ ImageType.T_PNG.equals(ImageType.Util.getFileSuffix(stream))) {
final PNGPixelRect image = PNGPixelRect.read(stream, null, true /* directBuffer */, 0 /* destMinStrideInBytes */, true /* destIsGLOriented */);
final GLPixelAttributes glpa = new GLPixelAttributes(glp, image.getPixelformat(), false /* pack */);
if ( 0 == pixelFormat ) {
@@ -1159,15 +1156,21 @@ public class TextureIO {
//----------------------------------------------------------------------
// JPEG image provider
- static class JPGTextureProvider extends StreamBasedTextureProvider {
+ static class JPGTextureProvider implements TextureProvider {
+ private static final ImageType[] imageTypes = new ImageType[] { new ImageType(ImageType.T_JPG) };
+ @Override
+ public final ImageType[] getImageTypes() {
+ return imageTypes;
+ }
+
@Override
public TextureData newTextureData(final GLProfile glp, final InputStream stream,
int internalFormat,
int pixelFormat,
final boolean mipmap,
final String fileSuffix) throws IOException {
- if (JPG.equals(fileSuffix) ||
- JPG.equals(ImageIOUtil.getFileSuffix(stream))) {
+ if (ImageType.T_JPG.equals(fileSuffix) ||
+ ImageType.T_JPG.equals(ImageType.Util.getFileSuffix(stream))) {
final JPEGImage image = JPEGImage.read(/*glp, */ stream);
if (pixelFormat == 0) {
pixelFormat = image.getGLFormat();
@@ -1203,7 +1206,7 @@ public class TextureIO {
@Override
public boolean write(final File file,
final TextureData data) throws IOException {
- if (DDS.equals(IOUtil.getFileSuffix(file))) {
+ if (ImageType.T_DDS.equals(IOUtil.getFileSuffix(file))) {
// See whether the DDS writer can handle this TextureData
final GLPixelAttributes pixelAttribs = data.getPixelAttributes();
final int pixelFormat = pixelAttribs.format;
@@ -1256,7 +1259,7 @@ public class TextureIO {
final TextureData data) throws IOException {
final String fileSuffix = IOUtil.getFileSuffix(file);
if (SGI.equals(fileSuffix) ||
- SGI_RGB.equals(fileSuffix)) {
+ ImageType.T_SGI_RGB.equals(fileSuffix)) {
// See whether the SGI writer can handle this TextureData
final GLPixelAttributes pixelAttribs = data.getPixelAttributes();
final int pixelFormat = pixelAttribs.format;
@@ -1300,7 +1303,7 @@ public class TextureIO {
@Override
public boolean write(final File file,
final TextureData data) throws IOException {
- if (TGA.equals(IOUtil.getFileSuffix(file))) {
+ if (ImageType.T_TGA.equals(IOUtil.getFileSuffix(file))) {
// See whether the TGA writer can handle this TextureData
final GLPixelAttributes pixelAttribs = data.getPixelAttributes();
final int pixelFormat = pixelAttribs.format;
@@ -1350,7 +1353,7 @@ public class TextureIO {
static class PNGTextureWriter implements TextureWriter {
@Override
public boolean write(final File file, final TextureData data) throws IOException {
- if (PNG.equals(IOUtil.getFileSuffix(file))) {
+ if (ImageType.T_PNG.equals(IOUtil.getFileSuffix(file))) {
// See whether the PNG writer can handle this TextureData
final GLPixelAttributes pixelAttribs = data.getPixelAttributes();
final int pixelFormat = pixelAttribs.format;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java
index 36c44a409..246676aae 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java
@@ -53,8 +53,7 @@ import java.nio.channels.FileChannel;
import com.jogamp.opengl.GL;
import com.jogamp.common.nio.Buffers;
import com.jogamp.common.util.IOUtil;
-import com.jogamp.opengl.util.GLBuffers;
-import com.jogamp.opengl.util.texture.ImageIOUtil;
+import com.jogamp.opengl.util.texture.ImageType;
/** A reader and writer for DirectDraw Surface (.dds) files, which are
used to describe textures. These files can contain multiple mipmap
@@ -238,38 +237,6 @@ public class DDSImage {
return image;
}
- /** Determines from the magic number whether the given InputStream
- points to a DDS image. The given InputStream must return true
- from markSupported() and support a minimum of four bytes of
- read-ahead.
-
- @param in Stream to check
- @return true if input stream is DDS image or false otherwise
- @throws java.io.IOException if an I/O exception occurred
- @deprecated rather call {@link ImageIOUtil#getFileSuffix(InputStream)}
- */
- @Deprecated
- public static boolean isDDSImage(InputStream in) throws IOException {
- if (!(in instanceof BufferedInputStream)) {
- in = new BufferedInputStream(in);
- }
- if (!in.markSupported()) {
- throw new IOException("Can not test non-destructively whether given InputStream is a DDS image");
- }
- in.mark(4);
- int magic = 0;
- for (int i = 0; i < 4; i++) {
- final int tmp = in.read();
- if (tmp < 0) {
- in.reset();
- return false;
- }
- magic = ((magic >>> 8) | (tmp << 24));
- }
- in.reset();
- return (magic == MAGIC);
- }
-
/**
* Writes this DDSImage to the specified file name.
* @param filename File name to write to
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java
index ff8167bb0..47e40e367 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java
@@ -42,7 +42,7 @@ package com.jogamp.opengl.util.texture.spi;
import java.io.*;
import com.jogamp.opengl.*;
-import com.jogamp.opengl.util.texture.ImageIOUtil;
+import com.jogamp.opengl.util.texture.ImageType;
import com.jogamp.common.util.IOUtil;
/** <p> Reads and writes SGI RGB/RGBA images. </p>
@@ -191,28 +191,6 @@ public class SGIImage {
return image;
}
- /**
- * Determines from the magic number whether the given InputStream points to
- * an SGI RGB image. The given InputStream must return true from
- * markSupported() and support a minimum of two bytes of read-ahead.
- *
- * @deprecated rather call {@link ImageIOUtil#getFileSuffix(InputStream)}
- */
- @Deprecated
- public static boolean isSGIImage(InputStream in) throws IOException {
- if (!(in instanceof BufferedInputStream)) {
- in = new BufferedInputStream(in);
- }
- if (!in.markSupported()) {
- throw new IOException("Can not test non-destructively whether given InputStream is an SGI RGB image");
- }
- final DataInputStream dIn = new DataInputStream(in);
- dIn.mark(4);
- final short magic = dIn.readShort();
- dIn.reset();
- return (magic == MAGIC);
- }
-
/** Returns the width of the image. */
public int getWidth() {
return header.xsize;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java
index e84f300e2..485a1b82d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2015 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -39,11 +40,13 @@
package com.jogamp.opengl.util.texture.spi;
-import java.io.*;
-import java.net.*;
+import java.io.IOException;
+import java.io.InputStream;
+
import com.jogamp.opengl.GLProfile;
+import com.jogamp.opengl.util.texture.ImageType;
+import com.jogamp.opengl.util.texture.TextureData;
-import com.jogamp.opengl.util.texture.*;
/** Plug-in interface to TextureIO to support reading OpenGL textures
from new file formats. For all methods, either internalFormat or
@@ -54,43 +57,24 @@ import com.jogamp.opengl.util.texture.*;
public interface TextureProvider {
/**
- * Produces a TextureData object from a file, or returns null if the
- * file format was not supported by this TextureProvider. Does not
- * do any OpenGL-related work. The resulting TextureData can be
- * converted into an OpenGL texture in a later step.
- *
- * @param glp the OpenGL Profile this texture data should be
- * created for.
- * @param file the file from which to read the texture data
- *
- * @param internalFormat the OpenGL internal format to be used for
- * the texture, or 0 if it should be inferred
- * from the file's contents
- *
- * @param pixelFormat the OpenGL pixel format to be used for
- * the texture, or 0 if it should be inferred
- * from the file's contents
- *
- * @param mipmap whether mipmaps should be produced for this
- * texture either by autogenerating them or
- * reading them from the file. Some file formats
- * support multiple mipmaps in a single file in
- * which case those mipmaps will be used rather
- * than generating them.
- *
- * @param fileSuffix the file suffix to be used as a hint to the
- * provider to more quickly decide whether it
- * can handle the file, or null if the
- * provider should infer the type from the
- * file's contents
- *
- * @throws IOException if an error occurred while reading the file
+ * Optional additional interface for {@link TextureProvider} implementation
+ * exposing the supported {@link ImageType}s.
+ * <p>
+ * Use case: Mapping of {@link ImageType}s to {@link TextureProvider}.
+ * </p>
*/
- public TextureData newTextureData(GLProfile glp, File file,
- int internalFormat,
- int pixelFormat,
- boolean mipmap,
- String fileSuffix) throws IOException;
+ public static interface SupportsImageTypes {
+ /** Returns the supported {@link ImageType}s. */
+ ImageType[] getImageTypes();
+ }
+
+ /**
+ * Returns the known supported {@link ImageType}s, or {@code null} if unknown.
+ * <p>
+ * Use case: Mapping of {@link ImageType}s to {@link TextureProvider}.
+ * </p>
+ */
+ ImageType[] getImageTypes();
/**
* Produces a TextureData object from a stream, or returns null if
@@ -130,43 +114,4 @@ public interface TextureProvider {
int pixelFormat,
boolean mipmap,
String fileSuffix) throws IOException;
-
- /**
- * Produces a TextureData object from a URL, or returns null if the
- * file format was not supported by this TextureProvider. Does not
- * do any OpenGL-related work. The resulting TextureData can be
- * converted into an OpenGL texture in a later step.
- *
- * @param glp the OpenGL Profile this texture data should be
- * created for.
- * @param url the URL from which to read the texture data
- *
- * @param internalFormat the OpenGL internal format to be used for
- * the texture, or 0 if it should be inferred
- * from the file's contents
- *
- * @param pixelFormat the OpenGL pixel format to be used for
- * the texture, or 0 if it should be inferred
- * from the file's contents
- *
- * @param mipmap whether mipmaps should be produced for this
- * texture either by autogenerating them or
- * reading them from the file. Some file formats
- * support multiple mipmaps in a single file in
- * which case those mipmaps will be used rather
- * than generating them.
- *
- * @param fileSuffix the file suffix to be used as a hint to the
- * provider to more quickly decide whether it
- * can handle the file, or null if the
- * provider should infer the type from the
- * file's contents
- *
- * @throws IOException if an error occurred while reading the URL
- */
- public TextureData newTextureData(GLProfile glp, URL url,
- int internalFormat,
- int pixelFormat,
- boolean mipmap,
- String fileSuffix) throws IOException;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java
index ba762baf3..8ee54899c 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2015 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -36,39 +37,29 @@
* Sun gratefully acknowledges that this software was originally authored
* and developed by Kenneth Bradley Russell and Christopher John Kline.
*/
-
+//
package com.jogamp.opengl.util.texture.spi.awt;
-import java.awt.Graphics;
-import java.awt.image.*;
-import java.io.*;
-import java.net.*;
-import javax.imageio.*;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.imageio.ImageIO;
+
import com.jogamp.opengl.GLProfile;
+import com.jogamp.opengl.util.texture.ImageType;
+import com.jogamp.opengl.util.texture.TextureData;
+import com.jogamp.opengl.util.texture.awt.AWTTextureData;
+import com.jogamp.opengl.util.texture.spi.TextureProvider;
import jogamp.opengl.Debug;
-import com.jogamp.opengl.util.texture.*;
-import com.jogamp.opengl.util.texture.awt.*;
-import com.jogamp.opengl.util.texture.spi.*;
public class IIOTextureProvider implements TextureProvider {
private static final boolean DEBUG = Debug.debug("TextureIO");
@Override
- public TextureData newTextureData(final GLProfile glp, final File file,
- final int internalFormat,
- final int pixelFormat,
- final boolean mipmap,
- final String fileSuffix) throws IOException {
- final BufferedImage img = ImageIO.read(file);
- if (img == null) {
- return null;
- }
- if (DEBUG) {
- System.out.println("TextureIO.newTextureData(): BufferedImage type for " + file + " = " +
- img.getType());
- }
- return new AWTTextureData(glp, internalFormat, pixelFormat, mipmap, img);
+ public final ImageType[] getImageTypes() {
+ return null;
}
@Override
@@ -87,18 +78,4 @@ public class IIOTextureProvider implements TextureProvider {
}
return new AWTTextureData(glp, internalFormat, pixelFormat, mipmap, img);
}
-
- @Override
- public TextureData newTextureData(final GLProfile glp, final URL url,
- final int internalFormat,
- final int pixelFormat,
- final boolean mipmap,
- final String fileSuffix) throws IOException {
- final InputStream stream = url.openStream();
- try {
- return newTextureData(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix);
- } finally {
- stream.close();
- }
- }
}
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);
diff --git a/src/jogl/native/GLDebugMessageHandler.c b/src/jogl/native/GLDebugMessageHandler.c
index 5c18b94b1..e524df9bf 100644
--- a/src/jogl/native/GLDebugMessageHandler.c
+++ b/src/jogl/native/GLDebugMessageHandler.c
@@ -17,6 +17,7 @@
#define DBG_PRINT(...)
#endif
+// Note: 'ARB' is also used for 'KHR'!
static jmethodID glDebugMessageARB = NULL; // int source, int type, int id, int severity, String msg
static jmethodID glDebugMessageAMD = NULL; // int id, int category, int severity, String msg
@@ -120,7 +121,8 @@ JNIEXPORT jlong JNICALL Java_jogamp_opengl_GLDebugMessageHandler_register0
handle->extType = extType;
DBG_PRINT("GLDebugMessageHandler.register0: jobject %p, extType %d\n", (void*)handle->obj, handle->extType);
- if(jogamp_opengl_GLDebugMessageHandler_EXT_ARB == extType) {
+ if(jogamp_opengl_GLDebugMessageHandler_EXT_KHR == extType ||
+ jogamp_opengl_GLDebugMessageHandler_EXT_ARB == extType) {
_local_PFNGLDEBUGMESSAGECALLBACKARBPROC ptr_glDebugMessageCallbackARB;
ptr_glDebugMessageCallbackARB = (_local_PFNGLDEBUGMESSAGECALLBACKARBPROC) (intptr_t) procAddress;
ptr_glDebugMessageCallbackARB((_local_GLDEBUGPROCARB)GLDebugMessageARBCallback, handle);
@@ -151,7 +153,8 @@ JNIEXPORT void JNICALL Java_jogamp_opengl_GLDebugMessageHandler_unregister0
JoglCommon_throwNewRuntimeException(env, "wrong handle (obj doesn't match)");
}
- if(jogamp_opengl_GLDebugMessageHandler_EXT_ARB == handle->extType) {
+ if(jogamp_opengl_GLDebugMessageHandler_EXT_KHR == handle->extType ||
+ jogamp_opengl_GLDebugMessageHandler_EXT_ARB == handle->extType) {
_local_PFNGLDEBUGMESSAGECALLBACKARBPROC ptr_glDebugMessageCallbackARB;
ptr_glDebugMessageCallbackARB = (_local_PFNGLDEBUGMESSAGECALLBACKARBPROC) (intptr_t) procAddress;
ptr_glDebugMessageCallbackARB((_local_GLDEBUGPROCARB)NULL, NULL);
diff --git a/src/jogl/native/libav/ffmpeg_impl_template.c b/src/jogl/native/libav/ffmpeg_impl_template.c
index ca283ef52..d02770eb7 100644
--- a/src/jogl/native/libav/ffmpeg_impl_template.c
+++ b/src/jogl/native/libav/ffmpeg_impl_template.c
@@ -622,6 +622,7 @@ static const char * inFmtNames[] = {
"video4linux", // linux (old)
"dshow", // windows
"vfwcap", // windows (old)
+ "avfoundation", // osx
"mpg",
"yuv2",
"mjpeg",
@@ -732,6 +733,9 @@ JNIEXPORT void JNICALL FF_FUNC(setStream0)
fprintf(stderr, "Camera %d not found\n", devIdx);
}
}
+ if(pAV->verbose) {
+ fprintf(stderr, "Camera: Filename: %s\n", filename);
+ }
const char *sizeS = NULL != jSizeS ? (*env)->GetStringUTFChars(env, jSizeS, &iscopy) : NULL;
int hasSize = 0;
@@ -756,6 +760,7 @@ JNIEXPORT void JNICALL FF_FUNC(setStream0)
}
sp_av_dict_set(&inOpts, "framerate", buffer, 0);
}
+ // FIXME pre-select: sp_av_dict_set(&inOpts, "pixel_format", "yuyv422", 0);
}
MY_MUTEX_LOCK(env, mutex_avcodec_openclose);
@@ -1148,8 +1153,10 @@ JNIEXPORT void JNICALL FF_FUNC(setStream0)
#endif
} else {
vLinesize[0] = pAV->pVFrame->linesize[0];
- if( pAV->vPixFmt == PIX_FMT_YUYV422 ) {
- // Stuff 2x 16bpp (YUYV) into one RGBA pixel!
+ if( pAV->vPixFmt == PIX_FMT_YUYV422 ||
+ pAV->vPixFmt == PIX_FMT_UYVY422 )
+ {
+ // Stuff 2x 16bpp (YUYV, UYVY) into one RGBA pixel!
pAV->vTexWidth[0] = pAV->pVCodecCtx->width / 2;
} else {
pAV->vTexWidth[0] = pAV->pVCodecCtx->width;