diff options
Diffstat (limited to 'src/newt/classes/jogamp')
11 files changed, 405 insertions, 145 deletions
diff --git a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java index bdbe96070..18418a8dc 100644 --- a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java +++ b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java @@ -49,12 +49,12 @@ import com.jogamp.newt.util.EDTUtil; public class DefaultEDTUtil implements EDTUtil { public static final boolean DEBUG = Debug.debug("EDT"); - private ThreadGroup threadGroup; + private final Object edtLock = new Object(); // locking the EDT start/stop state + private final ThreadGroup threadGroup; + private final String name; + private final Runnable dispatchMessages; private EventDispatchThread edt = null; - private Object edtLock = new Object(); // locking the EDT start/stop state - private String name; - int start_iter=0; - private Runnable dispatchMessages; + private int start_iter=0; private static long pollPeriod = EDTUtil.defaultEDTPollPeriod; public DefaultEDTUtil(ThreadGroup tg, String name, Runnable dispatchMessages) { @@ -65,14 +65,17 @@ public class DefaultEDTUtil implements EDTUtil { this.edt.setDaemon(true); // don't stop JVM from shutdown .. } + @Override final public long getPollPeriod() { return pollPeriod; } + @Override final public void setPollPeriod(long ms) { pollPeriod = ms; } + @Override public final void reset() { synchronized(edtLock) { waitUntilStopped(); @@ -88,36 +91,46 @@ public class DefaultEDTUtil implements EDTUtil { } } - public final void start() { - synchronized(edtLock) { - if(!edt.isRunning() && !edt.shouldStop) { - if(edt.isAlive()) { - throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+edt.isRunning()+", edt: "+edt+", tasks: "+edt.tasks.size()); - } - start_iter++; - edt.setName(name+start_iter); - edt.shouldStop = false; - if(DEBUG) { - System.err.println(Thread.currentThread()+": EDT START - edt: "+edt); - // Thread.dumpStack(); - } - edt.start(); - } + private final void startImpl() { + if(edt.isAlive()) { + throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+edt.isRunning()+", edt: "+edt+", tasks: "+edt.tasks.size()); } + start_iter++; + edt.setName(name+start_iter); + edt.shouldStop = false; + if(DEBUG) { + System.err.println(Thread.currentThread()+": EDT START - edt: "+edt); + // Thread.dumpStack(); + } + edt.start(); } + @Override public final boolean isCurrentThreadEDT() { - return edt == Thread.currentThread(); + return edt == Thread.currentThread(); // EDT == NEDT + } + + @Override + public final boolean isCurrentThreadNEDT() { + return edt == Thread.currentThread(); // EDT == NEDT } + @Override + public final boolean isCurrentThreadEDTorNEDT() { + return edt == Thread.currentThread(); // EDT == NEDT + } + + @Override public final boolean isRunning() { return edt.isRunning() ; } + @Override public final void invokeStop(Runnable task) { invokeImpl(true, task, true); } + @Override public final void invoke(boolean wait, Runnable task) { invokeImpl(wait, task, false); } @@ -158,8 +171,11 @@ public class DefaultEDTUtil implements EDTUtil { } } } else { + // start if should not stop && not started yet + if( !stop && !edt.isRunning() ) { + startImpl(); + } synchronized(edt.tasks) { - start(); // start if not started yet and !shouldStop wait = wait && edt.isRunning(); rTask = new RunnableTask(task, wait ? rTaskLock : null, @@ -195,6 +211,7 @@ public class DefaultEDTUtil implements EDTUtil { } } + @Override final public void waitUntilIdle() { final EventDispatchThread _edt; synchronized(edtLock) { @@ -215,6 +232,7 @@ public class DefaultEDTUtil implements EDTUtil { } } + @Override final public void waitUntilStopped() { synchronized(edtLock) { if(edt.isRunning() && edt != Thread.currentThread() ) { diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java index bac4031f0..bca7f6e5b 100644 --- a/src/newt/classes/jogamp/newt/DisplayImpl.java +++ b/src/newt/classes/jogamp/newt/DisplayImpl.java @@ -169,8 +169,7 @@ public abstract class DisplayImpl extends Display { public EDTUtil setEDTUtil(EDTUtil newEDTUtil) { if(null == newEDTUtil) { newEDTUtil = createEDTUtil(); - } - if( newEDTUtil == edtUtil ) { + } else if( newEDTUtil == edtUtil ) { if(DEBUG) { System.err.println("Display.setEDTUtil: "+newEDTUtil+" - keep!"); } @@ -366,7 +365,7 @@ public abstract class DisplayImpl extends Display { DisplayImpl.this.dispatchMessages(); } } - DispatchMessagesRunnable dispatchMessagesRunnable = new DispatchMessagesRunnable(); + protected DispatchMessagesRunnable dispatchMessagesRunnable = new DispatchMessagesRunnable(); final void dispatchMessage(final NEWTEventTask eventTask) { final NEWTEvent event = eventTask.get(); @@ -446,8 +445,8 @@ public abstract class DisplayImpl extends Display { return; } - // can't wait if we are on EDT -> consume right away - if(wait && edtUtil.isCurrentThreadEDT()) { + // can't wait if we are on EDT or NEDT -> consume right away + if(wait && edtUtil.isCurrentThreadEDTorNEDT() ) { dispatchMessage(new NEWTEventTask(e, null)); return; } diff --git a/src/newt/classes/jogamp/newt/OffscreenWindow.java b/src/newt/classes/jogamp/newt/OffscreenWindow.java index ba98ca3af..c6c1814f6 100644 --- a/src/newt/classes/jogamp/newt/OffscreenWindow.java +++ b/src/newt/classes/jogamp/newt/OffscreenWindow.java @@ -39,20 +39,16 @@ import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.GraphicsConfigurationFactory; import javax.media.nativewindow.MutableSurface; import javax.media.nativewindow.NativeWindowException; -import javax.media.nativewindow.ProxySurface; import javax.media.nativewindow.VisualIDHolder; import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.Point; public class OffscreenWindow extends WindowImpl implements MutableSurface { - long surfaceHandle = 0; - ProxySurface.UpstreamSurfaceHook upstreamHook; - ProxySurface dummySurface; + long surfaceHandle; public OffscreenWindow() { - upstreamHook = null; - dummySurface = null; + surfaceHandle = 0; } static long nextWindowHandle = 0x100; // start here - a marker @@ -62,17 +58,6 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface { throw new NativeWindowException("Capabilities is onscreen"); } final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen(); - /** Cannot use OpenGL here .. - if(capsRequested instanceof GLCapabilitiesImmutable) { - final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) capsRequested; - if(caps.isFBO() && GLContext.isFBOAvailable(aScreen.getDevice(), caps.getGLProfile()) ) { - final GLDrawableFactoryImpl factory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactory(caps.getGLProfile()); - final GLCapabilitiesImmutable dummyCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(caps); - final ProxySurface dummySurface = factory.createDummySurfaceImpl(aScreen.getDevice(), false, dummyCaps, null, 64, 64); - upstreamHook = dummySurface.getUpstreamSurfaceHook(); - dummySurface.createNotify(); - } - } */ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(aScreen.getDevice(), capsRequested).chooseGraphicsConfiguration( capsRequested, capsRequested, capabilitiesChooser, aScreen, VisualIDHolder.VID_UNDEFINED); if (null == cfg) { @@ -83,6 +68,7 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface { synchronized(OffscreenWindow.class) { setWindowHandle(nextWindowHandle++); } + visibleChanged(false, true); } protected void closeNativeImpl() { @@ -92,11 +78,6 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface { @Override public synchronized void destroy() { super.destroy(); - if(null != dummySurface) { - dummySurface.destroyNotify(); - dummySurface = null; - upstreamHook = null; - } surfaceHandle = 0; } @@ -106,10 +87,6 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface { @Override public long getSurfaceHandle() { - if(null != dummySurface) { - return dummySurface.getSurfaceHandle(); - // return upstreamHook.getWidth(); - } return surfaceHandle; } @@ -128,8 +105,8 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface { } protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + sizeChanged(false, width, height, false); if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { - sizeChanged(false, width, height, false); visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); } else { /** diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index ad7195944..c1ac87d38 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -767,11 +767,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } - public void setVisible(boolean visible) { + protected void setVisible(boolean wait, boolean visible) { if(DEBUG_IMPLEMENTATION) { System.err.println("Window setVisible: START ("+getThreadName()+") "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+this.visible+" -> "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+(null!=parentWindow)); } - runOnEDTIfAvail(true, new VisibleAction(visible)); + runOnEDTIfAvail(wait, new VisibleAction(visible)); + } + + public void setVisible(boolean visible) { + setVisible(true, visible); } private class SetSizeAction implements Runnable { @@ -783,21 +787,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } public final void run() { - boolean recreate = false; final RecursiveLock _lock = windowLock; _lock.lock(); try { if ( !isFullscreen() && ( getWidth() != width || getHeight() != height ) ) { - recreate = isNativeValid() && !getGraphicsConfiguration().getChosenCapabilities().isOnscreen(); if(DEBUG_IMPLEMENTATION) { - System.err.println("Window setSize: START "+getWidth()+"x"+getHeight()+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible+", recreate "+recreate); - } - if(recreate) { - // will trigger visibleAction:=2 -> create if wasVisible - final boolean wasVisible = WindowImpl.this.visible; - screen.addReference(); // retain screen - destroyAction.run(); - WindowImpl.this.visible = wasVisible; + System.err.println("Window setSize: START "+getWidth()+"x"+getHeight()+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible); } int visibleAction; // 0 nop, 1 invisible, 2 visible (create) if ( isNativeValid() && 0>=width*height && visible ) { @@ -823,9 +818,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } } finally { - if(recreate) { - screen.removeReference(); // bring back ref-count - } _lock.unlock(); } } @@ -940,11 +932,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer */ protected static boolean isOffscreenInstance(NativeWindow cWin, NativeWindow pWin) { boolean ofs = false; - if( null != cWin.getGraphicsConfiguration() ) { - ofs = !cWin.getGraphicsConfiguration().getChosenCapabilities().isOnscreen(); + final AbstractGraphicsConfiguration cWinCfg = cWin.getGraphicsConfiguration(); + if( null != cWinCfg ) { + ofs = !cWinCfg.getChosenCapabilities().isOnscreen(); } - if( !ofs && null != pWin && null != pWin.getGraphicsConfiguration() ) { - ofs |= !pWin.getGraphicsConfiguration().getChosenCapabilities().isOnscreen(); + if( !ofs && null != pWin ) { + final AbstractGraphicsConfiguration pWinCfg = pWin.getGraphicsConfiguration(); + if( null != pWinCfg ) { + ofs = !pWinCfg.getChosenCapabilities().isOnscreen(); + } } return ofs; } diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java index 91c589beb..28c4da72f 100644 --- a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java +++ b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java @@ -265,16 +265,17 @@ public class NewtBaseActivity extends Activity { if(!isDelegatedActivity()) { super.onResume(); } - if(null != animator) { - animator.resume(); - animator.resetFPSCounter(); - } - for(int i=newtWindows.size()-1; i>=0; i--) { + for(int i=0; i<newtWindows.size(); i++) { final Window win = newtWindows.get(i); + win.setVisible(true); if(win instanceof FPSCounter) { ((FPSCounter)win).resetFPSCounter(); } } + if(null != animator) { + animator.resume(); + animator.resetFPSCounter(); + } } @Override @@ -283,6 +284,10 @@ public class NewtBaseActivity extends Activity { if(null != animator) { animator.pause(); } + for(int i=0; i<newtWindows.size(); i++) { + final Window win = newtWindows.get(i); + win.setVisible(false); + } if(!isDelegatedActivity()) { super.onPause(); } diff --git a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java index 8ad11b35f..f18520630 100644 --- a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java @@ -39,6 +39,7 @@ import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.Point; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLException; import com.jogamp.nativewindow.egl.EGLGraphicsDevice; @@ -263,15 +264,24 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 { setGraphicsConfiguration(eglConfig); setWindowHandle(surfaceHandle); focusChanged(false, true); - Log.d(MD.TAG, "createNativeImpl X"); + Log.d(MD.TAG, "createNativeImpl X: eglSurfaceHandle 0x"+Long.toHexString(eglSurface)); } @Override protected void closeNativeImpl() { + Log.d(MD.TAG, "closeNativeImpl 0 - surfaceHandle 0x"+Long.toHexString(surfaceHandle)+ + ", eglSurfaceHandle 0x"+Long.toHexString(eglSurface)+ + ", format [a "+androidFormat+", n "+nativeFormat+"], "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+" - "+Thread.currentThread().getName()); + if(0 != eglSurface) { + final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) getScreen().getDisplay().getGraphicsDevice(); + if (!EGL.eglDestroySurface(eglDevice.getHandle(), eglSurface)) { + throw new GLException("Error destroying window surface (eglDestroySurface)"); + } + eglSurface = 0; + } release0(surfaceHandle); surface = null; surfaceHandle = 0; - eglSurface = 0; } @Override @@ -291,25 +301,33 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 { } } - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + boolean res = true; + if( 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) { Log.d(MD.TAG, "reconfigureWindowImpl.setFullscreen post creation (setContentView()) n/a"); return false; } - if(width>0 || height>0) { + if(getWidth() != width || getHeight() != height) { if(0!=getWindowHandle()) { Log.d(MD.TAG, "reconfigureWindowImpl.setSize n/a"); - return false; + res = false; + } else { + defineSize(width, height); } } - if(x>=0 || y>=0) { - Log.d(MD.TAG, "reconfigureWindowImpl.setPos n/a"); - return false; + if(getX() != x || getY() != y) { + if(0!=getWindowHandle()) { + Log.d(MD.TAG, "reconfigureWindowImpl.setPos n/a"); + res = false; + } else { + definePosition(x, y); + } } if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); } - return true; + return res; } protected Point getLocationOnScreenImpl(int x, int y) { @@ -410,7 +428,7 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 { getX()+"/"+getY()+" "+nWidth+"x"+nHeight+", visible: "+isVisible()); if(isVisible()) { - setVisible(true); + setVisible(false, true); } } sizeChanged(false, aWidth, aHeight, false); diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java index b3fdcad41..17eb6a2fb 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java +++ b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java @@ -35,6 +35,7 @@ package jogamp.newt.driver.awt; import java.awt.Canvas; +import java.awt.Graphics; import java.awt.GraphicsDevice; import java.awt.GraphicsConfiguration; import java.lang.reflect.Method; @@ -61,14 +62,16 @@ public class AWTCanvas extends Canvas { private GraphicsConfiguration chosen; private AWTGraphicsConfiguration awtConfig; + private WindowDriver newtWindowImpl; private CapabilitiesChooser chooser=null; private CapabilitiesImmutable capabilities; private boolean displayConfigChanged=false; - public AWTCanvas(CapabilitiesImmutable capabilities, CapabilitiesChooser chooser) { + public AWTCanvas(WindowDriver newtWindowImpl, CapabilitiesImmutable capabilities, CapabilitiesChooser chooser) { super(); + this.newtWindowImpl = newtWindowImpl; if(null==capabilities) { throw new NativeWindowException("Capabilities null"); } @@ -80,6 +83,25 @@ public class AWTCanvas extends Canvas { return awtConfig; } + /** + * Overridden from Canvas to prevent the AWT's clearing of the + * canvas from interfering with the OpenGL rendering. + */ + @Override + public void update(Graphics g) { + paint(g); + } + + /** Overridden to cause OpenGL rendering to be performed during + repaint cycles. Subclasses which override this method must call + super.paint() in their paint() method in order to function + properly. + */ + @Override + public void paint(Graphics g) { + newtWindowImpl.windowRepaint(0, 0, getWidth(), getHeight()); + } + public boolean hasDeviceChanged() { boolean res = displayConfigChanged; displayConfigChanged=false; @@ -275,10 +297,10 @@ public class AWTCanvas extends Canvas { private void disableBackgroundErase() { if (!disableBackgroundEraseInitialized) { try { - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { try { - Class clazz = getToolkit().getClass(); + Class<?> clazz = getToolkit().getClass(); while (clazz != null && disableBackgroundEraseMethod == null) { try { disableBackgroundEraseMethod = diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java index 942651187..8771f5c74 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java +++ b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java @@ -28,72 +28,239 @@ package jogamp.newt.driver.awt; -import javax.media.opengl.Threading; +import java.awt.EventQueue; import com.jogamp.newt.util.EDTUtil; + +import jogamp.common.awt.AWTEDTExecutor; import jogamp.newt.Debug; public class AWTEDTUtil implements EDTUtil { public static final boolean DEBUG = Debug.debug("EDT"); - - private static AWTEDTUtil singletonMainThread = new AWTEDTUtil(); // one singleton MainThread - public static AWTEDTUtil getSingleton() { - return singletonMainThread; - } + private final Object edtLock = new Object(); // locking the EDT start/stop state + private final ThreadGroup threadGroup; + private final String name; + private final Runnable dispatchMessages; + private NewtEventDispatchThread nedt = null; + private int start_iter=0; + private static long pollPeriod = EDTUtil.defaultEDTPollPeriod; - AWTEDTUtil() { - // package private access .. + public AWTEDTUtil(ThreadGroup tg, String name, Runnable dispatchMessages) { + this.threadGroup = tg; + this.name=Thread.currentThread().getName()+"-"+name+"-EDT-"; + this.dispatchMessages=dispatchMessages; + this.nedt = new NewtEventDispatchThread(threadGroup, name); + this.nedt.setDaemon(true); // don't stop JVM from shutdown .. } + @Override final public long getPollPeriod() { - return 0; + return pollPeriod; } + @Override final public void setPollPeriod(long ms) { - // nop + pollPeriod = ms; } + @Override final public void reset() { - // nop AWT is always running + synchronized(edtLock) { + waitUntilStopped(); + if(DEBUG) { + System.err.println(Thread.currentThread()+": EDT reset - edt: "+nedt); + } + this.nedt = new NewtEventDispatchThread(threadGroup, name); + this.nedt.setDaemon(true); // don't stop JVM from shutdown .. + } } - final public void start() { - // nop AWT is always running + private final void startImpl() { + if(nedt.isAlive()) { + throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning()+", edt: "+nedt); + } + start_iter++; + nedt.setName(name+start_iter); + nedt.shouldStop = false; + if(DEBUG) { + System.err.println(Thread.currentThread()+": EDT START - edt: "+nedt); + // Thread.dumpStack(); + } + nedt.start(); } + @Override final public boolean isCurrentThreadEDT() { - return Threading.isToolkitThread(); + return EventQueue.isDispatchThread(); } + @Override + public final boolean isCurrentThreadNEDT() { + return nedt == Thread.currentThread(); + } + + @Override + public final boolean isCurrentThreadEDTorNEDT() { + return EventQueue.isDispatchThread() || nedt == Thread.currentThread(); + } + + @Override final public boolean isRunning() { - return true; // AWT is always running + return nedt.isRunning() ; // AWT is always running } - final public void invokeStop(Runnable r) { - invoke(true, r); // AWT is always running + @Override + public final void invokeStop(Runnable task) { + invokeImpl(true, task, true); } - final public void invoke(boolean wait, Runnable r) { - if(r == null) { - return; - } - - Threading.invoke(wait, r, null); + @Override + public final void invoke(boolean wait, Runnable task) { + invokeImpl(wait, task, false); } + + private void invokeImpl(boolean wait, Runnable task, boolean stop) { + if(task == null) { + throw new RuntimeException("Null Runnable"); + } + synchronized(edtLock) { // lock the EDT status + if( nedt.shouldStop ) { + // drop task .. + if(DEBUG) { + System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+nedt); + Thread.dumpStack(); + } + return; + } + // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task); + // Thread.dumpStack(); + if(stop) { + nedt.shouldStop = true; + if(DEBUG) { + System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt); + // Thread.dumpStack(); + } + } + + // start if should not stop && not started yet + if( !stop && !nedt.isRunning() ) { + startImpl(); + } + } + AWTEDTExecutor.singleton.invoke(wait, task); + } + @Override final public void waitUntilIdle() { - // wait until previous events are processed, at least .. + final NewtEventDispatchThread _edt; + synchronized(edtLock) { + _edt = nedt; + } + if(!_edt.isRunning() || EventQueue.isDispatchThread() || _edt == Thread.currentThread()) { + return; + } try { - Threading.invoke(true, new Runnable() { + AWTEDTExecutor.singleton.invoke(true, new Runnable() { public void run() { } - }, null); + }); } catch (Exception e) { } } + @Override final public void waitUntilStopped() { - // nop: AWT is always running + synchronized(edtLock) { + if(nedt.isRunning() && nedt != Thread.currentThread() ) { + while(nedt.isRunning()) { + try { + edtLock.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } } + + class NewtEventDispatchThread extends Thread { + volatile boolean shouldStop = false; + volatile boolean isRunning = false; + Object sync = new Object(); + + public NewtEventDispatchThread(ThreadGroup tg, String name) { + super(tg, name); + } + + final public boolean isRunning() { + return isRunning; + } + + @Override + final public void start() throws IllegalThreadStateException { + isRunning = true; + super.start(); + } + + /** + * Utilizing locking only on tasks and its execution, + * not for event dispatching. + */ + @Override + final public void run() { + if(DEBUG) { + System.err.println(getName()+": EDT run() START "+ getName()); + } + RuntimeException error = null; + try { + do { + // event dispatch + if(!shouldStop) { + // FIXME: Determine whether we require to run the + // delivery of events (dispatch) on AWT-EDT. + // Since the WindowDriver itself delivers all Window related events, + // this shall not be required. + // AWTEDTExecutor.singleton.invoke(true, dispatchMessages); + dispatchMessages.run(); + } + // wait + synchronized(sync) { + if(!shouldStop) { + try { + sync.wait(pollPeriod); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } while(!shouldStop) ; + } catch (Throwable t) { + // handle errors .. + shouldStop = true; + if(t instanceof RuntimeException) { + error = (RuntimeException) t; + } else { + error = new RuntimeException("Within EDT", t); + } + } finally { + if(DEBUG) { + System.err.println(getName()+": EDT run() END "+ getName()+", "+error); + } + synchronized(edtLock) { + isRunning = !shouldStop; + if(!isRunning) { + edtLock.notifyAll(); + } + } + if(DEBUG) { + System.err.println(getName()+": EDT run() EXIT "+ getName()+", exception: "+error); + } + if(null!=error) { + throw error; + } + } // finally + } // run() + } // EventDispatchThread + } diff --git a/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java index 39d96585b..70e9ba570 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java @@ -38,6 +38,7 @@ import com.jogamp.nativewindow.awt.AWTGraphicsDevice; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.util.EDTUtil; +import jogamp.newt.DefaultEDTUtil; import jogamp.newt.DisplayImpl; public class DisplayDriver extends DisplayImpl { @@ -52,15 +53,12 @@ public class DisplayDriver extends DisplayImpl { aDevice = d; } - protected void closeNativeImpl() { } - - @Override protected EDTUtil createEDTUtil() { final EDTUtil def; if(NewtFactory.useEDT()) { - def = AWTEDTUtil.getSingleton(); + def = new AWTEDTUtil(Thread.currentThread().getThreadGroup(), "AWTDisplay-"+getFQName(), dispatchMessagesRunnable); if(DEBUG) { - System.err.println("AWTDisplay.createNative("+getFQName()+") Create EDTUtil: "+def.getClass().getName()); + System.err.println("Display.createNative("+getFQName()+") Create EDTUtil: "+def.getClass().getName()); } } else { def = null; @@ -68,6 +66,8 @@ public class DisplayDriver extends DisplayImpl { return def; } + protected void closeNativeImpl() { } + protected void dispatchMessagesNative() { /* nop */ } } diff --git a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java index 1723ffee5..bee43a95e 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java @@ -36,6 +36,7 @@ package jogamp.newt.driver.awt; import java.awt.BorderLayout; import java.awt.Container; +import java.awt.Dimension; import java.awt.Frame; import java.awt.Insets; @@ -47,6 +48,8 @@ import jogamp.newt.WindowImpl; import com.jogamp.nativewindow.awt.AWTGraphicsConfiguration; import com.jogamp.nativewindow.awt.AWTGraphicsDevice; import com.jogamp.nativewindow.awt.AWTGraphicsScreen; +import com.jogamp.newt.event.WindowEvent; +import com.jogamp.newt.event.WindowUpdateEvent; import com.jogamp.newt.event.awt.AWTKeyAdapter; import com.jogamp.newt.event.awt.AWTMouseAdapter; import com.jogamp.newt.event.awt.AWTWindowAdapter; @@ -107,18 +110,18 @@ public class WindowDriver extends WindowImpl { frame.setTitle(getTitle()); } container.setLayout(new BorderLayout()); - canvas = new AWTCanvas(capsRequested, WindowDriver.this.capabilitiesChooser); - - addWindowListener(new LocalWindowListener()); - - new AWTMouseAdapter(this).addTo(canvas); // fwd all AWT Mouse events to here - new AWTKeyAdapter(this).addTo(canvas); // fwd all AWT Key events to here + + canvas = new AWTCanvas(this, capsRequested, WindowDriver.this.capabilitiesChooser); // canvas.addComponentListener(listener); container.add(canvas, BorderLayout.CENTER); - container.setSize(getWidth(), getHeight()); - container.setLocation(getX(), getY()); - new AWTWindowAdapter(this).addTo(container); // fwd all AWT Window events to here + + // via EDT .. + new AWTMouseAdapter(this).addTo(canvas); // fwd all AWT Mouse events to here + new AWTKeyAdapter(this).addTo(canvas); // fwd all AWT Key events to here + + // direct w/o EDT + new AWTWindowAdapter(new LocalWindowListener(), this).addTo(canvas); // fwd all AWT Window events to here reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), getReconfigureFlags(FLAG_CHANGE_VISIBILITY | FLAG_CHANGE_DECORATION, true)); // throws exception if failed .. @@ -174,20 +177,32 @@ public class WindowDriver extends WindowImpl { frame.setUndecorated(isUndecorated()); } else { if(DEBUG_IMPLEMENTATION) { - System.err.println("AWTWindow can't undecorate already created frame"); + System.err.println(getThreadName()+": AWTWindow can't undecorate already created frame"); } } } + final Dimension szClient = new Dimension(width, height); + canvas.setMinimumSize(szClient); + canvas.setPreferredSize(szClient); + canvas.setSize(szClient); + if(DEBUG_IMPLEMENTATION) { + final Insets insets = container.getInsets(); + final Dimension szContainer = new Dimension(width + insets.left + insets.right, + height + insets.top + insets.bottom); + System.err.println(getThreadName()+": AWTWindow new size: szClient "+szClient+", szCont "+szContainer+", insets "+insets); + } + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + if(null != frame) { + frame.pack(); + } + container.validate(); container.setVisible(0 != ( FLAG_IS_VISIBLE & flags)); } container.setLocation(x, y); - Insets insets = container.getInsets(); - container.setSize(width + insets.left + insets.right, - height + insets.top + insets.bottom); - + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { if( 0 != ( FLAG_IS_VISIBLE & flags ) ) { if( !hasDeviceChanged() ) { @@ -200,6 +215,12 @@ public class WindowDriver extends WindowImpl { } } visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); + } else { + container.invalidate(); + if(null != frame) { + frame.pack(); + } + container.validate(); } return true; @@ -216,18 +237,41 @@ public class WindowDriver extends WindowImpl { return canvas; } - class LocalWindowListener extends com.jogamp.newt.event.WindowAdapter { + class LocalWindowListener implements com.jogamp.newt.event.WindowListener { @Override public void windowMoved(com.jogamp.newt.event.WindowEvent e) { if(null!=container) { - definePosition(container.getX(), container.getY()); + WindowDriver.this.positionChanged(false, container.getX(), container.getY()); } } @Override public void windowResized(com.jogamp.newt.event.WindowEvent e) { if(null!=canvas) { - defineSize(canvas.getWidth(), canvas.getHeight()); + WindowDriver.this.sizeChanged(false, canvas.getWidth(), canvas.getHeight(), false); + } + } + @Override + public void windowDestroyNotify(WindowEvent e) { + WindowDriver.this.windowDestroyNotify(false); + } + @Override + public void windowDestroyed(WindowEvent e) { + if(isNativeValid()) { + WindowDriver.this.windowDestroyNotify(true); } + + } + @Override + public void windowGainedFocus(WindowEvent e) { + WindowDriver.this.focusChanged(false, true); + } + @Override + public void windowLostFocus(WindowEvent e) { + WindowDriver.this.focusChanged(false, false); + } + @Override + public void windowRepaint(WindowUpdateEvent e) { + WindowDriver.this.windowRepaint(false, 0, 0, getWidth(), getHeight()); } } } diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java index ea48569bf..d0c0b8b20 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java @@ -117,6 +117,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl return 0 != sscSurfaceHandle ? sscSurfaceHandle : surfaceHandle; } + @Override public void setSurfaceHandle(long surfaceHandle) { if(DEBUG_IMPLEMENTATION) { System.err.println("MacWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle)); @@ -170,13 +171,22 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { - final Point pS = getTopLevelLocationOnScreen(x, y); - isOffscreenInstance = 0 != sscSurfaceHandle || isOffscreenInstance(this, this.getParent()); + final boolean _isOffscreenInstance = isOffscreenInstance(this, this.getParent()); + isOffscreenInstance = 0 != sscSurfaceHandle || _isOffscreenInstance; + final PointImmutable pS = isOffscreenInstance ? new Point(0, 0) : getTopLevelLocationOnScreen(x, y); if(DEBUG_IMPLEMENTATION) { + final AbstractGraphicsConfiguration cWinCfg = this.getGraphicsConfiguration(); + final NativeWindow pWin = getParent(); + final AbstractGraphicsConfiguration pWinCfg = null != pWin ? pWin.getGraphicsConfiguration() : null; System.err.println("MacWindow reconfig: "+x+"/"+y+" -> "+pS+" - "+width+"x"+height+ - ", offscreenInstance "+isOffscreenInstance+ - ", "+getReconfigureFlagsAsString(null, flags)); + ",\n\t parent type "+(null != pWin ? pWin.getClass().getName() : null)+ + ",\n\t this-chosenCaps "+(null != cWinCfg ? cWinCfg.getChosenCapabilities() : null)+ + ",\n\t parent-chosenCaps "+(null != pWinCfg ? pWinCfg.getChosenCapabilities() : null)+ + ", isOffscreenInstance(sscSurfaceHandle "+toHexString(sscSurfaceHandle)+ + ", ioi: "+_isOffscreenInstance+ + ") -> "+isOffscreenInstance+ + "\n\t, "+getReconfigureFlagsAsString(null, flags)); } if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 == ( FLAG_IS_VISIBLE & flags) ) { @@ -190,7 +200,11 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl 0 != ( FLAG_CHANGE_DECORATION & flags) || 0 != ( FLAG_CHANGE_PARENTING & flags) || 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) { - createWindow(isOffscreenInstance, 0 != getWindowHandle(), pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags)); + if(isOffscreenInstance) { + createWindow(true, 0 != getWindowHandle(), pS, 64, 64, false); + } else { + createWindow(false, 0 != getWindowHandle(), pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags)); + } if(isVisible()) { flags |= FLAG_CHANGE_VISIBILITY; } } if(x>=0 && y>=0) { |