diff options
author | Sven Gothel <[email protected]> | 2015-03-27 15:10:54 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2015-03-27 15:10:54 +0100 |
commit | ee2c18211a5128f5cde5312a7bbb5c0e80674903 (patch) | |
tree | 57ed742992fbe65c0e4cb501433c65a8c0775508 | |
parent | d09a50bdc7aca2d441fe7c595711a44fe9dc4a23 (diff) |
Bug 1116: Add ShutdownHook for all factories and devices to StereoDeviceFactory using NativeWindowFactory
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; + } } } |