summaryrefslogtreecommitdiffstats
path: root/src/newt
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2010-11-21 03:41:22 +0100
committerSven Gothel <[email protected]>2010-11-21 03:41:22 +0100
commit2aa296771e3e8dd6cf027f27b0455d1803244bfe (patch)
tree514c532f9ddff7f84e9e6fb75e883f04c71ec74f /src/newt
parent6f73de7c5bb85d0175c8dda7c55317923017bbe0 (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')
-rw-r--r--src/newt/classes/com/jogamp/newt/Window.java3
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/WindowImpl.java86
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java2
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java44
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);