aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2015-03-27 15:10:54 +0100
committerSven Gothel <[email protected]>2015-03-27 15:10:54 +0100
commitee2c18211a5128f5cde5312a7bbb5c0e80674903 (patch)
tree57ed742992fbe65c0e4cb501433c65a8c0775508
parentd09a50bdc7aca2d441fe7c595711a44fe9dc4a23 (diff)
Bug 1116: Add ShutdownHook for all factories and devices to StereoDeviceFactory using NativeWindowFactory
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDevice.java8
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDeviceFactory.java89
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/stereo/generic/GenericStereoDeviceFactory.java16
-rw-r--r--src/jogl/classes/jogamp/opengl/util/stereo/GenericStereoDevice.java5
-rw-r--r--src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDevice.java13
-rw-r--r--src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDeviceFactory.java17
6 files changed, 133 insertions, 15 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDevice.java b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDevice.java
index 6d8b85d8e..d59863530 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDevice.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDevice.java
@@ -44,10 +44,16 @@ public interface StereoDevice {
/** Return the factory used to create this device. */
public StereoDeviceFactory getFactory();
- /** Disposes this {@link StereoDevice}. */
+ /** Disposes this {@link StereoDevice}, if {@link #isValid() valid}. */
public void dispose();
/**
+ * Returns {@code true}, if instance is created and not {@link #dispose() disposed},
+ * otherwise returns {@code false}.
+ */
+ public boolean isValid();
+
+ /**
* If operation within a device spanning virtual desktop,
* returns the device position.
* <p>
diff --git a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDeviceFactory.java b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDeviceFactory.java
index 3847b7d3e..105fe6c70 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDeviceFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDeviceFactory.java
@@ -27,7 +27,11 @@
*/
package com.jogamp.opengl.util.stereo;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.nativewindow.NativeWindowFactory;
/**
* Platform agnostic {@link StereoDevice} factory.
@@ -44,6 +48,14 @@ public abstract class StereoDeviceFactory {
private static final String OVRStereoDeviceClazzName = "jogamp.opengl.oculusvr.OVRStereoDeviceFactory";
private static final String GenericStereoDeviceClazzName = com.jogamp.opengl.util.stereo.generic.GenericStereoDeviceFactory.class.getName();
private static final String isAvailableMethodName = "isAvailable";
+ static {
+ NativeWindowFactory.addCustomShutdownHook(false /* head */, new Runnable() {
+ @Override
+ public void run() {
+ shutdownAll();
+ }
+ });
+ }
/** {@link StereoDevice} type used for {@link StereoDeviceFactory#createFactory(DeviceType) createFactory(type)}. */
public static enum DeviceType {
@@ -91,12 +103,16 @@ public abstract class StereoDeviceFactory {
}
public static StereoDeviceFactory createFactory(final ClassLoader cl, final String implName) {
+ StereoDeviceFactory res = null;
try {
if(((Boolean)ReflectionUtil.callStaticMethod(implName, isAvailableMethodName, null, null, cl)).booleanValue()) {
- return (StereoDeviceFactory) ReflectionUtil.createInstance(implName, cl);
+ res = (StereoDeviceFactory) ReflectionUtil.createInstance(implName, cl);
}
} catch (final Throwable t) { if(StereoDevice.DEBUG) { System.err.println("Caught "+t.getClass().getName()+": "+t.getMessage()); t.printStackTrace(); } }
- return null;
+ if( null != res ) {
+ addFactory2List(res);
+ }
+ return res;
}
/**
@@ -106,10 +122,75 @@ public abstract class StereoDeviceFactory {
* @param verbose
* @return
*/
- public abstract StereoDevice createDevice(final int deviceIndex, final StereoDeviceConfig config, final boolean verbose);
+ public final StereoDevice createDevice(final int deviceIndex, final StereoDeviceConfig config, final boolean verbose) {
+ final StereoDevice device = createDeviceImpl(deviceIndex, config, verbose);
+ if( null != device ) {
+ addDevice2List(device);
+ }
+ return device;
+ }
+ protected abstract StereoDevice createDeviceImpl(final int deviceIndex, final StereoDeviceConfig config, final boolean verbose);
+
+ /**
+ * Returns {@code true}, if instance is created and not {@link #shutdown()}
+ * otherwise returns {@code false}.
+ */
+ public abstract boolean isValid();
/**
- * Shutdown factory
+ * Shutdown factory if {@link #isValid() valid}.
*/
public abstract void shutdown();
+
+ private static final ArrayList<WeakReference<StereoDeviceFactory>> factoryList = new ArrayList<WeakReference<StereoDeviceFactory>>();
+ private static void addFactory2List(final StereoDeviceFactory factory) {
+ synchronized(factoryList) {
+ // GC before add
+ int i=0;
+ while( i < factoryList.size() ) {
+ if( null == factoryList.get(i).get() ) {
+ factoryList.remove(i);
+ } else {
+ i++;
+ }
+ }
+ factoryList.add(new WeakReference<StereoDeviceFactory>(factory));
+ }
+ }
+ private static final ArrayList<WeakReference<StereoDevice>> deviceList = new ArrayList<WeakReference<StereoDevice>>();
+ private static void addDevice2List(final StereoDevice device) {
+ synchronized(deviceList) {
+ // GC before add
+ int i=0;
+ while( i < deviceList.size() ) {
+ if( null == deviceList.get(i).get() ) {
+ deviceList.remove(i);
+ } else {
+ i++;
+ }
+ }
+ deviceList.add(new WeakReference<StereoDevice>(device));
+ }
+ }
+
+ private final static void shutdownAll() {
+ shutdownDevices();
+ shutdownFactories();
+ }
+ private final static void shutdownFactories() {
+ while( 0 < factoryList.size() ) {
+ final StereoDeviceFactory f = factoryList.remove(0).get();
+ if( null != f && f.isValid() ) {
+ f.shutdown();
+ }
+ }
+ }
+ private final static void shutdownDevices() {
+ while( 0 < deviceList.size() ) {
+ final StereoDevice d = deviceList.remove(0).get();
+ if( null != d && d.isValid() ) {
+ d.dispose();
+ }
+ }
+ }
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/stereo/generic/GenericStereoDeviceFactory.java b/src/jogl/classes/com/jogamp/opengl/util/stereo/generic/GenericStereoDeviceFactory.java
index 9c28c0767..6adb96ba4 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/stereo/generic/GenericStereoDeviceFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/stereo/generic/GenericStereoDeviceFactory.java
@@ -187,12 +187,22 @@ public class GenericStereoDeviceFactory extends StereoDeviceFactory {
}
@Override
- public final StereoDevice createDevice(final int deviceIndex, final StereoDeviceConfig config, final boolean verbose) {
+ protected final StereoDevice createDeviceImpl(final int deviceIndex, final StereoDeviceConfig config, final boolean verbose) {
return new GenericStereoDevice(this, deviceIndex, config);
}
+ private boolean isValid = true;
+
@Override
- public void shutdown() {
- // NOP
+ public boolean isValid() {
+ return isValid;
+ }
+
+ @Override
+ public final void shutdown() {
+ if( isValid ) {
+ // NOP
+ isValid = false;
+ }
}
}
diff --git a/src/jogl/classes/jogamp/opengl/util/stereo/GenericStereoDevice.java b/src/jogl/classes/jogamp/opengl/util/stereo/GenericStereoDevice.java
index 5bfc775fa..9c0a5045b 100644
--- a/src/jogl/classes/jogamp/opengl/util/stereo/GenericStereoDevice.java
+++ b/src/jogl/classes/jogamp/opengl/util/stereo/GenericStereoDevice.java
@@ -157,6 +157,11 @@ public class GenericStereoDevice implements StereoDevice {
}
@Override
+ public boolean isValid() {
+ return true;
+ }
+
+ @Override
public final PointImmutable getPosition() {
return surfacePos;
}
diff --git a/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDevice.java b/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDevice.java
index fda554fdd..3abea5839 100644
--- a/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDevice.java
+++ b/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDevice.java
@@ -128,9 +128,16 @@ public class OVRStereoDevice implements StereoDevice {
@Override
public final void dispose() {
- OVR.ovrHmd_Destroy(hmdDesc);
- hmdDesc = null;
- handle = null;
+ if( isValid() ) {
+ OVR.ovrHmd_Destroy(hmdDesc);
+ hmdDesc = null;
+ handle = null;
+ }
+ }
+
+ @Override
+ public boolean isValid() {
+ return null != hmdDesc && null != handle;
}
@Override
diff --git a/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDeviceFactory.java b/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDeviceFactory.java
index eecc15c3f..772891115 100644
--- a/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDeviceFactory.java
+++ b/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDeviceFactory.java
@@ -63,12 +63,14 @@ public class OVRStereoDeviceFactory extends StereoDeviceFactory {
return false;
}
+ private boolean isValid = true;
+
private void dumpCaps(final ovrHmdDesc hmdDesc, final int deviceIndex) {
System.err.println(OVRVersion.getAvailableCapabilitiesInfo(hmdDesc, deviceIndex, null).toString());
}
@Override
- public final StereoDevice createDevice(final int deviceIndex, final StereoDeviceConfig config, final boolean verbose) {
+ protected final StereoDevice createDeviceImpl(final int deviceIndex, final StereoDeviceConfig config, final boolean verbose) {
final ovrHmdDesc hmdDesc = OVR.ovrHmd_Create(deviceIndex);
if( null == hmdDesc ) {
if( verbose ) {
@@ -86,12 +88,19 @@ public class OVRStereoDeviceFactory extends StereoDeviceFactory {
if( verbose ) {
dumpCaps(hmdDesc, deviceIndex);
}
- final OVRStereoDevice ctx = new OVRStereoDevice(this, hmdDesc, deviceIndex);
- return ctx;
+ return new OVRStereoDevice(this, hmdDesc, deviceIndex);
+ }
+
+ @Override
+ public boolean isValid() {
+ return isValid;
}
@Override
public final void shutdown() {
- OVR.ovr_Shutdown();
+ if( isValid ) {
+ OVR.ovr_Shutdown();
+ isValid = false;
+ }
}
}