diff options
author | Sven Gothel <[email protected]> | 2011-02-28 19:47:10 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-02-28 19:47:10 +0100 |
commit | 5681c25cfd4c7abce7d653910c9aa7a4e989057e (patch) | |
tree | 030887c110c6fbefd4bf958f4ab760478d71ec3e | |
parent | 30839d5a645d91ba6ea0b7f7f8150afac36bb215 (diff) |
NEWT WindowImpl EDT fixes
- all features intended to run on EDT and lock the surface shall only allowed to wait for result,
if the surface is unlocked. Otherwise don't wait - ie a pending operation.
- proper sequence of all feature Runnables, ie include pre/post lock actions in Runnable,
since it might be a pending task (see above).
This shall avoid deadlocks cause by user code where features are called (visible, fullscreen, ..)
when invoked within a locked surface code path - ie GLAutoDrawable.invoke(boolean wait, GLRunnable glRunnable).
-rw-r--r-- | src/newt/classes/jogamp/newt/WindowImpl.java | 199 |
1 files changed, 93 insertions, 106 deletions
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 391f918cf..fd38c9f04 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -612,75 +612,74 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer return screen; } - class VisibleAction implements Runnable { - boolean visible; - boolean nativeWindowCreated; - boolean madeVisible; - - public VisibleAction (boolean visible) { - this.visible = visible; - this.nativeWindowCreated = false; - this.madeVisible = false; - } - - public final boolean getNativeWindowCreated() { return nativeWindowCreated; } - public final boolean getBecameVisible() { return madeVisible; } - public final boolean getChanged() { return nativeWindowCreated || madeVisible; } - - public void run() { - windowLock.lock(); - try { - if(null!=lifecycleHook) { - lifecycleHook.resetCounter(); - } + final void setVisibleActionImpl(boolean visible) { + boolean nativeWindowCreated = false; + boolean madeVisible = false; + + windowLock.lock(); + try { + if(null!=lifecycleHook) { + lifecycleHook.resetCounter(); + } - if(!visible && null!=childWindows && childWindows.size()>0) { - synchronized(childWindowsLock) { - for(int i = 0; i < childWindows.size(); i++ ) { - NativeWindow nw = (NativeWindow) childWindows.get(i); - if(nw instanceof WindowImpl) { - ((WindowImpl)nw).setVisible(false); - } + if(!visible && null!=childWindows && childWindows.size()>0) { + synchronized(childWindowsLock) { + for(int i = 0; i < childWindows.size(); i++ ) { + NativeWindow nw = (NativeWindow) childWindows.get(i); + if(nw instanceof WindowImpl) { + ((WindowImpl)nw).setVisible(false); } - } } - if(0==windowHandle && visible) { - if( 0<width*height ) { - nativeWindowCreated = createNative(); - WindowImpl.this.waitForVisible(visible, true); - madeVisible = visible; - } - } else if(WindowImpl.this.visible != visible) { - if(0 != windowHandle) { - setVisibleImpl(visible, x, y, width, height); - WindowImpl.this.waitForVisible(visible, true); - madeVisible = visible; - } + } + } + if(0==windowHandle && visible) { + if( 0<width*height ) { + nativeWindowCreated = createNative(); + WindowImpl.this.waitForVisible(visible, true); + madeVisible = visible; } - - if(null!=lifecycleHook) { - lifecycleHook.setVisibleActionPost(visible, nativeWindowCreated); + } else if(WindowImpl.this.visible != visible) { + if(0 != windowHandle) { + setVisibleImpl(visible, x, y, width, height); + WindowImpl.this.waitForVisible(visible, true); + madeVisible = visible; } + } - if(0!=windowHandle && visible && null!=childWindows && childWindows.size()>0) { - synchronized(childWindowsLock) { - for(int i = 0; i < childWindows.size(); i++ ) { - NativeWindow nw = (NativeWindow) childWindows.get(i); - if(nw instanceof WindowImpl) { - ((WindowImpl)nw).setVisible(true); - } + if(null!=lifecycleHook) { + lifecycleHook.setVisibleActionPost(visible, nativeWindowCreated); + } + + if(0!=windowHandle && visible && null!=childWindows && childWindows.size()>0) { + synchronized(childWindowsLock) { + for(int i = 0; i < childWindows.size(); i++ ) { + NativeWindow nw = (NativeWindow) childWindows.get(i); + if(nw instanceof WindowImpl) { + ((WindowImpl)nw).setVisible(true); } - } - } - if(DEBUG_IMPLEMENTATION) { - System.err.println("Window setVisible: END ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+WindowImpl.this.visible+", nativeWindowCreated: "+nativeWindowCreated+", madeVisible: "+madeVisible); } - } finally { - windowLock.unlock(); + } } - if( getChanged() ) { - sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener + if(DEBUG_IMPLEMENTATION) { + System.err.println("Window setVisible: END ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+WindowImpl.this.visible+", nativeWindowCreated: "+nativeWindowCreated+", madeVisible: "+madeVisible); } + } finally { + windowLock.unlock(); + } + if( nativeWindowCreated || madeVisible ) { + sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener + } + } + + class VisibleAction implements Runnable { + boolean visible; + + public VisibleAction (boolean visible) { + this.visible = visible; + } + + public void run() { + setVisibleActionImpl(visible); } } @@ -696,18 +695,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer System.err.println(msg); Thread.dumpStack(); } - VisibleAction visibleAction = new VisibleAction(visible); - runOnEDTIfAvail(true, visibleAction); + runOnEDTIfAvail(!isSurfaceLocked(), new VisibleAction(visible)); } } class SetSizeActionImpl implements Runnable { - int visibleAction = 0; // 1 invisible, 2 visible (create) int width, height; - public int getVisibleAction() { - return visibleAction; - } public SetSizeActionImpl(int w, int h) { width = w; height = h; @@ -715,6 +709,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer public void run() { windowLock.lock(); try { + int visibleAction = 0; // 1 invisible, 2 visible (create) if ( !fullscreen && ( width != WindowImpl.this.width || WindowImpl.this.height != height ) ) { if(DEBUG_IMPLEMENTATION) { String msg = "Window setSize: START "+WindowImpl.this.width+"x"+WindowImpl.this.height+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible; @@ -737,6 +732,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } if(DEBUG_IMPLEMENTATION) { System.err.println("Window setSize: END "+WindowImpl.this.width+"x"+WindowImpl.this.height+", visibleAction "+visibleAction); + } + switch(visibleAction) { + case 1: setVisibleActionImpl(false); break; + case 2: setVisibleActionImpl(true); break; } } } finally { @@ -747,17 +746,19 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer public void setSize(int width, int height) { if(isValid()) { - SetSizeActionImpl setSizeAction = new SetSizeActionImpl(width, height); - runOnEDTIfAvail(true, setSizeAction); - switch(setSizeAction.getVisibleAction()) { - case 1: setVisible(false); break; - case 2: setVisible(true); break; - } + runOnEDTIfAvail(!isSurfaceLocked(), new SetSizeActionImpl(width, height)); } } class DestroyAction implements Runnable { public void run() { + boolean animatorPaused = false; + if(null!=lifecycleHook) { + animatorPaused = lifecycleHook.pauseRenderingAction(); + } + if(null!=lifecycleHook) { + lifecycleHook.destroyActionPreLock(); + } windowLock.lock(); try { if( !isValid() ) { @@ -797,6 +798,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } finally { windowLock.unlock(); } + if(animatorPaused) { + lifecycleHook.resumeRenderingAction(); + } } } @@ -808,17 +812,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer //Exception ee = new Exception(msg); //ee.printStackTrace(); } - boolean animatorPaused = false; - if(null!=lifecycleHook) { - animatorPaused = lifecycleHook.pauseRenderingAction(); - } - if(null!=lifecycleHook) { - lifecycleHook.destroyActionPreLock(); - } - runOnEDTIfAvail(true, destroyAction); - if(animatorPaused) { - lifecycleHook.resumeRenderingAction(); - } + runOnEDTIfAvail(!isSurfaceLocked(), destroyAction); } } @@ -921,13 +915,17 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } public void run() { - boolean wasVisible; + boolean animatorPaused = false; + if(null!=lifecycleHook) { + animatorPaused = lifecycleHook.pauseRenderingAction(); + } // mirror pos/size so native change notification can get overwritten int x = WindowImpl.this.x; int y = WindowImpl.this.y; int width = WindowImpl.this.width; int height = WindowImpl.this.height; + boolean wasVisible; windowLock.lock(); try { @@ -1160,12 +1158,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer break; case ACTION_NATIVE_CREATION: - // This may run on the Display/Screen connection, - // hence a new EDT task + // This may run on the new Display/Screen connection, hence a new EDT task runOnEDTIfAvail(true, reparentActionRecreate); break; } } + if(animatorPaused) { + lifecycleHook.resumeRenderingAction(); + } } } @@ -1191,19 +1191,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer public int reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) { int reparentActionStrategy = ReparentAction.ACTION_INVALID; if(isValid()) { - boolean animatorPaused = false; - if(null!=lifecycleHook) { - animatorPaused = lifecycleHook.pauseRenderingAction(); - } - try { - ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate); - runOnEDTIfAvail(true, reparentAction); - reparentActionStrategy = reparentAction.getStrategy(); - } finally { - if(animatorPaused) { - lifecycleHook.resumeRenderingAction(); - } - } + ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate); + runOnEDTIfAvail(!isSurfaceLocked(), reparentAction); + reparentActionStrategy = reparentAction.getStrategy(); } return reparentActionStrategy; } @@ -1284,14 +1274,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } finally { windowLock.unlock(); } + sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener } } public void setUndecorated(boolean value) { if(isValid()) { - DecorationActionImpl decorationAction = new DecorationActionImpl(value); - runOnEDTIfAvail(true, decorationAction); - sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener + runOnEDTIfAvail(!isSurfaceLocked(), new DecorationActionImpl(value)); } } @@ -1500,8 +1489,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer public void setPosition(int x, int y) { if(isValid()) { - SetPositionActionImpl setPositionAction = new SetPositionActionImpl(x, y); - runOnEDTIfAvail(true, setPositionAction); + runOnEDTIfAvail(!isSurfaceLocked(), new SetPositionActionImpl(x, y)); } } @@ -1578,14 +1566,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } finally { windowLock.unlock(); } + sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener } } public boolean setFullscreen(boolean fullscreen) { if(isValid()) { - FullScreenActionImpl fullScreenAction = new FullScreenActionImpl(fullscreen); - runOnEDTIfAvail(true, fullScreenAction); - sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener + runOnEDTIfAvail(!isSurfaceLocked(), new FullScreenActionImpl(fullscreen)); } return this.fullscreen; } |