diff options
-rw-r--r-- | src/jogl/classes/javax/media/opengl/awt/GLCanvas.java | 73 | ||||
-rw-r--r-- | src/junit/com/jogamp/test/junit/jogl/awt/TestAWT03GLCanvasRecreate01.java | 183 |
2 files changed, 224 insertions, 32 deletions
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index b2d919eaf..aeb698c81 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -86,17 +86,17 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { defaultGLProfile = GLProfile.getDefault(GLProfile.getDefaultDesktopDevice()); } - private GLProfile glProfile; private GLDrawableHelper drawableHelper = new GLDrawableHelper(); - private GraphicsConfiguration chosen; private AWTGraphicsConfiguration awtConfig; private GLDrawable drawable; private GLContextImpl context; private boolean sendReshape = false; - // copy of the cstr args .. + // copy of the cstr args, mainly for recreation + private GLCapabilitiesImmutable capsReqUser; private GLCapabilitiesChooser chooser; - private GLContext shareWith; + private GLContext shareWith; + private GraphicsDevice device; /** Creates a new GLCanvas component with a default set of OpenGL capabilities, using the default OpenGL capabilities selection @@ -154,25 +154,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } } - this.glProfile = capsReqUser.getGLProfile(); + // instantiation will be issued in addNotify() + this.capsReqUser = capsReqUser; this.chooser = chooser; this.shareWith = shareWith; - - /* - * Save the 'chosen' GraphicsConfiguration for use in getGraphicsConfiguration(). - */ - awtConfig = chooseGraphicsConfiguration(capsReqUser, capsReqUser, chooser, device); - if(null==awtConfig) { - throw new GLException("Error: NULL AWTGraphicsConfiguration"); - } - chosen = awtConfig.getGraphicsConfiguration(); - - if (!Beans.isDesignTime()) { - // no lock required, since this resource ain't available yet - drawable = GLDrawableFactory.getFactory(glProfile).createGLDrawable(NativeWindowFactory.getNativeWindow(this, awtConfig)); - context = (GLContextImpl) drawable.createContext(shareWith); - context.setSynchronized(true); - } + this.device = device; } protected interface DestroyMethod { @@ -230,6 +216,8 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { * otherwise it is from an ancestor component that this Canvas is being * added to, and we go into this block. */ + GraphicsConfiguration chosen = awtConfig.getGraphicsConfiguration(); + if (gc != null && chosen != null && !chosen.equals(gc)) { /* * Check for compatibility with gc. If they differ by only the @@ -350,11 +338,8 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { boolean animatorPaused = false; GLAnimatorControl animator = getAnimator(); if(null!=animator) { - if(regenerate) { - animatorPaused = animator.pause(); - } else { - animator.remove(this); - } + // can't remove us from animator for recreational addNotify() + animatorPaused = animator.pause(); } disposeRegenerate=regenerate; @@ -445,16 +430,36 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { Exception ex1 = new Exception(Thread.currentThread().getName()+" - Info: addNotify - start"); ex1.printStackTrace(); } - // 'super.addNotify()' determines the GraphicsConfiguration, - // while calling this class's overriden 'getGraphicsConfiguration()' method. - // Then it creates the native peer. - // Hence we chose the proper GraphicsConfiguration beforehand (see constructor). + + /** + * 'super.addNotify()' determines the GraphicsConfiguration, + * while calling this class's overriden 'getGraphicsConfiguration()' method + * after which it creates the native peer. + * Hence we have to set the 'awtConfig' before since it's GraphicsConfiguration + * is being used in getGraphicsConfiguration(). + * This code order also allows recreation, ie re-adding the GLCanvas. + */ + awtConfig = chooseGraphicsConfiguration(capsReqUser, capsReqUser, chooser, device); + if(null==awtConfig) { + throw new GLException("Error: NULL AWTGraphicsConfiguration"); + } + + if (!Beans.isDesignTime()) { + // no lock required, since this resource ain't available yet + drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile()) + .createGLDrawable(NativeWindowFactory.getNativeWindow(this, awtConfig)); + context = (GLContextImpl) drawable.createContext(shareWith); + context.setSynchronized(true); + } + + // issues getGraphicsConfiguration() and creates the native peer super.addNotify(); if (!Beans.isDesignTime()) { // no lock required, since this resource ain't available yet disableBackgroundErase(); drawable.setRealized(true); + sendReshape=true; // ensure a reshape is being send .. if(DEBUG) { System.err.println(Thread.currentThread().getName()+" - Realized Drawable: "+drawable); } @@ -576,7 +581,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } public GLProfile getGLProfile() { - return glProfile; + return capsReqUser.getGLProfile(); } public GLCapabilitiesImmutable getChosenGLCapabilities() { @@ -641,7 +646,8 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { if(disposeRegenerate) { // recreate GLDrawable to reflect it's new graphics configuration - drawable = GLDrawableFactory.getFactory(glProfile).createGLDrawable(NativeWindowFactory.getNativeWindow(GLCanvas.this, awtConfig)); + drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile()) + .createGLDrawable(NativeWindowFactory.getNativeWindow(GLCanvas.this, awtConfig)); if(DEBUG) { System.err.println("GLCanvas.dispose(true): new drawable: "+drawable); } @@ -693,6 +699,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { class DisplayAction implements Runnable { public void run() { if (sendReshape) { + if(DEBUG) { + System.err.println(Thread.currentThread().getName()+" - reshape: "+getWidth()+"x"+getHeight()); + } // Note: we ignore the given x and y within the parent component // since we are drawing directly into this heavyweight component. drawableHelper.reshape(GLCanvas.this, 0, 0, getWidth(), getHeight()); diff --git a/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT03GLCanvasRecreate01.java b/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT03GLCanvasRecreate01.java new file mode 100644 index 000000000..7678f60e1 --- /dev/null +++ b/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT03GLCanvasRecreate01.java @@ -0,0 +1,183 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.test.junit.jogl.awt; + +import javax.media.opengl.GLProfile; +import javax.media.opengl.awt.GLCanvas; +import com.jogamp.opengl.util.Animator; + +import com.jogamp.test.junit.util.UITestCase; +import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.test.junit.util.MiscUtils; + +import java.awt.Frame; +import java.awt.Label; + +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.After; +import org.junit.Test; + + +public class TestAWT03GLCanvasRecreate01 extends UITestCase { + static long durationPerTest = 1000; // ms + + Frame frame1=null; + Frame frame2=null; + GLCanvas glCanvas=null; + Label label = null; + Animator animator = null; + + @BeforeClass + public static void startup() { + GLProfile.initSingleton(true); + System.out.println("GLProfile <static> "+GLProfile.glAvailabilityToString()); + } + + @Before + public void init() { + glCanvas = new GLCanvas(); + Assert.assertNotNull(glCanvas); + glCanvas.addGLEventListener(new Gears()); + + animator = new Animator(glCanvas); + animator.start(); + + label = new Label("No GLCanvas"); + + frame1 = new Frame("Frame 1"); + Assert.assertNotNull(frame1); + frame1.add(label); + frame1.setSize(512, 512); + frame1.setLocation(0, 0); + + frame2 = new Frame("Frame 2"); + Assert.assertNotNull(frame2); + frame2.add(label); + frame2.setSize(512, 512); + frame2.setLocation(512, 0); + } + + @After + public void release() { + Assert.assertNotNull(frame1); + Assert.assertNotNull(frame2); + Assert.assertNotNull(glCanvas); + try { + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + glCanvas.destroy(); + frame1.dispose(); + frame2.dispose(); + }}); + } catch (Throwable t) { + t.printStackTrace(); + Assume.assumeNoException(t); + } + frame1=null; + frame2=null; + glCanvas=null; + + animator.stop(); + animator=null; + } + + private void addCanvas(final Frame frame) { + try { + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame.remove(label); + frame.add(glCanvas); + frame.validate(); + }}); + } catch (Throwable t) { + t.printStackTrace(); + Assume.assumeNoException(t); + } + } + + private void removeCanvas(final Frame frame) { + try { + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame.remove(glCanvas); + frame.add(label); + frame.validate(); + }}); + } catch (Throwable t) { + t.printStackTrace(); + Assume.assumeNoException(t); + } + } + + private void setVisible(final Frame frame, final boolean v) { + try { + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame.setVisible(v); + }}); + } catch (Throwable t) { + t.printStackTrace(); + Assume.assumeNoException(t); + } + } + + + @Test + public void testAddRemove3Times() throws InterruptedException { + setVisible(frame1, true); + setVisible(frame2, true); + + addCanvas(frame1); + Thread.sleep(durationPerTest/4); + + removeCanvas(frame1); + addCanvas(frame2); + Thread.sleep(durationPerTest/4); + + removeCanvas(frame2); + addCanvas(frame1); + Thread.sleep(durationPerTest/4); + + removeCanvas(frame1); + addCanvas(frame2); + Thread.sleep(durationPerTest/4); + } + + public static void main(String args[]) { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + durationPerTest = MiscUtils.atoi(args[++i], (int)durationPerTest); + } + } + org.junit.runner.JUnitCore.main(TestAWT03GLCanvasRecreate01.class.getName()); + } +} |