diff options
author | Sven Gothel <[email protected]> | 2013-07-04 20:19:35 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-07-04 20:19:35 +0200 |
commit | 99479bf3197cde8e89c5b499d135417863d521c7 (patch) | |
tree | fd4ae1f0532c750a3ac02af2edb74ed83ebf0743 /src/newt/classes/jogamp | |
parent | 1d9e043f6e0acba2dde9d4afd57bc75141ed050f (diff) |
NEWT: Using WeakReferences for global cache of Display, Screen and Window instances; Removing ref. at API destroy() is wrong ; Allow GC to clear ..
- Removing ref. at API destroy() is wrong
- Since all instances can be recreated, removing ref at destroy() is simply wrong.
- Keep weak references until GC collects, i.e. user does not claim them anymore.
- Safe for Display, since it holds it's EDT thread.
- Window/Screen .. if user abandons reference .. nothing we can do here.
- Allow GC to clear ..
No need to hold ref loonger than user.
Diffstat (limited to 'src/newt/classes/jogamp')
-rw-r--r-- | src/newt/classes/jogamp/newt/DisplayImpl.java | 60 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/ScreenImpl.java | 29 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/WindowImpl.java | 33 |
3 files changed, 68 insertions, 54 deletions
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java index 0d1dcf5ab..bb493cbbd 100644 --- a/src/newt/classes/jogamp/newt/DisplayImpl.java +++ b/src/newt/classes/jogamp/newt/DisplayImpl.java @@ -41,6 +41,7 @@ import com.jogamp.newt.event.NEWTEventConsumer; import jogamp.newt.event.NEWTEventTask; import com.jogamp.newt.util.EDTUtil; + import java.util.ArrayList; import javax.media.nativewindow.AbstractGraphicsDevice; @@ -96,7 +97,7 @@ public abstract class DisplayImpl extends Display { display.id = serialno++; display.fqname = getFQName(display.type, display.name, display.id); display.hashCode = display.fqname.hashCode(); - displayList.add(display); + Display.addDisplay2List(display); } display.setEDTUtil(display.edtUtil); // device's default if EDT is used, or null @@ -155,11 +156,11 @@ public abstract class DisplayImpl extends Display { if(null==aDevice) { throw new NativeWindowException("Display.createNative() failed to instanciate an AbstractGraphicsDevice"); } - if(DEBUG) { - System.err.println("Display.createNative() END ("+getThreadName()+", "+this+")"); - } synchronized(displayList) { displaysActive++; + if(DEBUG) { + System.err.println("Display.createNative() END ("+getThreadName()+", "+this+", active "+displaysActive+")"); + } } } } @@ -238,13 +239,12 @@ public abstract class DisplayImpl extends Display { dumpDisplayList("Display.destroy("+getFQName()+") BEGIN"); } synchronized(displayList) { - displayList.remove(this); if(0 < displaysActive) { displaysActive--; } - } - if(DEBUG) { - System.err.println("Display.destroy(): "+this+" "+getThreadName()); + if(DEBUG) { + System.err.println("Display.destroy(): "+this+", active "+displaysActive+" "+getThreadName()); + } } final DisplayImpl f_dpy = this; removeEDT( new Runnable() { // blocks! @@ -268,32 +268,34 @@ public abstract class DisplayImpl extends Display { dumpDisplayList("Display.shutdownAll "+dCount+" instances, on thread "+getThreadName()); } for(int i=0; i<dCount && displayList.size()>0; i++) { // be safe .. - final DisplayImpl d = (DisplayImpl) displayList.remove(0); - if(0 < displaysActive) { - displaysActive--; - } + final DisplayImpl d = (DisplayImpl) displayList.remove(0).get(); if(DEBUG) { - System.err.println("Display.shutdownAll["+(i+1)+"/"+dCount+"]: "+d); + System.err.println("Display.shutdownAll["+(i+1)+"/"+dCount+"]: "+d+", GCed "+(null==d)); } - final Runnable closeNativeTask = new Runnable() { - public void run() { - if ( null != d.getGraphicsDevice() ) { - d.closeNativeImpl(); + if( null != d ) { // GC'ed ? + if(0 < displaysActive) { + displaysActive--; + } + final Runnable closeNativeTask = new Runnable() { + public void run() { + if ( null != d.getGraphicsDevice() ) { + d.closeNativeImpl(); + } } + }; + final EDTUtil edtUtil = d.getEDTUtil(); + if(null != edtUtil) { + final long coopSleep = edtUtil.getPollPeriod() * 2; + edtUtil.invokeStop(false, closeNativeTask); // don't block + try { + Thread.sleep( coopSleep < 50 ? coopSleep : 50 ); + } catch (InterruptedException e) { } + } else { + closeNativeTask.run(); } - }; - final EDTUtil edtUtil = d.getEDTUtil(); - if(null != edtUtil) { - final long coopSleep = edtUtil.getPollPeriod() * 2; - edtUtil.invokeStop(false, closeNativeTask); // don't block - try { - Thread.sleep( coopSleep < 50 ? coopSleep : 50 ); - } catch (InterruptedException e) { } - } else { - closeNativeTask.run(); + d.aDevice = null; + d.refCount=0; } - d.aDevice = null; - d.refCount=0; } } diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java index c02f4f288..fe9e91b57 100644 --- a/src/newt/classes/jogamp/newt/ScreenImpl.java +++ b/src/newt/classes/jogamp/newt/ScreenImpl.java @@ -125,7 +125,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { screen.screen_idx = idx; screen.fqname = display.getFQName()+"-s"+idx; screen.hashCode = screen.fqname.hashCode(); - screenList.add(screen); + Screen.addScreen2List(screen); if(DEBUG) { System.err.println("Screen.create() NEW: "+screen+" "+Display.getThreadName()); } @@ -169,8 +169,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { System.err.println("Screen.createNative() START ("+DisplayImpl.getThreadName()+", "+this+")"); } else { tCreated = 0; - } - + } display.addReference(); createNativeImpl(); @@ -179,11 +178,11 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { } initMonitorState(); - if(DEBUG) { - System.err.println("Screen.createNative() END ("+DisplayImpl.getThreadName()+", "+this+"), total "+ (System.nanoTime()-tCreated)/1e6 +"ms"); - } synchronized(screenList) { screensActive++; + if(DEBUG) { + System.err.println("Screen.createNative() END ("+DisplayImpl.getThreadName()+", "+this+"), active "+screensActive+", total "+ (System.nanoTime()-tCreated)/1e6 +"ms"); + } } ScreenMonitorState.getScreenMonitorState(this.getFQName()).addListener(this); } @@ -192,10 +191,12 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { @Override public synchronized final void destroy() { synchronized(screenList) { - if( screenList.remove(this) ) { - if(0 < screensActive) { - screensActive--; - } + if(0 < screensActive) { + screensActive--; + } + if(DEBUG) { + System.err.println("Screen.destroy() ("+DisplayImpl.getThreadName()+"): active "+screensActive); + // Thread.dumpStack(); } } @@ -667,11 +668,13 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { System.err.println("Screen.shutdownAll "+sCount+" instances, on thread "+Display.getThreadName()); } for(int i=0; i<sCount && screenList.size()>0; i++) { // be safe .. - final ScreenImpl s = (ScreenImpl) screenList.remove(0); + final ScreenImpl s = (ScreenImpl) screenList.remove(0).get(); if(DEBUG) { - System.err.println("Screen.shutdownAll["+(i+1)+"/"+sCount+"]: "+s); + System.err.println("Screen.shutdownAll["+(i+1)+"/"+sCount+"]: "+s+", GCed "+(null==s)); + } + if( null != s ) { + s.shutdown(); } - s.shutdown(); } } } diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 7c4011f34..460763f47 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -36,6 +36,7 @@ package jogamp.newt; import java.util.ArrayList; import java.util.List; +import java.lang.ref.WeakReference; import java.lang.reflect.Method; import com.jogamp.common.util.IntBitfield; @@ -82,7 +83,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer { public static final boolean DEBUG_TEST_REPARENT_INCOMPATIBLE = Debug.isPropertyDefined("newt.test.Window.reparent.incompatible", true); - protected static final ArrayList<WindowImpl> windowList = new ArrayList<WindowImpl>(); + protected static final ArrayList<WeakReference<WindowImpl>> windowList = new ArrayList<WeakReference<WindowImpl>>(); static { ScreenImpl.initSingleton(); @@ -95,13 +96,28 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer System.err.println("Window.shutdownAll "+wCount+" instances, on thread "+getThreadName()); } for(int i=0; i<wCount && windowList.size()>0; i++) { // be safe .. - final WindowImpl w = windowList.remove(0); + final WindowImpl w = windowList.remove(0).get(); if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.shutdownAll["+(i+1)+"/"+wCount+"]: "+toHexString(w.getWindowHandle())); + final long wh = null != w ? w.getWindowHandle() : 0; + System.err.println("Window.shutdownAll["+(i+1)+"/"+wCount+"]: "+toHexString(wh)+", GCed "+(null==w)); } w.shutdown(); } } + private static void addWindow2List(WindowImpl window) { + synchronized(windowList) { + // GC before add + int i=0; + while( i < windowList.size() ) { + if( null == windowList.get(i).get() ) { + windowList.remove(i); + } else { + i++; + } + } + windowList.add(new WeakReference<WindowImpl>(window)); + } + } /** Timeout of queued events (repaint and resize) */ static final long QUEUED_EVENT_TO = 1200; // ms @@ -208,9 +224,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer window.screen = (ScreenImpl) screen; window.capsRequested = (CapabilitiesImmutable) caps.cloneMutable(); window.instantiationFinished(); - synchronized( windowList ) { - windowList.add(window); - } + addWindow2List(window); return window; } catch (Throwable t) { t.printStackTrace(); @@ -233,9 +247,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer window.screen = (ScreenImpl) screen; window.capsRequested = (CapabilitiesImmutable) caps.cloneMutable(); window.instantiationFinished(); - synchronized( windowList ) { - windowList.add(window); - } + addWindow2List(window); return window; } catch (Throwable t) { throw new NativeWindowException(t); @@ -1062,9 +1074,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer @Override public void destroy() { - synchronized( windowList ) { - windowList.remove(this); - } visible = false; // Immediately mark synchronized visibility flag, avoiding possible recreation runOnEDTIfAvail(true, destroyAction); } |