diff options
author | Sven Gothel <[email protected]> | 2010-11-21 03:41:22 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-11-21 03:41:22 +0100 |
commit | 2aa296771e3e8dd6cf027f27b0455d1803244bfe (patch) | |
tree | 514c532f9ddff7f84e9e6fb75e883f04c71ec74f /src/newt | |
parent | 6f73de7c5bb85d0175c8dda7c55317923017bbe0 (diff) |
JOGL/NEWT: Animator fixes
Consider use cases with many drawables and no drawables at start,
this had to be reflected all over this patch set, implementation,
usage and test cases.
- GLAnimatorControl
- refine API doc / states
- add 'void remove(GLAutoDrawable drawable);'
- Animator*:
- using RecursiveLock 'stateSync' for all actions out of the big synchronized (animator) block:
- get status methods (thread, isPaused, ..), hence no more synchronized
- display drawables change, utilizing synced ArrayList swap
This removes the need for volatiles usage shouldPause/shouldStop within the display method.
- added blocking wait for state change for add(GLAutoDrawable)/remove(GLAutoDrawable) method
- remove flawed double checked locking in anim thread (pause/idle condition)
- thread is now a daemon thread, hence it won't hinder the JVM from shutdown
-
- Animator use change:
- Always resume after pause, except in case of final destroy -> NEWT invalidate / GLCanvas,
this considers use cases with many drawables and no drawables at start.
- GLDrawableHelper: Don't pause at implicit dispose()
Diffstat (limited to 'src/newt')
4 files changed, 67 insertions, 68 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index 8b9e7bb4e..99db47168 100644 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -31,7 +31,6 @@ package com.jogamp.newt; import com.jogamp.newt.event.WindowListener; import com.jogamp.newt.event.KeyListener; import com.jogamp.newt.event.MouseListener; -import com.jogamp.newt.event.ScreenModeListener; import com.jogamp.newt.impl.Debug; import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.CapabilitiesImmutable; @@ -43,7 +42,7 @@ import javax.media.nativewindow.util.Insets; * Specifying the public Window functionality for the * using a Window and for shadowing one like {@link com.jogamp.newt.opengl.GLWindow}. */ -public interface Window extends NativeWindow, ScreenModeListener { +public interface Window extends NativeWindow { public static final boolean DEBUG_MOUSE_EVENT = Debug.debug("Window.MouseEvent"); public static final boolean DEBUG_KEY_EVENT = Debug.debug("Window.KeyEvent"); public static final boolean DEBUG_WINDOW_EVENT = Debug.debug("Window.WindowEvent"); diff --git a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java index f0aa9effd..fd5c1b662 100644 --- a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java +++ b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java @@ -68,7 +68,7 @@ import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.Point; import javax.media.nativewindow.util.Rectangle; -public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenModeListener +public abstract class WindowImpl implements Window, NEWTEventConsumer { public static final boolean DEBUG_TEST_REPARENT_INCOMPATIBLE = Debug.isPropertyDefined("newt.test.Window.reparent.incompatible", true); @@ -112,6 +112,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod private ArrayList windowListeners; private boolean repaintQueued = false; + ScreenModeListenerImpl screenModeListenerImpl = new ScreenModeListenerImpl(); + private void initializeStates() { invalidate(true); @@ -250,9 +252,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod * Invoked for expensive modifications, ie while reparenting and ScreenMode change.<br> * No lock is hold when invoked.<br> * + * @return true is paused, otherwise false. If true {@link #resumeRenderingAction()} shall be issued. + * * @see #resumeRenderingAction() */ - void pauseRenderingAction(); + boolean pauseRenderingAction(); /** * Invoked for expensive modifications, ie while reparenting and ScreenMode change. @@ -280,7 +284,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod screenReferenceAdded = true; createNativeImpl(); setVisibleImpl(true, x, y, width, height); - screen.addScreenModeListener(this); + screen.addScreenModeListener(screenModeListenerImpl); } } finally { if(null!=parentWindow) { @@ -308,7 +312,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod try { if( null != screen ) { if( 0 != windowHandle ) { - screen.removeScreenModeListener(WindowImpl.this); + screen.removeScreenModeListener(screenModeListenerImpl); closeNativeImpl(); removeScreenReference(); } @@ -438,20 +442,22 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod public final int lockSurface() { int res = LOCK_SURFACE_NOT_READY; - windowLock.lock(); - AbstractGraphicsDevice adevice = screen.getDisplay().getGraphicsDevice(); - adevice.lock(); - try { - res = lockSurfaceImpl(); - } finally { - if(!isNativeValid()) { - adevice.unlock(); - windowLock.unlock(); - res = LOCK_SURFACE_NOT_READY; + if(isNativeValid()) { + AbstractGraphicsDevice adevice = screen.getDisplay().getGraphicsDevice(); + adevice.lock(); + try { + res = lockSurfaceImpl(); + } finally { + if( LOCK_SURFACE_NOT_READY == res ) { + adevice.unlock(); + } } } + if( LOCK_SURFACE_NOT_READY == res ) { + windowLock.unlock(); + } return res; } @@ -752,14 +758,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod //Exception ee = new Exception(msg); //ee.printStackTrace(); } + boolean animatorPaused = false; if(null!=lifecycleHook) { - lifecycleHook.pauseRenderingAction(); + animatorPaused = lifecycleHook.pauseRenderingAction(); } if(null!=lifecycleHook) { lifecycleHook.destroyActionPreLock(); } runOnEDTIfAvail(true, destroyAction); - if(null!=lifecycleHook) { + if(animatorPaused) { lifecycleHook.resumeRenderingAction(); } } @@ -1134,15 +1141,16 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod public int reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) { int reparentActionStrategy = ReparentAction.ACTION_INVALID; if(isValid()) { + boolean animatorPaused = false; if(null!=lifecycleHook) { - lifecycleHook.pauseRenderingAction(); + animatorPaused = lifecycleHook.pauseRenderingAction(); } try { ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate); runOnEDTIfAvail(true, reparentAction); reparentActionStrategy = reparentAction.getStrategy(); } finally { - if(null!=lifecycleHook) { + if(animatorPaused) { lifecycleHook.resumeRenderingAction(); } } @@ -1531,31 +1539,35 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod return this.fullscreen; } - public void screenModeChangeNotify(ScreenMode sm) { - if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { - System.err.println("Window.screenModeChangeNotify: "+sm); - } + class ScreenModeListenerImpl implements ScreenModeListener { + boolean animatorPaused = false; - if(null!=lifecycleHook) { - lifecycleHook.pauseRenderingAction(); - } - } + public void screenModeChangeNotify(ScreenMode sm) { + if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { + System.err.println("Window.screenModeChangeNotify: "+sm); + } - public void screenModeChanged(ScreenMode sm, boolean success) { - if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { - System.err.println("Window.screenModeChanged: "+sm+", success: "+success); + if(null!=lifecycleHook) { + animatorPaused = lifecycleHook.pauseRenderingAction(); + } } - if(success) { - DimensionReadOnly screenSize = sm.getMonitorMode().getSurfaceSize().getResolution(); - if ( getHeight() > screenSize.getHeight() || - getWidth() > screenSize.getWidth() ) { - setSize(screenSize.getWidth(), screenSize.getHeight()); + public void screenModeChanged(ScreenMode sm, boolean success) { + if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { + System.err.println("Window.screenModeChanged: "+sm+", success: "+success); } - } - if(null!=lifecycleHook) { - lifecycleHook.resumeRenderingAction(); + if(success) { + DimensionReadOnly screenSize = sm.getMonitorMode().getSurfaceSize().getResolution(); + if ( getHeight() > screenSize.getHeight() || + getWidth() > screenSize.getWidth() ) { + setSize(screenSize.getWidth(), screenSize.getHeight()); + } + } + + if(animatorPaused) { + lifecycleHook.resumeRenderingAction(); + } sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener } } diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java index 5d7bcd7b3..d4f4f77ea 100644 --- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java @@ -59,7 +59,7 @@ public class WindowsWindow extends WindowImpl { hdc = GetDC0(getWindowHandle()); hmon = MonitorFromWindow0(getWindowHandle()); } - return LOCK_SUCCESS; + return ( 0 != hdc ) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY; } protected void unlockSurfaceImpl() { diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index dc5c12b58..da22a6217 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -86,11 +86,11 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer { public void windowDestroyNotify(WindowEvent e) { // Is an animator thread perform rendering? - if (GLWindow.this.helper.isExternalAnimatorAnimating()) { + if (GLWindow.this.helper.isExternalAnimatorRunning()) { // Pause animations before initiating safe destroy. GLAnimatorControl ctrl = GLWindow.this.helper.getAnimator(); ctrl.pause(); - + destroy(); ctrl.resume(); @@ -251,15 +251,7 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer { public final void addChild(NativeWindow win) { window.addChild(win); } - - public void screenModeChangeNotify(ScreenMode sm) { - window.screenModeChangeNotify(sm); - } - - public void screenModeChanged(ScreenMode sm, boolean success) { - window.screenModeChanged(sm, success); - } - + //---------------------------------------------------------------------- // Window.LifecycleHook Implementation // @@ -299,12 +291,10 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer { } DisposeAction disposeAction = new DisposeAction(); - /** Window.LifecycleHook */ public synchronized void destroyActionPreLock() { // nop } - /** Window.LifecycleHook */ public synchronized void destroyActionInLock() { if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) { String msg = new String("GLWindow.destroy() "+Thread.currentThread()+", start"); @@ -334,7 +324,6 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer { } } - /** Window.LifecycleHook */ public synchronized void invalidate(boolean unrecoverable) { if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) { String msg = new String("GLWindow.invalidate("+unrecoverable+") "+Thread.currentThread()+", start"); @@ -344,14 +333,13 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer { } if(unrecoverable) { GLAnimatorControl ctrl = GLWindow.this.getAnimator(); - if ( null!=ctrl && ctrl.isStarted() ) { - ctrl.stop(); + if ( null!=ctrl ) { + ctrl.remove(GLWindow.this); } helper=null; } } - /** Window.LifecycleHook */ public synchronized void resetCounter() { if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) { System.err.println("GLWindow.resetCounter() "+Thread.currentThread()); @@ -394,21 +382,20 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer { //e1.printStackTrace(); } } - - boolean animatorPaused = false; - - public synchronized void pauseRenderingAction() { + + public synchronized boolean pauseRenderingAction() { + boolean animatorPaused = false; GLAnimatorControl ctrl = GLWindow.this.getAnimator(); - if ( null!=ctrl && ctrl.isAnimating() && ctrl.getThread() != Thread.currentThread() ) { + if ( null!=ctrl && ctrl.isStarted() && !ctrl.isPaused()) { animatorPaused = true; ctrl.pause(); } + return animatorPaused; } public synchronized void resumeRenderingAction() { GLAnimatorControl ctrl = GLWindow.this.getAnimator(); - if ( null!=ctrl && animatorPaused ) { - animatorPaused = false; + if ( null!=ctrl && ctrl.isPaused() ) { ctrl.resume(); } } @@ -517,10 +504,11 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer { setVisible(true); } - if( isVisible() && isNativeValid() && null != context ) { - if(forceReshape) { - sendReshape = true; - } + if(forceReshape) { + sendReshape = true; + } + + if( isVisible() && null != context ) { if( NativeSurface.LOCK_SURFACE_NOT_READY < lockSurface() ) { try { helper.invokeGL(drawable, context, displayAction, initAction); |