diff options
author | Sven Gothel <[email protected]> | 2010-10-27 16:39:20 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-10-27 16:39:20 +0200 |
commit | e6225fce71daa90a2a2b631550ba048c2a84ff25 (patch) | |
tree | 863985817e72b5b9fc855de3be4f2154fa86dedf /src | |
parent | e6131c6b2cbf8d1e5a05f0343612f5083b55aaa9 (diff) |
WindowImpl/GLWindow LifecycleHook:
- 'destroyAction' -> 'destroyActionPreLock' 'destroyActionInLock',
to be able to stop animation before locking.
GLDrawableHelper.invokeGL() dispose case (initAction == null):
- pause animator if animating before makeCurrent (locking)
GLCanvas/GLJPanel dispose: recreate case
- resume animator if was animating
Diffstat (limited to 'src')
8 files changed, 154 insertions, 69 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java index c8cfd9a01..e8df40b13 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java @@ -131,6 +131,11 @@ public class GLDrawableHelper { } } + /** + * Issues {@link javax.media.opengl.GLEventListener#dispose(javax.media.opengl.GLAutoDrawable)} + * to all listeners. + * @param drawable + */ public final void dispose(GLAutoDrawable drawable) { synchronized(listenersLock) { listenersIter = true; @@ -283,12 +288,24 @@ public class GLDrawableHelper { } private static final ThreadLocal perThreadInitAction = new ThreadLocal(); + /** Principal helper method which runs a Runnable with the context made current. This could have been made part of GLContext, but a - desired goal is to be able to implement the GLCanvas in terms of + desired goal is to be able to implement GLAutoDrawable's in terms of the GLContext's public APIs, and putting it into a separate class helps ensure that we don't inadvertently use private - methods of the GLContext or its implementing classes. */ + methods of the GLContext or its implementing classes.<br> + * <br> + * Remark: In case this method is called to dispose the GLDrawable/GLAutoDrawable, + * <code>initAction</code> shall be <code>null</code> to mark this cause.<br> + * In this case, the locally delegated {@link javax.media.opengl.GLAnimatorControl} via {@link #setAnimator(javax.media.opengl.GLAnimatorControl) setAnimator(animatorControl)} + * is paused first, if {@link javax.media.opengl.GLAnimatorControl#isAnimating()}. + * + * @param drawable + * @param context + * @param runnable + * @param initAction + */ public final void invokeGL(GLDrawable drawable, GLContext context, Runnable runnable, @@ -300,6 +317,20 @@ public class GLDrawableHelper { } return; } + + if(null==initAction) { + // disposal case + + if(!context.isCreated()) { + throw new GLException("Dispose case (no init action given): Native context must be created: "+context); + } + + GLAnimatorControl animCtrl = getAnimator(); + if(null!=animCtrl && animCtrl.isAnimating()) { + animCtrl.pause(); + } + } + // Support for recursive makeCurrent() calls as well as calling // other drawables' display() methods from within another one's GLContext lastContext = GLContext.getCurrent(); @@ -308,9 +339,6 @@ public class GLDrawableHelper { lastContext.release(); } - if(!context.isCreated() && null == initAction) { - throw new GLException("Context has to be created, but no initAction is given: "+context); - } int res = 0; try { res = context.makeCurrent(); diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index 4ac21204f..c165a4833 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -315,6 +315,12 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } if(null!=context) { + boolean animatorWasAnimating = false; + GLAnimatorControl animator = getAnimator(); + if(null!=animator) { + animatorWasAnimating = animator.isAnimating(); + } + disposeRegenerate=regenerate; if (Threading.isSingleThreaded() && @@ -336,6 +342,10 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } else if(context.isCreated()) { drawableHelper.invokeGL(drawable, context, disposeAction, null); } + + if(regenerate && animatorWasAnimating && animator.isPaused()) { + animator.resume(); + } } if(DEBUG) { @@ -420,9 +430,15 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { if(null==awtConfig) { throw new GLException("Error: AWTGraphicsConfiguration is null"); } - drawable = GLDrawableFactory.getFactory(glProfile).createGLDrawable(NativeWindowFactory.getNativeWindow(this, awtConfig)); - context = (GLContextImpl) drawable.createContext(shareWith); - context.setSynchronized(true); + // awtConfig.getScreen().getDevice().lock(); + try { + drawable = GLDrawableFactory.getFactory(glProfile).createGLDrawable(NativeWindowFactory.getNativeWindow(this, awtConfig)); + context = (GLContextImpl) drawable.createContext(shareWith); + context.setSynchronized(true); + drawable.setRealized(true); + } finally { + // awtConfig.getScreen().getDevice().unlock(); + } } finally { NativeWindowFactory.getDefaultToolkitLock().unlock(); } @@ -430,7 +446,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { if(DEBUG) { System.err.println("Created Drawable: "+drawable); } - drawable.setRealized(true); } } diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index 192695955..10aeefaf5 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -213,7 +213,14 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { Exception ex1 = new Exception("Info: dispose("+regenerate+") - start"); ex1.printStackTrace(); } + if (backend != null) { + boolean animatorWasAnimating = false; + GLAnimatorControl animator = getAnimator(); + if(null!=animator) { + animatorWasAnimating = animator.isAnimating(); + } + disposeRegenerate=regenerate; disposeContext=backend.getContext(); disposeDrawable=backend.getDrawable(); @@ -242,6 +249,10 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { if(null==disposeContext) { isInitialized = false; } + + if(regenerate && animatorWasAnimating && animator.isPaused()) { + animator.resume(); + } } if(DEBUG) { diff --git a/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWTRobotUsageBeforeJOGLInitBug411.java b/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWTRobotUsageBeforeJOGLInitBug411.java index 62fc02251..e77f4f8b0 100644 --- a/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWTRobotUsageBeforeJOGLInitBug411.java +++ b/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWTRobotUsageBeforeJOGLInitBug411.java @@ -28,7 +28,6 @@ package com.jogamp.test.junit.jogl.awt; -import com.jogamp.test.junit.util.UITestCase; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; import com.jogamp.test.junit.util.*; @@ -43,19 +42,15 @@ import com.jogamp.newt.Screen; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.newt.awt.NewtCanvasAWT; -import java.awt.AWTException; import java.awt.BorderLayout; import java.awt.Canvas; import java.awt.Color; import java.awt.Dimension; import java.awt.AWTException; -import java.awt.LayoutManager; import java.awt.Robot; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.InputEvent; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; @@ -68,7 +63,6 @@ import javax.swing.BorderFactory; import javax.swing.border.Border; import org.junit.Assert; -import org.junit.Assume; import org.junit.BeforeClass; import org.junit.AfterClass; import org.junit.Test; @@ -238,12 +232,10 @@ public class TestSwingAWTRobotUsageBeforeJOGLInitBug411 extends UITestCase { } robot.mouseRelease(InputEvent.BUTTON1_MASK); - for(int i=0; !windowClosing && i<durationPerTest/10; i++) { - Thread.sleep(10); + for(int i=0; !windowClosing && i<durationPerTest/100; i++) { + Thread.sleep(100); } - animator.stop(); - Assert.assertNotNull(canvas); javax.swing.SwingUtilities.invokeAndWait(new Runnable() { public void run() { @@ -251,11 +243,13 @@ public class TestSwingAWTRobotUsageBeforeJOGLInitBug411 extends UITestCase { frame.pack(); } }); + Assert.assertEquals(false, animator.isAnimating()); } @Test - public void test01GLCanvas() throws AWTException, InterruptedException, InvocationTargetException { - System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.test01GLCanvas(): Start"); + public void test01NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException { + System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.test01NewtCanvasAWT(): Start"); + GLProfile glp = GLProfile.getDefault(); GLCapabilities caps = new GLCapabilities(glp); @@ -268,45 +262,40 @@ public class TestSwingAWTRobotUsageBeforeJOGLInitBug411 extends UITestCase { Animator anim0 = new Animator(win0); anim0.start(); - GLCanvas glCanvas = new GLCanvas(caps); + NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(GLWindow.create(caps)); - runTestGL(glCanvas, glCanvas); + runTestGL(newtCanvasAWT, (GLAutoDrawable)newtCanvasAWT.getNEWTChild()); - anim0.stop(); win0.destroy(true); - System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.test01GLCanvas(): End"); + Assert.assertEquals(false, anim0.isAnimating()); + + newtCanvasAWT.destroy(true); + + System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.test01NewtCanvasAWT(): End"); } @Test - public void test02NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException { - System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.test02NewtCanvasAWT(): Start"); - + public void test02GLCanvas() throws AWTException, InterruptedException, InvocationTargetException { + System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.test02GLCanvas(): Start"); GLProfile glp = GLProfile.getDefault(); GLCapabilities caps = new GLCapabilities(glp); - GLWindow winDummy = GLWindow.create(caps); - winDummy.addGLEventListener(new Gears()); - GLWindow win0 = GLWindow.create(caps); win0.setSize(100,100); win0.setVisible(true); Screen screen = win0.getScreen(); win0.setPosition(screen.getWidth()-150, screen.getHeight()-150); win0.addGLEventListener(new Gears()); - Animator anim0 = new Animator(win0); + Animator anim0 = new Animator(win0); anim0.start(); - NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(GLWindow.create(caps)); + GLCanvas glCanvas = new GLCanvas(caps); - runTestGL(newtCanvasAWT, (GLAutoDrawable)newtCanvasAWT.getNEWTChild()); - newtCanvasAWT.destroy(true); + runTestGL(glCanvas, glCanvas); - anim0.stop(); win0.destroy(true); - - winDummy.destroy(true); - - System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.test02NewtCanvasAWT(): End"); + Assert.assertEquals(false, anim0.isAnimating()); + System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.test02GLCanvas(): End"); } static int atoi(String a) { diff --git a/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java index 73d962dfa..f136b2a3c 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java +++ b/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java @@ -253,16 +253,14 @@ public class TestGLWindows01NEWT extends UITestCase { Assert.assertNotNull(display); display.setDestroyWhenUnused(true); - Screen screen1 = NewtFactory.createScreen(display, 0); // screen 0 - Assert.assertNotNull(screen1); - GLWindow window1 = createWindow(screen1, caps, width, height, + Screen screen = NewtFactory.createScreen(display, 0); // screen 0 + Assert.assertNotNull(screen); + GLWindow window1 = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */, false /*addGLEventListenerAfterVisible*/); Assert.assertNotNull(window1); - Screen screen2 = NewtFactory.createScreen(display, 0); // screen 0 - Assert.assertNotNull(screen2); - GLWindow window2 = createWindow(screen2, caps, width, height, + GLWindow window2 = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */, false /*addGLEventListenerAfterVisible*/); Assert.assertNotNull(window2); @@ -274,11 +272,8 @@ public class TestGLWindows01NEWT extends UITestCase { Assert.assertNotNull(display.getEDTUtil()); Assert.assertEquals(true,display.getEDTUtil().isRunning()); - Assert.assertEquals(1,screen1.getReferenceCount()); - Assert.assertEquals(true,screen1.isNativeValid()); - - Assert.assertEquals(1,screen2.getReferenceCount()); - Assert.assertEquals(true,screen2.isNativeValid()); + Assert.assertEquals(2,screen.getReferenceCount()); + Assert.assertEquals(true,screen.isNativeValid()); int state; for(state=0; state*100<durationPerTest; state++) { @@ -297,11 +292,8 @@ public class TestGLWindows01NEWT extends UITestCase { Assert.assertNotNull(display.getEDTUtil()); Assert.assertEquals(false,display.getEDTUtil().isRunning()); - Assert.assertEquals(0,screen1.getReferenceCount()); - Assert.assertEquals(false,screen1.isNativeValid()); - - Assert.assertEquals(0,screen2.getReferenceCount()); - Assert.assertEquals(false,screen2.isNativeValid()); + Assert.assertEquals(0,screen.getReferenceCount()); + Assert.assertEquals(false,screen.isNativeValid()); } @Test diff --git a/src/junit/com/jogamp/test/junit/newt/TestGLWindows02NEWTAnimated.java b/src/junit/com/jogamp/test/junit/newt/TestGLWindows02NEWTAnimated.java index 7a8bc1db0..12cc7875a 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestGLWindows02NEWTAnimated.java +++ b/src/junit/com/jogamp/test/junit/newt/TestGLWindows02NEWTAnimated.java @@ -130,8 +130,8 @@ public class TestGLWindows02NEWTAnimated extends UITestCase { while(animator.isAnimating() && animator.getDuration()<durationPerTest) { Thread.sleep(100); } - animator.stop(); destroyWindow(window, true); + Assert.assertEquals(false, animator.isAnimating()); } @Test @@ -144,13 +144,43 @@ public class TestGLWindows02NEWTAnimated extends UITestCase { while(animator.isAnimating() && animator.getDuration()<durationPerTest) { Thread.sleep(100); } - animator.stop(); destroyWindow(window, false); destroyWindow(window, true); + Assert.assertEquals(false, animator.isAnimating()); } @Test - public void testWindowDecor03TwoWin() throws InterruptedException { + public void testWindowDecor03TwoWinOneDisplay() throws InterruptedException { + GLCapabilities caps = new GLCapabilities(glp); + Assert.assertNotNull(caps); + + Display display = NewtFactory.createDisplay(null); // local display + Assert.assertNotNull(display); + + Screen screen = NewtFactory.createScreen(display, 0); // screen 0 + Assert.assertNotNull(screen); + GLWindow window1 = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */); + Assert.assertNotNull(window1); + + GLWindow window2 = createWindow(screen, caps, width-10, height-10, true /* onscreen */, false /* undecorated */); + Assert.assertNotNull(window2); + + Animator animator1 = new Animator(window1); + animator1.start(); + Animator animator2 = new Animator(window2); + animator2.start(); + while(animator1.isAnimating() && animator1.getDuration()<durationPerTest) { + Thread.sleep(100); + } + + destroyWindow(window2, true); + Assert.assertEquals(false, animator2.isAnimating()); + + destroyWindow(window1, true); + Assert.assertEquals(false, animator1.isAnimating()); + } + @Test + public void testWindowDecor03TwoWinTwoDisplays() throws InterruptedException { GLCapabilities caps = new GLCapabilities(glp); Assert.assertNotNull(caps); @@ -178,13 +208,11 @@ public class TestGLWindows02NEWTAnimated extends UITestCase { Thread.sleep(100); } - animator2.stop(); - Assert.assertEquals(false, animator2.isAnimating()); - destroyWindow(window2, false); - - animator1.stop(); - Assert.assertEquals(false, animator1.isAnimating()); destroyWindow(window1, true); + Assert.assertEquals(false, animator1.isAnimating()); + + destroyWindow(window2, false); + Assert.assertEquals(false, animator2.isAnimating()); } public static void setDemoFields(GLEventListener demo, GLWindow glWindow) { diff --git a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java index f9383ea38..0eb8f9644 100644 --- a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java +++ b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java @@ -149,10 +149,19 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod /** * Invoked before Window destroy action, - * allows releasing of resources depending on the native Window. + * allows releasing of resources depending on the native Window.<br> + * Surface not locked yet.<br> + * Called not necessarily from EDT. + */ + void destroyActionPreLock(boolean unrecoverable); + + /** + * Invoked before Window destroy action, + * allows releasing of resources depending on the native Window.<br> + * Surface locked.<br> * Called from EDT. */ - void destroyAction(boolean unrecoverable); + void destroyActionInLock(boolean unrecoverable); /** Only informal, when starting reparenting */ void reparentActionPre(); @@ -640,7 +649,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod } if(null!=lifecycleHook) { - lifecycleHook.destroyAction(unrecoverable); + lifecycleHook.destroyActionInLock(unrecoverable); } // Now us .. @@ -680,6 +689,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod //Exception ee = new Exception(msg); //ee.printStackTrace(); } + if(null!=lifecycleHook) { + lifecycleHook.destroyActionPreLock(unrecoverable); + } DestroyAction destroyAction = new DestroyAction(unrecoverable); runOnEDTIfAvail(true, destroyAction); } diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index aef4de92a..f6901e54a 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -278,7 +278,17 @@ public class GLWindow implements GLAutoDrawable, Window { DisposeAction disposeAction = new DisposeAction(); /** Window.LifecycleHook */ - public synchronized void destroyAction(boolean unrecoverable) { + public synchronized void destroyActionPreLock(boolean unrecoverable) { + GLAnimatorControl animator = GLWindow.this.getAnimator(); + // since we have no 'recreation model' for dispose here yet, + // we simply stop the animator if started. + if(null!=animator && animator.isStarted()) { + animator.stop(); + } + } + + /** Window.LifecycleHook */ + public synchronized void destroyActionInLock(boolean unrecoverable) { if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) { String msg = new String("GLWindow.destroy("+unrecoverable+") "+Thread.currentThread()+", start"); System.err.println(msg); |