aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/com')
-rw-r--r--src/jogl/classes/com/jogamp/audio/windows/waveout/Mixer.java239
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLAnimatorControl.java3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/awt/GLJPanel.java3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/Animator.java23
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java5
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java3
6 files changed, 149 insertions, 127 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/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/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/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..41b969551 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
@@ -40,6 +40,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>
@@ -596,7 +597,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/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();