From d94115b3d72ec556371e6d09c2967345662fc781 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Wed, 2 Jun 2010 04:13:43 +0200 Subject: NEWT: Simplified Locking - Using Display.getEDTUtil() and Display.runCreateAndDestroyOnEDT() to determine the NEWT EDT behavior, which may be specialized by the implementation. - AWTWrapper and Newt/AWT Parenting deadlock fix. - Misc fixes in test cases --- src/newt/classes/com/jogamp/newt/Display.java | 108 +++++++++++++-------- src/newt/classes/com/jogamp/newt/Window.java | 13 +-- .../newt/event/awt/AWTParentWindowAdapter.java | 40 +++++++- .../jogamp/newt/event/awt/AWTWindowAdapter.java | 59 +---------- .../com/jogamp/newt/impl/awt/AWTDisplay.java | 3 + .../classes/com/jogamp/newt/opengl/GLWindow.java | 10 +- 6 files changed, 121 insertions(+), 112 deletions(-) (limited to 'src/newt') diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java index 113ec547e..8710f82ba 100755 --- a/src/newt/classes/com/jogamp/newt/Display.java +++ b/src/newt/classes/com/jogamp/newt/Display.java @@ -112,7 +112,7 @@ public abstract class Display { Map displayMap = getCurrentDisplayMap(); Set entrySet = displayMap.entrySet(); Iterator i = entrySet.iterator(); - System.err.println(prefix+" DisplayMap["+entrySet.size()+"] "+Thread.currentThread()); + System.err.println(prefix+" DisplayMap[] entries: "+entrySet.size()+" - "+Thread.currentThread()); for(int j=0; i.hasNext(); j++) { Map.Entry entry = (Map.Entry) i.next(); System.err.println(" ["+j+"] "+entry.getKey()+" -> "+entry.getValue()); @@ -125,7 +125,7 @@ public abstract class Display { } /** Make sure to reuse a Display with the same name */ - protected static Display create(String type, String name, final long handle) { + protected static synchronized Display create(String type, String name, final long handle) { try { Class displayClass = getDisplayClass(type); Display tmpDisplay = (Display) displayClass.newInstance(); @@ -140,41 +140,30 @@ public abstract class Display { tmpDisplay = null; display.name = name; display.type=type; - display.refCount=1; - - if(NewtFactory.useEDT()) { - final Display f_dpy = display; - Thread current = Thread.currentThread(); - display.edtUtil = new EDTUtil(current.getThreadGroup(), - "Display_"+display.getFQName(), - new Runnable() { - public void run() { - if(null!=f_dpy.getGraphicsDevice()) { - f_dpy.pumpMessagesImpl(); - } - } } ); - display.edt = display.edtUtil.start(); - display.edtUtil.invokeAndWait(new Runnable() { - public void run() { - f_dpy.createNative(); - } - } ); - } else { - display.createNative(); - } - if(null==display.aDevice) { - throw new RuntimeException("Display.createNative() failed to instanciate an AbstractGraphicsDevice"); - } - setCurrentDisplay(display); + display.refCount=0; if(DEBUG) { - System.err.println("Display.create("+getFQName(type, name)+") NEW: "+display+" "+Thread.currentThread()); + System.err.println("Display.create("+getFQName(type, name)+") NEW: refCount "+display.refCount+", "+display+" "+Thread.currentThread()); } } else { tmpDisplay = null; - synchronized(display) { - display.refCount++; + if(DEBUG) { + System.err.println("Display.create("+getFQName(type, name)+") REUSE: refCount "+display.refCount+", "+display+" "+Thread.currentThread()); + } + } + synchronized(display) { + display.refCount++; + if(null==display.aDevice) { + final Display f_dpy = display; + display.runOnEDTIfAvail(true, new Runnable() { + public void run() { + f_dpy.createNative(); + }}); + if(null==display.aDevice) { + throw new RuntimeException("Display.createNative() failed to instanciate an AbstractGraphicsDevice"); + } + setCurrentDisplay(display); if(DEBUG) { - System.err.println("Display.create("+getFQName(type, name)+") REUSE: refCount "+display.refCount+", "+display+" "+Thread.currentThread()); + System.err.println("Display.create("+getFQName(type, name)+") CreateNative: "+display+" "+Thread.currentThread()); } } } @@ -187,7 +176,41 @@ public abstract class Display { } } - public EDTUtil getEDTUtil() { return edtUtil; } + public boolean runCreateAndDestroyOnEDT() { + return true; + } + public EDTUtil getEDTUtil() { + if( !edtQueried ) { + synchronized (this) { + if( !edtQueried ) { + edtQueried = true; + if(NewtFactory.useEDT()) { + final Display f_dpy = this; + Thread current = Thread.currentThread(); + edtUtil = new EDTUtil(current.getThreadGroup(), + "Display_"+getFQName(), + new Runnable() { + public void run() { + if(null!=f_dpy.getGraphicsDevice()) { + f_dpy.pumpMessagesImpl(); + } } } ); + edt = edtUtil.start(); + } + } + } + } + return edtUtil; + } + volatile boolean edtQueried = false; + + public void runOnEDTIfAvail(boolean wait, final Runnable task) { + EDTUtil edtUtil = getEDTUtil(); + if(runCreateAndDestroyOnEDT() && null!=edtUtil) { + edtUtil.invoke(wait, task); + } else { + task.run(); + } + } public synchronized void destroy() { if(DEBUG) { @@ -199,18 +222,17 @@ public abstract class Display { if(DEBUG) { System.err.println("Display.destroy("+getFQName()+") REMOVE: "+this+" "+Thread.currentThread()); } - if(null!=edtUtil) { - final Display f_dpy = this; - final EDTUtil f_edt = edtUtil; - edtUtil.invokeAndWait(new Runnable() { - public void run() { - f_dpy.closeNative(); + final Display f_dpy = this; + final EDTUtil f_edt = edtUtil; + runOnEDTIfAvail(true, new Runnable() { + public void run() { + f_dpy.closeNative(); + if(null!=f_edt) { f_edt.stop(); } - } ); - } else { - closeNative(); - } + } + } ); + if(null!=edtUtil) { edtUtil.waitUntilStopped(); edtUtil=null; diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index bb3fa8982..87f0bf0eb 100755 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -161,11 +161,6 @@ public abstract class Window implements NativeWindow if( null==screen || 0!=windowHandle || !visible ) { return 0 != windowHandle ; } - EDTUtil edtUtil = screen.getDisplay().getEDTUtil(); - if( null != edtUtil && edtUtil.isRunning() && !edtUtil.isCurrentThreadEDT() ) { - throw new NativeWindowException("EDT enabled but not on EDT"); - } - if(DEBUG_IMPLEMENTATION) { System.err.println("Window.createNative() START ("+Thread.currentThread()+", "+this+")"); } @@ -219,12 +214,8 @@ public abstract class Window implements NativeWindow if(null==screen) { throw new RuntimeException("Null screen of inner class: "+this); } - EDTUtil edtUtil = screen.getDisplay().getEDTUtil(); - if(null!=edtUtil) { - edtUtil.invoke(wait, task); - } else { - task.run(); - } + Display d = screen.getDisplay(); + d.runOnEDTIfAvail(wait, task); } /** diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java index d94a32a9c..33c291e96 100644 --- a/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java @@ -35,12 +35,24 @@ package com.jogamp.newt.event.awt; * Specialized parent/client adapter, * where the NEWT child window really gets resized, * and the parent move window event gets discarded. */ -public class AWTParentWindowAdapter extends AWTWindowAdapter +public class AWTParentWindowAdapter + extends AWTWindowAdapter + implements java.awt.event.HierarchyListener { public AWTParentWindowAdapter(com.jogamp.newt.Window downstream) { super(downstream); } + public AWTAdapter addTo(java.awt.Component awtComponent) { + awtComponent.addHierarchyListener(this); + return super.addTo(awtComponent); + } + + public AWTAdapter removeFrom(java.awt.Component awtComponent) { + awtComponent.removeHierarchyListener(this); + return super.removeFrom(awtComponent); + } + public void componentResized(java.awt.event.ComponentEvent e) { // Need to resize the NEWT child window // the resized event will be send via the native window feedback. @@ -67,5 +79,31 @@ public class AWTParentWindowAdapter extends AWTWindowAdapter public void windowDeactivated(java.awt.event.WindowEvent e) { // no propagation to NEWT child window } + + public void hierarchyChanged(java.awt.event.HierarchyEvent e) { + if( null == newtListener ) { + long bits = e.getChangeFlags(); + final java.awt.Component changed = e.getChanged(); + if( 0 != ( java.awt.event.HierarchyEvent.SHOWING_CHANGED & bits ) ) { + final boolean showing = changed.isShowing(); + if(DEBUG_IMPLEMENTATION) { + System.out.println("hierarchyChanged SHOWING_CHANGED: showing "+showing+", "+changed); + } + if(!newtWindow.isDestroyed()) { + newtWindow.runOnEDTIfAvail(false, new Runnable() { + public void run() { + newtWindow.setVisible(showing); + } + }); + } + } + if( 0 != ( java.awt.event.HierarchyEvent.DISPLAYABILITY_CHANGED & bits ) ) { + final boolean displayability = changed.isDisplayable(); + if(DEBUG_IMPLEMENTATION) { + System.out.println("hierarchyChanged DISPLAYABILITY_CHANGED: displayability "+displayability+", "+changed); + } + } + } + } } diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java index 53ce03299..570b0678a 100644 --- a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java @@ -33,8 +33,7 @@ package com.jogamp.newt.event.awt; public class AWTWindowAdapter extends AWTAdapter - implements java.awt.event.ComponentListener, java.awt.event.WindowListener, - java.awt.event.HierarchyListener, java.awt.event.HierarchyBoundsListener + implements java.awt.event.ComponentListener, java.awt.event.WindowListener { WindowClosingListener windowClosingListener; @@ -53,8 +52,6 @@ public class AWTWindowAdapter public AWTAdapter addTo(java.awt.Component awtComponent) { java.awt.Window win = getWindow(awtComponent); awtComponent.addComponentListener(this); - awtComponent.addHierarchyListener(this); - awtComponent.addHierarchyBoundsListener(this); if( null == windowClosingListener ) { windowClosingListener = new WindowClosingListener(); } @@ -69,8 +66,6 @@ public class AWTWindowAdapter public AWTAdapter removeFrom(java.awt.Component awtComponent) { awtComponent.removeComponentListener(this); - awtComponent.removeHierarchyListener(this); - awtComponent.removeHierarchyBoundsListener(this); java.awt.Window win = getWindow(awtComponent); if( null != win && null != windowClosingListener ) { win.removeWindowListener(windowClosingListener); @@ -110,6 +105,7 @@ public class AWTWindowAdapter } public void componentShown(java.awt.event.ComponentEvent e) { + /** if(null==newtListener) { if(!newtWindow.isDestroyed()) { newtWindow.runOnEDTIfAvail(false, new Runnable() { @@ -118,10 +114,11 @@ public class AWTWindowAdapter } }); } - } + }*/ } public void componentHidden(java.awt.event.ComponentEvent e) { + /** if(null==newtListener) { if(!newtWindow.isDestroyed()) { newtWindow.runOnEDTIfAvail(false, new Runnable() { @@ -130,7 +127,7 @@ public class AWTWindowAdapter } }); } - } + }*/ } public void windowActivated(java.awt.event.WindowEvent e) { @@ -161,52 +158,6 @@ public class AWTWindowAdapter public void windowOpened(java.awt.event.WindowEvent e) { } - public void hierarchyChanged(java.awt.event.HierarchyEvent e) { - if( null == newtListener ) { - long bits = e.getChangeFlags(); - final java.awt.Component changed = e.getChanged(); - if( 0 != ( java.awt.event.HierarchyEvent.SHOWING_CHANGED & bits ) ) { - final boolean showing = changed.isShowing(); - if(DEBUG_IMPLEMENTATION) { - System.out.println("hierarchyChanged SHOWING_CHANGED: showing "+showing+", "+changed); - } - if(!newtWindow.isDestroyed()) { - newtWindow.runOnEDTIfAvail(false, new Runnable() { - public void run() { - newtWindow.setVisible(showing); - } - }); - } - } - if( 0 != ( java.awt.event.HierarchyEvent.DISPLAYABILITY_CHANGED & bits ) ) { - final boolean displayability = changed.isDisplayable(); - if(DEBUG_IMPLEMENTATION) { - System.out.println("hierarchyChanged DISPLAYABILITY_CHANGED: displayability "+displayability+", "+changed); - } - } - } - } - - public void ancestorMoved(java.awt.event.HierarchyEvent e) { - if( null == newtListener ) { - final java.awt.Component changed = e.getChanged(); - final boolean showing = changed.isShowing(); - if(DEBUG_IMPLEMENTATION) { - System.out.println("ancestorMoved: showing "+showing+", "+changed); - } - } - } - - public void ancestorResized(java.awt.event.HierarchyEvent e) { - if( null == newtListener ) { - final java.awt.Component changed = e.getChanged(); - final boolean showing = changed.isShowing(); - if(DEBUG_IMPLEMENTATION) { - System.out.println("ancestorResized: showing "+showing+", "+changed); - } - } - } - class WindowClosingListener implements java.awt.event.WindowListener { public void windowClosing(java.awt.event.WindowEvent e) { com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow); diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/AWTDisplay.java b/src/newt/classes/com/jogamp/newt/impl/awt/AWTDisplay.java index f54e66f07..e705d364a 100644 --- a/src/newt/classes/com/jogamp/newt/impl/awt/AWTDisplay.java +++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTDisplay.java @@ -54,6 +54,9 @@ public class AWTDisplay extends Display { protected void closeNative() { } + public boolean runCreateAndDestroyOnEDT() { + return false; + } protected void dispatchMessagesNative() { /* nop */ } } diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index 2bb28466c..9559043c4 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -120,10 +120,14 @@ public class GLWindow extends Window implements GLAutoDrawable { return (null!=window)?window.isDestroyed():true; } - public Window getInnerWindow() { + public final Window getInnerWindow() { return window.getInnerWindow(); } + public final Object getWrappedWindow() { + return window.getWrappedWindow(); + } + /** * EXPERIMENTAL
* Enable or disables running the {@link Display#pumpMessages} in the {@link #display()} call.
@@ -244,8 +248,8 @@ public class GLWindow extends Window implements GLAutoDrawable { window.setVisible(visible); if (null == context && visible && 0 != window.getWindowHandle() && 0