diff options
author | Sven Gothel <[email protected]> | 2013-01-11 08:13:24 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-01-11 08:13:24 +0100 |
commit | 224fab1b2c71464826594740022fdcbe278867dc (patch) | |
tree | fb4292f8cd8b8fa2664c04005ba2ddde630d159c /src/test | |
parent | 6fd9c3d84e1758ae27cd10a89237a558460ca1fb (diff) |
GLAutoDrawable/AnimatorBase: Add ExclusiveContextThread (ECT) feature; AnimatorBase: Add setModeBits/MODE_EXPECT_AWT_RENDERING_THREAD; FPSAnimator: Make transactions deterministic.
ExclusiveContextThread (ECT) allows user to dedicate a GLContext to a given thread.
Only the ECT will be allowed to claim the GLContext, hence releasing must be done on the ECT itself.
The core feature is accessible via GLAutoDrawable, while it can be conveniently enabled and disabled
via an AnimatorBase implementation. The latter ensures it's being released on the ECT and waits for the result.
Note that ECT cannot be guaranteed to work correctly w/ native (heavyweight) AWT components
due to resource locking and AWT-EDT access. This is disabled in all new tests per default and
noted on the API doc.
Note: 'Animator transaction' == start(), stop(), pause(), resume().
- Add ExclusiveContextThread (ECT) feature
- GLAutoDrawable NEW:
- Thread setExclusiveContextThread(Thread t)
- Thread getExclusiveContextThread()
- AnimatorBase NEW:
- Thread setExclusiveContext(Thread t)
- boolean setExclusiveContext(boolean enable)
- boolean isExclusiveContextEnabled()
- Thread getExclusiveContextThread()
- AnimatorBase: Add setModeBits/MODE_EXPECT_AWT_RENDERING_THREAD
Allows user to pre-determine whether AWT rendering is expected before starting the animator.
If AWT is excluded, a more simple and transaction correct impl. will be used.
- FPSAnimator: Make transactions deterministic.
FPSAnimator previously did not ensure whether a transaction was completed.
A deterministic transaction is required to utilize ECT.
FPSAnimator now uses same mechanism like Animator to ensure completeness,
i.e. Condition and 'finishLifecycleAction(..)'. Both are moved to AnimatorBase.
Tested manually on Linux/NV, Linux/AMD, Windows/NV and OSX/NV.
- All new tests validated correctness.
- All new tests shows an performance increase of ~3x w/ single GLWindow, where multiple GLWindows don't show a perf. increase.
Diffstat (limited to 'src/test')
18 files changed, 1685 insertions, 55 deletions
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase00.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase00.java new file mode 100644 index 000000000..c6eb3a103 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase00.java @@ -0,0 +1,420 @@ +/** + * Copyright 2013 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.opengl.test.junit.jogl.acore; + +import com.jogamp.newt.NewtFactory; +import com.jogamp.newt.Window; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; +import com.jogamp.opengl.test.junit.util.UITestCase; + +import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.AnimatorBase; + +import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; + +import javax.media.nativewindow.Capabilities; +import javax.media.nativewindow.util.InsetsImmutable; + +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLProfile; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.AfterClass; +import org.junit.Test; + +/** + * ExclusiveContextThread base implementation to test correctness of the ExclusiveContext feature _and_ AnimatorBase. + */ +public abstract class ExclusiveContextBase00 extends UITestCase { + static boolean testExclusiveWithAWT = false; + static final int durationParts = 9; + static long duration = 320 * durationParts; // ms ~ 20 frames + + static boolean showFPS = false; + static int showFPSRate = 100; + + static final int demoSize = 128; + + static InsetsImmutable insets = null; + static int scrnHeight, scrnWidth; + static int num_x, num_y; + + static int swapInterval = 0; + + @BeforeClass + public static void initClass00() { + Window dummyWindow = NewtFactory.createWindow(new Capabilities()); + dummyWindow.setSize(demoSize, demoSize); + dummyWindow.setVisible(true); + Assert.assertEquals(true, dummyWindow.isVisible()); + Assert.assertEquals(true, dummyWindow.isNativeValid()); + insets = dummyWindow.getInsets(); + scrnHeight = dummyWindow.getScreen().getHeight(); + scrnWidth = dummyWindow.getScreen().getWidth(); + num_x = scrnWidth / ( demoSize + insets.getTotalWidth() ) - 2; + num_y = scrnHeight / ( demoSize + insets.getTotalHeight() ) - 2; + dummyWindow.destroy(); + } + + @AfterClass + public static void releaseClass00() { + } + + protected abstract boolean isAWTTestCase(); + protected abstract Thread getAWTRenderThread(); + protected abstract AnimatorBase createAnimator(); + protected abstract GLAutoDrawable createGLAutoDrawable(String title, int x, int y, int width, int height, GLCapabilitiesImmutable caps); + protected abstract void setGLAutoDrawableVisible(GLAutoDrawable[] glads); + protected abstract void destroyGLAutoDrawableVisible(GLAutoDrawable glad); + + protected void runTestGL(GLCapabilitiesImmutable caps, int drawableCount, boolean exclusive, boolean preAdd, boolean shortenTest) throws InterruptedException { + final boolean useAWTRenderThread = isAWTTestCase(); + if( useAWTRenderThread && exclusive ) { + if( testExclusiveWithAWT ) { + System.err.println("Warning: Testing AWT + Exclusive -> Not advised!"); + } else { + System.err.println("Info: Skip test: AWT + Exclusive!"); + return; + } + } + if( useAWTRenderThread && exclusive && !testExclusiveWithAWT) { + System.err.println("Skip test: AWT + Exclusive -> Not advised!"); + return; + } + final Thread awtRenderThread = getAWTRenderThread(); + final AnimatorBase animator = createAnimator(); + if( !useAWTRenderThread ) { + animator.setModeBits(false, Animator.MODE_EXPECT_AWT_RENDERING_THREAD); + } + final GLAutoDrawable[] drawables = new GLAutoDrawable[drawableCount]; + for(int i=0; i<drawableCount; i++) { + final int x = ( i % num_x ) * ( demoSize + insets.getTotalHeight() ) + insets.getLeftWidth(); + final int y = ( (i / num_x) % num_y ) * ( demoSize + insets.getTotalHeight() ) + insets.getTopHeight(); + + drawables[i] = createGLAutoDrawable("Win #"+i, x, y, demoSize, demoSize, caps); + Assert.assertNotNull(drawables[i]); + final GearsES2 demo = new GearsES2(swapInterval); + demo.setVerbose(false); + drawables[i].addGLEventListener(demo); + } + + if( preAdd ) { + for(int i=0; i<drawableCount; i++) { + animator.add(drawables[i]); + } + if( exclusive ) { + if( useAWTRenderThread ) { + Assert.assertEquals(null, animator.setExclusiveContext(awtRenderThread)); + } else { + Assert.assertEquals(false, animator.setExclusiveContext(true)); + } + } + } + Assert.assertFalse(animator.isAnimating()); + Assert.assertFalse(animator.isStarted()); + + // Animator Start + Assert.assertTrue(animator.start()); + + Assert.assertTrue(animator.isStarted()); + if( preAdd ) { + Assert.assertTrue(animator.isAnimating()); + } else { + Assert.assertFalse(animator.isAnimating()); + if( exclusive ) { + if( useAWTRenderThread ) { + Assert.assertEquals(null, animator.setExclusiveContext(awtRenderThread)); + } else { + Assert.assertEquals(false, animator.setExclusiveContext(true)); + } + } + for(int i=0; i<drawableCount; i++) { + animator.add(drawables[i]); + } + Assert.assertTrue(animator.isAnimating()); + } + Assert.assertEquals(exclusive, animator.isExclusiveContextEnabled()); + + // After start, ExclusiveContextThread is set + { + final Thread ect = animator.getExclusiveContextThread(); + if(exclusive) { + if( useAWTRenderThread ) { + Assert.assertEquals(awtRenderThread, ect); + } else { + Assert.assertEquals(animator.getThread(), ect); + } + } else { + Assert.assertEquals(null, ect); + } + for(int i=0; i<drawableCount; i++) { + Assert.assertEquals(ect, drawables[i].getExclusiveContextThread()); + } + setGLAutoDrawableVisible(drawables); + } + animator.setUpdateFPSFrames(showFPSRate, showFPS ? System.err : null); + + // Normal run .. + Thread.sleep(duration/durationParts); // 1 + + if( !shortenTest ) { + // Disable/Enable exclusive mode manually for all GLAutoDrawable + if(exclusive) { + final Thread ect = animator.getExclusiveContextThread(); + if( useAWTRenderThread ) { + Assert.assertEquals(awtRenderThread, ect); + } else { + Assert.assertEquals(animator.getThread(), ect); + } + for(int i=0; i<drawableCount; i++) { + final Thread t = drawables[i].setExclusiveContextThread(null); + Assert.assertEquals(ect, t); + } + + Thread.sleep(duration/durationParts); // 2 + + for(int i=0; i<drawableCount; i++) { + // poll until clearing drawable ECT is established + { + boolean ok = null == drawables[i].getExclusiveContextThread(); + int c = 0; + while(!ok && c<5*50) { // 5*50*20 = 5s TO + Thread.sleep(20); + ok = null == drawables[i].getExclusiveContextThread(); + c++; + } + if(c>0) { + System.err.println("Clearing drawable ECT was done 'later' @ "+(c*20)+"ms, ok "+ok); + } + Assert.assertEquals(true, ok); + } + final Thread t = drawables[i].setExclusiveContextThread(ect); + Assert.assertEquals(null, t); + } + + Thread.sleep(duration/durationParts); // 3 + } + + // Disable/Enable exclusive mode via Animator for all GLAutoDrawable + if(exclusive) { + final Thread ect = animator.getExclusiveContextThread(); + if( useAWTRenderThread ) { + Assert.assertEquals(awtRenderThread, ect); + } else { + Assert.assertEquals(animator.getThread(), ect); + } + + Assert.assertEquals(true, animator.setExclusiveContext(false)); + Assert.assertFalse(animator.isExclusiveContextEnabled()); + for(int i=0; i<drawableCount; i++) { + Assert.assertEquals(null, drawables[i].getExclusiveContextThread()); + } + + Thread.sleep(duration/durationParts); // 4 + + Assert.assertEquals(null, animator.setExclusiveContext(ect)); + Assert.assertTrue(animator.isExclusiveContextEnabled()); + Assert.assertEquals(ect, animator.getExclusiveContextThread()); + for(int i=0; i<drawableCount; i++) { + Assert.assertEquals(ect, drawables[i].getExclusiveContextThread()); + } + + Thread.sleep(duration/durationParts); // 5 + } + + Assert.assertEquals(exclusive, animator.isExclusiveContextEnabled()); + Assert.assertTrue(animator.isStarted()); + Assert.assertTrue(animator.isAnimating()); + Assert.assertFalse(animator.isPaused()); + + // Animator Pause + Assert.assertTrue(animator.pause()); + Assert.assertTrue(animator.isStarted()); + Assert.assertFalse(animator.isAnimating()); + Assert.assertTrue(animator.isPaused()); + Assert.assertEquals(exclusive, animator.isExclusiveContextEnabled()); + if(exclusive) { + final Thread ect = animator.getExclusiveContextThread(); + if( useAWTRenderThread ) { + Assert.assertEquals(awtRenderThread, ect); + } else { + Assert.assertEquals(animator.getThread(), ect); + } + } else { + Assert.assertEquals(null, animator.getExclusiveContextThread()); + } + for(int i=0; i<drawableCount; i++) { + Assert.assertEquals(null, drawables[i].getExclusiveContextThread()); + } + Thread.sleep(duration/durationParts); // 6 + + // Animator Resume + Assert.assertTrue(animator.resume()); + Assert.assertTrue(animator.isStarted()); + Assert.assertTrue(animator.isAnimating()); + Assert.assertFalse(animator.isPaused()); + Assert.assertEquals(exclusive, animator.isExclusiveContextEnabled()); + if(exclusive) { + final Thread ect = animator.getExclusiveContextThread(); + if( useAWTRenderThread ) { + Assert.assertEquals(awtRenderThread, ect); + } else { + Assert.assertEquals(animator.getThread(), ect); + } + for(int i=0; i<drawableCount; i++) { + Assert.assertEquals(ect, drawables[i].getExclusiveContextThread()); + } + } else { + Assert.assertEquals(null, animator.getExclusiveContextThread()); + for(int i=0; i<drawableCount; i++) { + Assert.assertEquals(null, drawables[i].getExclusiveContextThread()); + } + } + Thread.sleep(duration/durationParts); // 7 + + // Animator Stop #1 + Assert.assertTrue(animator.stop()); + Assert.assertFalse(animator.isAnimating()); + Assert.assertFalse(animator.isStarted()); + Assert.assertFalse(animator.isPaused()); + Assert.assertEquals(exclusive, animator.isExclusiveContextEnabled()); + Assert.assertEquals(null, animator.getExclusiveContextThread()); + for(int i=0; i<drawableCount; i++) { + Assert.assertEquals(null, drawables[i].getExclusiveContextThread()); + } + Thread.sleep(duration/durationParts); // 8 + + // Animator Re-Start + Assert.assertTrue(animator.start()); + Assert.assertTrue(animator.isStarted()); + Assert.assertTrue(animator.isAnimating()); + Assert.assertEquals(exclusive, animator.isExclusiveContextEnabled()); + // After start, ExclusiveContextThread is set + { + final Thread ect = animator.getExclusiveContextThread(); + if(exclusive) { + if( useAWTRenderThread ) { + Assert.assertEquals(awtRenderThread, ect); + } else { + Assert.assertEquals(animator.getThread(), ect); + } + } else { + Assert.assertEquals(null, ect); + } + for(int i=0; i<drawableCount; i++) { + Assert.assertEquals(ect, drawables[i].getExclusiveContextThread()); + } + } + Thread.sleep(duration/durationParts); // 9 + + // Remove all drawables .. while running! + for(int i=0; i<drawableCount; i++) { + final GLAutoDrawable drawable = drawables[i]; + animator.remove(drawable); + Assert.assertEquals(null, drawable.getExclusiveContextThread()); + } + Assert.assertTrue(animator.isStarted()); + Assert.assertFalse(animator.isAnimating()); // no drawables in list! + } // !shortenTest + + // Animator Stop #2 + Assert.assertTrue(animator.stop()); + Assert.assertFalse(animator.isAnimating()); + Assert.assertFalse(animator.isStarted()); + Assert.assertFalse(animator.isPaused()); + Assert.assertEquals(exclusive, animator.isExclusiveContextEnabled()); + Assert.assertEquals(null, animator.getExclusiveContextThread()); + + // Destroy GLWindows + for(int i=0; i<drawableCount; i++) { + destroyGLAutoDrawableVisible(drawables[i]); + Assert.assertEquals(true, AWTRobotUtil.waitForRealized(drawables[i], false)); + } + } + + @Test + public void test01NormalPre_1Win() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities( glp ); + runTestGL(caps, 1 /* numWin */, false /* exclusive */, true /* preAdd */, false /* short */); + } + + @Test + public void test02NormalPost_1Win() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities( glp ); + runTestGL(caps, 1 /* numWin */, false /* exclusive */, false /* preAdd */, true /* short */); + } + + @Test + public void test03ExclPre_1Win() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities( glp ); + runTestGL(caps, 1 /* numWin */, true /* exclusive */, true /* preAdd */, false /* short */); + } + + @Test + public void test04ExclPost_1Win() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities( glp ); + runTestGL(caps, 1 /* numWin */, true /* exclusive */, false /* preAdd */, true /* short */); + } + + @Test + public void test05NormalPre_4Win() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities( glp ); + runTestGL(caps, 4 /* numWin */, false /* exclusive */, true /* preAdd */, false /* short */); + } + + @Test + public void test06NormalPost_4Win() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities( glp ); + runTestGL(caps, 4 /* numWin */, false /* exclusive */, false /* preAdd */, true /* short */); + } + + @Test + public void test07ExclPre_4Win() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities( glp ); + runTestGL(caps, 4 /* numWin */, true /* exclusive */, true /* preAdd */, false /* short */); + } + + @Test + public void test08ExclPost_4Win() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities( glp ); + runTestGL(caps, 4 /* numWin */, true /* exclusive */, false /* preAdd */, true /* short */); + } + +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase00AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase00AWT.java new file mode 100644 index 000000000..310f59f07 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase00AWT.java @@ -0,0 +1,161 @@ +/** + * Copyright 2013 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.opengl.test.junit.jogl.acore; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; + +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.awt.GLCanvas; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.AfterClass; + +import com.jogamp.common.os.Platform; +import com.jogamp.common.util.VersionNumber; + +/** + * ExclusiveContextThread base implementation to test correctness of the ExclusiveContext feature _and_ AnimatorBase with AWT. + */ +public abstract class ExclusiveContextBase00AWT extends ExclusiveContextBase00 { + + static Thread awtEDT; + static boolean osxCALayerAWTModBug; + + @BeforeClass + public static void initClass00AWT() { + + final VersionNumber version170 = new VersionNumber(1, 7, 0); + osxCALayerAWTModBug = Platform.OSType.MACOS == Platform.getOSType() && + 0 > Platform.getJavaVersionNumber().compareTo(version170); + System.err.println("OSX CALayer AWT-Mod Bug "+osxCALayerAWTModBug); + System.err.println("OSType "+Platform.getOSType()); + System.err.println("Java Version "+Platform.getJavaVersionNumber()); + + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + awtEDT = Thread.currentThread(); + } } ); + } catch (Exception e) { + e.printStackTrace(); + Assert.assertNull(e); + } + + } + + @AfterClass + public static void releaseClass00AWT() { + } + + @Override + protected boolean isAWTTestCase() { return true; } + + @Override + protected Thread getAWTRenderThread() { + return awtEDT; + } + + @Override + protected GLAutoDrawable createGLAutoDrawable(final String title, final int x, final int y, final int width, final int height, GLCapabilitiesImmutable caps) { + final GLCanvas glCanvas = new GLCanvas(); + + // FIXME: Below AWT layouts freezes OSX/Java7 @ setVisible: Window.setVisible .. [email protected] + // final Dimension sz = new Dimension(width, height); + // glCanvas.setMinimumSize(sz); + // glCanvas.setPreferredSize(sz); + // glCanvas.setSize(sz); + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + final Frame frame = new Frame(); + frame.setLayout(new BorderLayout()); + frame.setMinimumSize(new Dimension(width, height)); + frame.setBounds(x, y, width, height); + frame.add(glCanvas, BorderLayout.CENTER); + // frame.pack(); + frame.validate(); + if( !osxCALayerAWTModBug ) { + frame.setTitle(title); + } + } }); + } catch (Exception e) { + e.printStackTrace(); + Assert.assertNull(e); + } + + return glCanvas; + } + + protected Frame getFrame(GLAutoDrawable glad) { + Container p = ((Component)glad).getParent(); + while( null != p && !( p instanceof Frame ) ) { + p = p.getParent(); + } + return (Frame)p; + } + + @Override + protected void setGLAutoDrawableVisible(final GLAutoDrawable[] glads) { + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + final int count = glads.length; + for(int i=0; i<count; i++) { + final GLAutoDrawable glad = glads[i]; + final Frame frame = getFrame(glad); + frame.setVisible(true); + } + } } ); + } catch (Exception e) { + e.printStackTrace(); + Assert.assertNull(e); + } + } + + @Override + protected void destroyGLAutoDrawableVisible(GLAutoDrawable glad) { + final Frame frame = getFrame(glad); + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + frame.dispose(); + } } ); + } catch (Exception e) { + e.printStackTrace(); + Assert.assertNull(e); + } + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase00NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase00NEWT.java new file mode 100644 index 000000000..40a79f484 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase00NEWT.java @@ -0,0 +1,94 @@ +/** + * Copyright 2013 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.opengl.test.junit.jogl.acore; + +import com.jogamp.newt.Display; +import com.jogamp.newt.NewtFactory; +import com.jogamp.newt.Screen; +import com.jogamp.newt.opengl.GLWindow; + +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilitiesImmutable; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.AfterClass; + +/** + * ExclusiveContextThread base implementation to test correctness of the ExclusiveContext feature _and_ AnimatorBase with NEWT. + */ +public abstract class ExclusiveContextBase00NEWT extends ExclusiveContextBase00 { + + static Display dpy; + static Screen screen; + + @BeforeClass + public static void initClass00NEWT() { + dpy = NewtFactory.createDisplay(null); + screen = NewtFactory.createScreen(dpy, 0); + } + + @AfterClass + public static void releaseClass00NEWT() { + screen = null; + dpy = null; + } + + @Override + protected boolean isAWTTestCase() { return false; } + + @Override + protected Thread getAWTRenderThread() { + return null; + } + + @Override + protected GLAutoDrawable createGLAutoDrawable(String title, int x, int y, int width, int height, GLCapabilitiesImmutable caps) { + GLWindow glWindow = GLWindow.create(screen, caps); + Assert.assertNotNull(glWindow); + glWindow.setTitle(title); + glWindow.setSize(width, height); + glWindow.setPosition(x, y); + return glWindow; + } + + @Override + protected void setGLAutoDrawableVisible(GLAutoDrawable[] glads) { + final int count = glads.length; + for(int i=0; i<count; i++) { + final GLAutoDrawable glad = glads[i]; + ((GLWindow)glad).setVisible(true); + } + } + + @Override + protected void destroyGLAutoDrawableVisible(GLAutoDrawable glad) { + ((GLWindow)glad).destroy(); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase10.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase10.java new file mode 100644 index 000000000..4bad6c84f --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase10.java @@ -0,0 +1,213 @@ +/** + * Copyright 2013 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.opengl.test.junit.jogl.acore; + +import com.jogamp.newt.NewtFactory; +import com.jogamp.newt.Window; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; +import com.jogamp.opengl.test.junit.util.UITestCase; + +import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.AnimatorBase; + +import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; + +import javax.media.nativewindow.Capabilities; +import javax.media.nativewindow.util.InsetsImmutable; + +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLProfile; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.AfterClass; +import org.junit.Test; + +/** + * ExclusiveContextThread base implementation to test performance impact of the ExclusiveContext feature with AnimatorBase. + */ +public abstract class ExclusiveContextBase10 extends UITestCase { + static boolean testExclusiveWithAWT = false; + static long duration = 1400; + + static boolean showFPS = true; + static int showFPSRate = 60; + + static final int demoSize = 128; + + static InsetsImmutable insets = null; + static int scrnHeight, scrnWidth; + static int num_x, num_y; + + static int swapInterval = 0; + + @BeforeClass + public static void initClass00() { + Window dummyWindow = NewtFactory.createWindow(new Capabilities()); + dummyWindow.setSize(demoSize, demoSize); + dummyWindow.setVisible(true); + Assert.assertEquals(true, dummyWindow.isVisible()); + Assert.assertEquals(true, dummyWindow.isNativeValid()); + insets = dummyWindow.getInsets(); + scrnHeight = dummyWindow.getScreen().getHeight(); + scrnWidth = dummyWindow.getScreen().getWidth(); + num_x = scrnWidth / ( demoSize + insets.getTotalWidth() ) - 2; + num_y = scrnHeight / ( demoSize + insets.getTotalHeight() ) - 2; + dummyWindow.destroy(); + } + + @AfterClass + public static void releaseClass00() { + } + + protected abstract boolean isAWTTestCase(); + protected abstract Thread getAWTRenderThread(); + protected abstract AnimatorBase createAnimator(); + protected abstract GLAutoDrawable createGLAutoDrawable(String title, int x, int y, int width, int height, GLCapabilitiesImmutable caps); + protected abstract void setGLAutoDrawableVisible(GLAutoDrawable[] glads); + protected abstract void destroyGLAutoDrawableVisible(GLAutoDrawable glad); + + protected void runTestGL(GLCapabilitiesImmutable caps, int drawableCount, boolean exclusive) throws InterruptedException { + final boolean useAWTRenderThread = isAWTTestCase(); + if( useAWTRenderThread && exclusive ) { + if( testExclusiveWithAWT ) { + System.err.println("Warning: Testing AWT + Exclusive -> Not advised!"); + } else { + System.err.println("Info: Skip test: AWT + Exclusive!"); + return; + } + } + if( useAWTRenderThread && exclusive && !testExclusiveWithAWT) { + System.err.println("Skip test: AWT + Exclusive -> Not advised!"); + return; + } + final Thread awtRenderThread = getAWTRenderThread(); + final AnimatorBase animator = createAnimator(); + if( !useAWTRenderThread ) { + animator.setModeBits(false, Animator.MODE_EXPECT_AWT_RENDERING_THREAD); + } + final GLAutoDrawable[] drawables = new GLAutoDrawable[drawableCount]; + for(int i=0; i<drawableCount; i++) { + final int x = ( i % num_x ) * ( demoSize + insets.getTotalHeight() ) + insets.getLeftWidth(); + final int y = ( (i / num_x) % num_y ) * ( demoSize + insets.getTotalHeight() ) + insets.getTopHeight(); + + drawables[i] = createGLAutoDrawable("Win #"+i, x, y, demoSize, demoSize, caps); + Assert.assertNotNull(drawables[i]); + final GearsES2 demo = new GearsES2(swapInterval); + demo.setVerbose(false); + drawables[i].addGLEventListener(demo); + } + + for(int i=0; i<drawableCount; i++) { + animator.add(drawables[i]); + } + if( exclusive ) { + if( useAWTRenderThread ) { + Assert.assertEquals(null, animator.setExclusiveContext(awtRenderThread)); + } else { + Assert.assertEquals(false, animator.setExclusiveContext(true)); + } + } + Assert.assertFalse(animator.isAnimating()); + Assert.assertFalse(animator.isStarted()); + + // Animator Start + Assert.assertTrue(animator.start()); + + Assert.assertTrue(animator.isStarted()); + Assert.assertTrue(animator.isAnimating()); + Assert.assertEquals(exclusive, animator.isExclusiveContextEnabled()); + + // After start, ExclusiveContextThread is set + { + final Thread ect = animator.getExclusiveContextThread(); + if(exclusive) { + if( useAWTRenderThread ) { + Assert.assertEquals(awtRenderThread, ect); + } else { + Assert.assertEquals(animator.getThread(), ect); + } + } else { + Assert.assertEquals(null, ect); + } + for(int i=0; i<drawableCount; i++) { + Assert.assertEquals(ect, drawables[i].getExclusiveContextThread()); + } + setGLAutoDrawableVisible(drawables); + } + animator.setUpdateFPSFrames(showFPSRate, showFPS ? System.err : null); + + // Normal run .. + Thread.sleep(duration); + + // Animator Stop #2 + Assert.assertTrue(animator.stop()); + Assert.assertFalse(animator.isAnimating()); + Assert.assertFalse(animator.isStarted()); + Assert.assertFalse(animator.isPaused()); + Assert.assertEquals(exclusive, animator.isExclusiveContextEnabled()); + Assert.assertEquals(null, animator.getExclusiveContextThread()); + + // Destroy GLWindows + for(int i=0; i<drawableCount; i++) { + destroyGLAutoDrawableVisible(drawables[i]); + Assert.assertEquals(true, AWTRobotUtil.waitForRealized(drawables[i], false)); + } + } + + @Test + public void test01Normal_1Win() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities( glp ); + runTestGL(caps, 1 /* numWin */, false /* exclusive */); + } + + @Test + public void test03Excl_1Win() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities( glp ); + runTestGL(caps, 1 /* numWin */, true /* exclusive */); + } + + @Test + public void test05Normal_4Win() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities( glp ); + runTestGL(caps, 4 /* numWin */, false /* exclusive */); + } + + @Test + public void test07Excl_4Win() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities( glp ); + runTestGL(caps, 4 /* numWin */, true /* exclusive */); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase10AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase10AWT.java new file mode 100644 index 000000000..5c4e9fd32 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase10AWT.java @@ -0,0 +1,161 @@ +/** + * Copyright 2013 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.opengl.test.junit.jogl.acore; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; + +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.awt.GLCanvas; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.AfterClass; + +import com.jogamp.common.os.Platform; +import com.jogamp.common.util.VersionNumber; + +/** + * ExclusiveContextThread base implementation to test performance impact of the ExclusiveContext feature with AnimatorBase and AWT. + */ +public abstract class ExclusiveContextBase10AWT extends ExclusiveContextBase10 { + + static Thread awtEDT; + static boolean osxCALayerAWTModBug; + + @BeforeClass + public static void initClass00AWT() { + + final VersionNumber version170 = new VersionNumber(1, 7, 0); + osxCALayerAWTModBug = Platform.OSType.MACOS == Platform.getOSType() && + 0 > Platform.getJavaVersionNumber().compareTo(version170); + System.err.println("OSX CALayer AWT-Mod Bug "+osxCALayerAWTModBug); + System.err.println("OSType "+Platform.getOSType()); + System.err.println("Java Version "+Platform.getJavaVersionNumber()); + + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + awtEDT = Thread.currentThread(); + } } ); + } catch (Exception e) { + e.printStackTrace(); + Assert.assertNull(e); + } + + } + + @AfterClass + public static void releaseClass00AWT() { + } + + @Override + protected boolean isAWTTestCase() { return true; } + + @Override + protected Thread getAWTRenderThread() { + return awtEDT; + } + + @Override + protected GLAutoDrawable createGLAutoDrawable(final String title, final int x, final int y, final int width, final int height, GLCapabilitiesImmutable caps) { + final GLCanvas glCanvas = new GLCanvas(); + + // FIXME: Below AWT layouts freezes OSX/Java7 @ setVisible: Window.setVisible .. [email protected] + // final Dimension sz = new Dimension(width, height); + // glCanvas.setMinimumSize(sz); + // glCanvas.setPreferredSize(sz); + // glCanvas.setSize(sz); + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + final Frame frame = new Frame(); + frame.setLayout(new BorderLayout()); + frame.setMinimumSize(new Dimension(width, height)); + frame.setBounds(x, y, width, height); + frame.add(glCanvas, BorderLayout.CENTER); + // frame.pack(); + frame.validate(); + if( !osxCALayerAWTModBug ) { + frame.setTitle(title); + } + } }); + } catch (Exception e) { + e.printStackTrace(); + Assert.assertNull(e); + } + + return glCanvas; + } + + protected Frame getFrame(GLAutoDrawable glad) { + Container p = ((Component)glad).getParent(); + while( null != p && !( p instanceof Frame ) ) { + p = p.getParent(); + } + return (Frame)p; + } + + @Override + protected void setGLAutoDrawableVisible(final GLAutoDrawable[] glads) { + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + final int count = glads.length; + for(int i=0; i<count; i++) { + final GLAutoDrawable glad = glads[i]; + final Frame frame = getFrame(glad); + frame.setVisible(true); + } + } } ); + } catch (Exception e) { + e.printStackTrace(); + Assert.assertNull(e); + } + } + + @Override + protected void destroyGLAutoDrawableVisible(GLAutoDrawable glad) { + final Frame frame = getFrame(glad); + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + frame.dispose(); + } } ); + } catch (Exception e) { + e.printStackTrace(); + Assert.assertNull(e); + } + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase10NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase10NEWT.java new file mode 100644 index 000000000..ba95b597d --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/ExclusiveContextBase10NEWT.java @@ -0,0 +1,94 @@ +/** + * Copyright 2013 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.opengl.test.junit.jogl.acore; + +import com.jogamp.newt.Display; +import com.jogamp.newt.NewtFactory; +import com.jogamp.newt.Screen; +import com.jogamp.newt.opengl.GLWindow; + +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilitiesImmutable; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.AfterClass; + +/** + * ExclusiveContextThread base implementation to test performance impact of the ExclusiveContext feature with AnimatorBase and NEWT. + */ +public abstract class ExclusiveContextBase10NEWT extends ExclusiveContextBase10 { + + static Display dpy; + static Screen screen; + + @BeforeClass + public static void initClass00NEWT() { + dpy = NewtFactory.createDisplay(null); + screen = NewtFactory.createScreen(dpy, 0); + } + + @AfterClass + public static void releaseClass00NEWT() { + screen = null; + dpy = null; + } + + @Override + protected boolean isAWTTestCase() { return false; } + + @Override + protected Thread getAWTRenderThread() { + return null; + } + + @Override + protected GLAutoDrawable createGLAutoDrawable(String title, int x, int y, int width, int height, GLCapabilitiesImmutable caps) { + GLWindow glWindow = GLWindow.create(screen, caps); + Assert.assertNotNull(glWindow); + glWindow.setTitle(title); + glWindow.setSize(width, height); + glWindow.setPosition(x, y); + return glWindow; + } + + @Override + protected void setGLAutoDrawableVisible(GLAutoDrawable[] glads) { + final int count = glads.length; + for(int i=0; i<count; i++) { + final GLAutoDrawable glad = glads[i]; + ((GLWindow)glad).setVisible(true); + } + } + + @Override + protected void destroyGLAutoDrawableVisible(GLAutoDrawable glad) { + ((GLWindow)glad).destroy(); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java index 6b2de8366..f8e6ee5d3 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java @@ -53,7 +53,7 @@ import com.jogamp.opengl.util.Animator; * Rendering is always lock-free and independent of the EDT. * </p> */ -public class InitConcurrentBaseNEWT extends UITestCase { +public abstract class InitConcurrentBaseNEWT extends UITestCase { static final int demoSize = 128; diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext01VSyncAnimAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext01VSyncAnimAWT.java new file mode 100644 index 000000000..245d42031 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext01VSyncAnimAWT.java @@ -0,0 +1,70 @@ +/** + * Copyright 2013 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.opengl.test.junit.jogl.acore; + +import java.io.IOException; + +import com.jogamp.opengl.test.junit.util.MiscUtils; + +import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.AnimatorBase; + +/** + * ExclusiveContextThread VSync Animator to test correctness of the ExclusiveContext feature _and_ Animator with AWT. + */ +public class TestExclusiveContext01VSyncAnimAWT extends ExclusiveContextBase00AWT { + + @Override + protected AnimatorBase createAnimator() { + return new Animator(); + } + + public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + i++; + duration = MiscUtils.atol(args[i], duration); + } else if(args[i].equals("-vsync")) { + i++; + swapInterval = MiscUtils.atoi(args[i], swapInterval); + } else if(args[i].equals("-showFPS")) { + i++; + showFPS = MiscUtils.atoi(args[i], showFPS ? 1 : 0) == 0 ? false : true ; + } else if(args[i].equals("-forceExclusiveTest")) { + testExclusiveWithAWT = true; + } + } + System.err.println("duration "+duration); + System.err.println("showFPS "+showFPS); + System.err.println("swapInterval "+swapInterval); + System.err.println("testExclusiveWithAWT "+testExclusiveWithAWT); + + org.junit.runner.JUnitCore.main(TestExclusiveContext01VSyncAnimAWT.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext01VSyncAnimNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext01VSyncAnimNEWT.java new file mode 100644 index 000000000..2cc423332 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext01VSyncAnimNEWT.java @@ -0,0 +1,67 @@ +/** + * Copyright 2013 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.opengl.test.junit.jogl.acore; + +import java.io.IOException; + +import com.jogamp.opengl.test.junit.util.MiscUtils; +import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.AnimatorBase; + + +/** + * ExclusiveContextThread VSync Animator to test correctness of the ExclusiveContext feature _and_ Animator with NEWT. + */ +public class TestExclusiveContext01VSyncAnimNEWT extends ExclusiveContextBase00NEWT { + + @Override + protected AnimatorBase createAnimator() { + return new Animator(); + } + + public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + i++; + duration = MiscUtils.atol(args[i], duration); + } else if(args[i].equals("-vsync")) { + i++; + swapInterval = MiscUtils.atoi(args[i], swapInterval); + } else if(args[i].equals("-showFPS")) { + i++; + showFPS = MiscUtils.atoi(args[i], showFPS ? 1 : 0) == 0 ? false : true ; + } + } + System.err.println("duration "+duration); + System.err.println("showFPS "+showFPS); + System.err.println("swapInterval "+swapInterval); + + org.junit.runner.JUnitCore.main(TestExclusiveContext01VSyncAnimNEWT.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext02FPSAnimAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext02FPSAnimAWT.java new file mode 100644 index 000000000..5e8e1ba07 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext02FPSAnimAWT.java @@ -0,0 +1,70 @@ +/** + * Copyright 2013 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.opengl.test.junit.jogl.acore; + +import java.io.IOException; + +import com.jogamp.opengl.test.junit.util.MiscUtils; +import com.jogamp.opengl.util.AnimatorBase; +import com.jogamp.opengl.util.FPSAnimator; + + +/** + * ExclusiveContextThread FPS Animator to test correctness of the ExclusiveContext feature _and_ FPSAnimator with AWT. + */ +public class TestExclusiveContext02FPSAnimAWT extends ExclusiveContextBase00AWT { + + @Override + protected AnimatorBase createAnimator() { + return new FPSAnimator(0); + } + + public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + i++; + duration = MiscUtils.atol(args[i], duration); + } else if(args[i].equals("-vsync")) { + i++; + swapInterval = MiscUtils.atoi(args[i], swapInterval); + } else if(args[i].equals("-showFPS")) { + i++; + showFPS = MiscUtils.atoi(args[i], showFPS ? 1 : 0) == 0 ? false : true ; + } else if(args[i].equals("-forceExclusiveTest")) { + testExclusiveWithAWT = true; + } + } + System.err.println("duration "+duration); + System.err.println("showFPS "+showFPS); + System.err.println("swapInterval "+swapInterval); + System.err.println("testExclusiveWithAWT "+testExclusiveWithAWT); + + org.junit.runner.JUnitCore.main(TestExclusiveContext02FPSAnimAWT.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext02FPSAnimNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext02FPSAnimNEWT.java new file mode 100644 index 000000000..26fb7814e --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext02FPSAnimNEWT.java @@ -0,0 +1,67 @@ +/** + * Copyright 2013 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.opengl.test.junit.jogl.acore; + +import java.io.IOException; + +import com.jogamp.opengl.test.junit.util.MiscUtils; +import com.jogamp.opengl.util.AnimatorBase; +import com.jogamp.opengl.util.FPSAnimator; + + +/** + * ExclusiveContextThread FPS Animator to test correctness of the ExclusiveContext feature _and_ FPSAnimator with NEWT. + */ +public class TestExclusiveContext02FPSAnimNEWT extends ExclusiveContextBase00NEWT { + + @Override + protected AnimatorBase createAnimator() { + return new FPSAnimator(0); + } + + public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + i++; + duration = MiscUtils.atol(args[i], duration); + } else if(args[i].equals("-vsync")) { + i++; + swapInterval = MiscUtils.atoi(args[i], swapInterval); + } else if(args[i].equals("-showFPS")) { + i++; + showFPS = MiscUtils.atoi(args[i], showFPS ? 1 : 0) == 0 ? false : true ; + } + } + System.err.println("duration "+duration); + System.err.println("showFPS "+showFPS); + System.err.println("swapInterval "+swapInterval); + + org.junit.runner.JUnitCore.main(TestExclusiveContext02FPSAnimNEWT.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext11VSyncAnimNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext11VSyncAnimNEWT.java new file mode 100644 index 000000000..3a7a130ea --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext11VSyncAnimNEWT.java @@ -0,0 +1,66 @@ +/** + * Copyright 2013 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.opengl.test.junit.jogl.acore; + +import java.io.IOException; + +import com.jogamp.opengl.test.junit.util.MiscUtils; +import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.AnimatorBase; + +/** + * ExclusiveContextThread base implementation to test performance impact of the ExclusiveContext feature with Animator and NEWT. + */ +public class TestExclusiveContext11VSyncAnimNEWT extends ExclusiveContextBase10NEWT { + + @Override + protected AnimatorBase createAnimator() { + return new Animator(); + } + + public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + i++; + duration = MiscUtils.atol(args[i], duration); + } else if(args[i].equals("-vsync")) { + i++; + swapInterval = MiscUtils.atoi(args[i], swapInterval); + } else if(args[i].equals("-showFPS")) { + i++; + showFPS = MiscUtils.atoi(args[i], showFPS ? 1 : 0) == 0 ? false : true ; + } + } + System.err.println("duration "+duration); + System.err.println("showFPS "+showFPS); + System.err.println("swapInterval "+swapInterval); + + org.junit.runner.JUnitCore.main(TestExclusiveContext11VSyncAnimNEWT.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext12FPSAnimNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext12FPSAnimNEWT.java new file mode 100644 index 000000000..3f99e3fb7 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestExclusiveContext12FPSAnimNEWT.java @@ -0,0 +1,67 @@ +/** + * Copyright 2013 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.opengl.test.junit.jogl.acore; + +import java.io.IOException; + +import com.jogamp.opengl.test.junit.util.MiscUtils; +import com.jogamp.opengl.util.AnimatorBase; +import com.jogamp.opengl.util.FPSAnimator; + + +/** + * ExclusiveContextThread base implementation to test performance impact of the ExclusiveContext feature with FPSAnimator and NEWT. + */ +public class TestExclusiveContext12FPSAnimNEWT extends ExclusiveContextBase10NEWT { + + @Override + protected AnimatorBase createAnimator() { + return new FPSAnimator(0); + } + + public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + i++; + duration = MiscUtils.atol(args[i], duration); + } else if(args[i].equals("-vsync")) { + i++; + swapInterval = MiscUtils.atoi(args[i], swapInterval); + } else if(args[i].equals("-showFPS")) { + i++; + showFPS = MiscUtils.atoi(args[i], showFPS ? 1 : 0) == 0 ? false : true ; + } + } + System.err.println("duration "+duration); + System.err.println("showFPS "+showFPS); + System.err.println("swapInterval "+swapInterval); + + org.junit.runner.JUnitCore.main(TestExclusiveContext12FPSAnimNEWT.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java index 9e0bbae71..05cc2aeb0 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java @@ -31,6 +31,7 @@ package com.jogamp.opengl.test.junit.jogl.demos.es1.newt; import com.jogamp.newt.event.KeyAdapter; import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.test.junit.util.MiscUtils; import com.jogamp.opengl.test.junit.util.UITestCase; import com.jogamp.opengl.test.junit.util.QuitAdapter; @@ -50,6 +51,7 @@ public class TestGearsES1NEWT extends UITestCase { static int width, height; static boolean forceES2 = false; static boolean forceFFPEmu = false; + static int swapInterval = 1; @BeforeClass public static void initClass() { @@ -66,7 +68,7 @@ public class TestGearsES1NEWT extends UITestCase { Assert.assertNotNull(glWindow); glWindow.setTitle("Gears NEWT Test"); - final GearsES1 demo = new GearsES1(); + final GearsES1 demo = new GearsES1(swapInterval); demo.setForceFFPEmu(forceFFPEmu, forceFFPEmu, false, false); glWindow.addGLEventListener(demo); final SnapshotGLEventListener snap = new SnapshotGLEventListener(); @@ -117,7 +119,7 @@ public class TestGearsES1NEWT extends UITestCase { runTestGL(caps, forceFFPEmu); } - static long duration = 1000; // ms + static long duration = 500; // ms public static void main(String args[]) { for(int i=0; i<args.length; i++) { @@ -126,6 +128,9 @@ public class TestGearsES1NEWT extends UITestCase { try { duration = Integer.parseInt(args[i]); } catch (Exception ex) { ex.printStackTrace(); } + } else if(args[i].equals("-vsync")) { + i++; + swapInterval = MiscUtils.atoi(args[i], swapInterval); } else if(args[i].equals("-es2")) { forceES2 = true; } else if(args[i].equals("-ffpemu")) { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java index 21c9f3535..cc5aae99e 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java @@ -65,7 +65,9 @@ public class GearsES2 implements GLEventListener { private int prevMouseX, prevMouseY; private boolean doRotate = true; - boolean ignoreFocus = false; + private boolean ignoreFocus = false; + private boolean clearBuffers = true; + private boolean verbose = true; public GearsES2(int swapInterval) { this.swapInterval = swapInterval; @@ -77,6 +79,8 @@ public class GearsES2 implements GLEventListener { public void setIgnoreFocus(boolean v) { ignoreFocus = v; } public void setDoRotation(boolean rotate) { this.doRotate = rotate; } + public void setClearBuffers(boolean v) { clearBuffers = v; } + public void setVerbose(boolean v) { verbose = v; } public void setPMVUseBackingArray(boolean pmvUseBackingArray) { this.pmvUseBackingArray = pmvUseBackingArray; @@ -108,17 +112,19 @@ public class GearsES2 implements GLEventListener { System.err.println(Thread.currentThread()+" GearsES2.init ..."); GL2ES2 gl = drawable.getGL().getGL2ES2(); - System.err.println("GearsES2 init on "+Thread.currentThread()); - System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities()); - System.err.println("INIT GL IS: " + gl.getClass().getName()); - System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR)); - System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER)); - System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION)); - System.err.println("GL GLSL: "+gl.hasGLSL()+", has-compiler: "+gl.isFunctionAvailable("glCompileShader")+", version "+(gl.hasGLSL() ? gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) : "none")+", "+gl.getContext().getGLSLVersionNumber()); - System.err.println("GL FBO: basic "+ gl.hasBasicFBOSupport()+", full "+gl.hasFullFBOSupport()); - System.err.println("GL Profile: "+gl.getGLProfile()); - System.err.println("GL Renderer Quirks:" + gl.getContext().getRendererQuirks().toString()); - System.err.println("GL:" + gl + ", " + gl.getContext().getGLVersion()); + if(verbose) { + System.err.println("GearsES2 init on "+Thread.currentThread()); + System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities()); + System.err.println("INIT GL IS: " + gl.getClass().getName()); + System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR)); + System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER)); + System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION)); + System.err.println("GL GLSL: "+gl.hasGLSL()+", has-compiler: "+gl.isFunctionAvailable("glCompileShader")+", version "+(gl.hasGLSL() ? gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) : "none")+", "+gl.getContext().getGLSLVersionNumber()); + System.err.println("GL FBO: basic "+ gl.hasBasicFBOSupport()+", full "+gl.hasFullFBOSupport()); + System.err.println("GL Profile: "+gl.getGLProfile()); + System.err.println("GL Renderer Quirks:" + gl.getContext().getRendererQuirks().toString()); + System.err.println("GL:" + gl + ", " + gl.getContext().getGLVersion()); + } gl.glEnable(GL.GL_DEPTH_TEST); @@ -153,26 +159,38 @@ public class GearsES2 implements GLEventListener { if(null == gear1) { gear1 = new GearsObjectES2(st, 1.0f, 4.0f, 1.0f, 20, 0.7f, pmvMatrix, pmvMatrixUniform, colorU); - System.err.println("gear1 created: "+gear1); + if(verbose) { + System.err.println("gear1 created: "+gear1); + } } else { gear1 = new GearsObjectES2(gear1, st, pmvMatrix, pmvMatrixUniform, colorU); - System.err.println("gear1 reused: "+gear1); + if(verbose) { + System.err.println("gear1 reused: "+gear1); + } } if(null == gear2) { gear2 = new GearsObjectES2(st, 0.5f, 2.0f, 2.0f, 10, 0.7f, pmvMatrix, pmvMatrixUniform, colorU); - System.err.println("gear2 created: "+gear2); + if(verbose) { + System.err.println("gear2 created: "+gear2); + } } else { gear2 = new GearsObjectES2(gear2, st, pmvMatrix, pmvMatrixUniform, colorU); - System.err.println("gear2 reused: "+gear2); + if(verbose) { + System.err.println("gear2 reused: "+gear2); + } } if(null == gear3) { gear3 = new GearsObjectES2(st, 1.3f, 2.0f, 0.5f, 10, 0.7f, pmvMatrix, pmvMatrixUniform, colorU); - System.err.println("gear3 created: "+gear3); + if(verbose) { + System.err.println("gear3 created: "+gear3); + } } else { gear3 = new GearsObjectES2(gear3, st, pmvMatrix, pmvMatrixUniform, colorU); - System.err.println("gear3 reused: "+gear3); + if(verbose) { + System.err.println("gear3 reused: "+gear3); + } } final Object upstreamWidget = drawable.getUpstreamWidget(); @@ -264,22 +282,23 @@ public class GearsES2 implements GLEventListener { gl.glEnable(GL.GL_CULL_FACE); - if( ignoreFocus || hasFocus ) { - gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - } else { - gl.glClearColor(0.2f, 0.2f, 0.2f, 0.0f); - } - - // Special handling for the case where the GLJPanel is translucent - // and wants to be composited with other Java 2D content - if (GLProfile.isAWTAvailable() && - (drawable instanceof javax.media.opengl.awt.GLJPanel) && - !((javax.media.opengl.awt.GLJPanel) drawable).isOpaque() && - ((javax.media.opengl.awt.GLJPanel) drawable).shouldPreserveColorBufferIfTranslucent()) { - gl.glClear(GL.GL_DEPTH_BUFFER_BIT); - } else { - gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - } + if( clearBuffers ) { + if( ignoreFocus || hasFocus ) { + gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + } else { + gl.glClearColor(0.2f, 0.2f, 0.2f, 0.0f); + } + // Special handling for the case where the GLJPanel is translucent + // and wants to be composited with other Java 2D content + if (GLProfile.isAWTAvailable() && + (drawable instanceof javax.media.opengl.awt.GLJPanel) && + !((javax.media.opengl.awt.GLJPanel) drawable).isOpaque() && + ((javax.media.opengl.awt.GLJPanel) drawable).shouldPreserveColorBufferIfTranslucent()) { + gl.glClear(GL.GL_DEPTH_BUFFER_BIT); + } else { + gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + } + } st.useProgram(gl, true); pmvMatrix.glPushMatrix(); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java index 6ff3dc3de..9b3fe74cd 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java @@ -39,15 +39,16 @@ import javax.media.opengl.GLEventListener; import javax.media.opengl.GLUniformData; public class RedSquareES2 implements GLEventListener { - ShaderState st; - PMVMatrix pmvMatrix; - GLUniformData pmvMatrixUniform; - GLArrayDataServer vertices ; - GLArrayDataServer colors ; - long t0; + private ShaderState st; + private PMVMatrix pmvMatrix; + private GLUniformData pmvMatrixUniform; + private GLArrayDataServer vertices ; + private GLArrayDataServer colors ; + private long t0; private int swapInterval = 0; - float aspect = 1.0f; - boolean doRotate = true; + private float aspect = 1.0f; + private boolean doRotate = true; + private boolean clearBuffers = true; public RedSquareES2(int swapInterval) { this.swapInterval = swapInterval; @@ -59,6 +60,7 @@ public class RedSquareES2 implements GLEventListener { public void setAspect(float aspect) { this.aspect = aspect; } public void setDoRotation(boolean rotate) { this.doRotate = rotate; } + public void setClearBuffers(boolean v) { clearBuffers = v; } public void init(GLAutoDrawable glad) { System.err.println(Thread.currentThread()+" RedSquareES2.init ..."); @@ -131,8 +133,10 @@ public class RedSquareES2 implements GLEventListener { long t1 = System.currentTimeMillis(); GL2ES2 gl = glad.getGL().getGL2ES2(); - gl.glClearColor(0, 0, 0, 0); - gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + if( clearBuffers ) { + gl.glClearColor(0, 0, 0, 0); + gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + } st.useProgram(gl, true); // One rotation every four seconds pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java index 0a8063297..9f62e4a49 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java @@ -46,6 +46,7 @@ import com.jogamp.opengl.test.junit.util.QuitAdapter; import java.awt.BorderLayout; import java.awt.Dimension; +import java.awt.EventQueue; import java.awt.Frame; import java.awt.TextArea; import java.io.BufferedReader; @@ -71,11 +72,22 @@ public class TestGearsES2AWT extends UITestCase { static boolean shutdownDisposeFrame = true; static boolean shutdownSystemExit = false; static int swapInterval = 1; + static boolean exclusiveContext = false; + static Thread awtEDT; @BeforeClass public static void initClass() { width = 640; height = 480; + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + awtEDT = Thread.currentThread(); + } } ); + } catch (Exception e) { + e.printStackTrace(); + Assert.assertNull(e); + } } @AfterClass @@ -106,6 +118,9 @@ public class TestGearsES2AWT extends UITestCase { glCanvas.addGLEventListener(new GearsES2(swapInterval)); Animator animator = new Animator(glCanvas); + if( exclusiveContext ) { + animator.setExclusiveContext(awtEDT); + } QuitAdapter quitAdapter = new QuitAdapter(); new AWTKeyAdapter(new TraceKeyAdapter(quitAdapter)).addTo(glCanvas); @@ -117,8 +132,11 @@ public class TestGearsES2AWT extends UITestCase { frame.setVisible(true); }}); animator.start(); + Assert.assertTrue(animator.isStarted()); + Assert.assertTrue(animator.isAnimating()); + Assert.assertEquals(exclusiveContext ? awtEDT : null, glCanvas.getExclusiveContextThread()); animator.setUpdateFPSFrames(60, System.err); - + while(!quitAdapter.shouldQuit() /* && animator.isAnimating() */ && animator.getTotalFPSDuration()<duration) { Thread.sleep(100); } @@ -127,8 +145,11 @@ public class TestGearsES2AWT extends UITestCase { Assert.assertNotNull(glCanvas); Assert.assertNotNull(animator); + Assert.assertEquals(exclusiveContext ? awtEDT : null, glCanvas.getExclusiveContextThread()); animator.stop(); - Assert.assertEquals(false, animator.isAnimating()); + Assert.assertFalse(animator.isAnimating()); + Assert.assertFalse(animator.isStarted()); + Assert.assertEquals(null, glCanvas.getExclusiveContextThread()); frame.setVisible(false); Assert.assertEquals(false, frame.isVisible()); javax.swing.SwingUtilities.invokeAndWait(new Runnable() { @@ -190,6 +211,8 @@ public class TestGearsES2AWT extends UITestCase { } else if(args[i].equals("-vsync")) { i++; swapInterval = MiscUtils.atoi(args[i], swapInterval); + } else if(args[i].equals("-exclctx")) { + exclusiveContext = true; } else if(args[i].equals("-layered")) { shallUseOffscreenLayer = true; } else if(args[i].equals("-layeredPBuffer")) { @@ -216,6 +239,7 @@ public class TestGearsES2AWT extends UITestCase { System.err.println("forceES2 "+forceES2); System.err.println("forceGL3 "+forceGL3); System.err.println("swapInterval "+swapInterval); + System.err.println("exclusiveContext "+exclusiveContext); System.err.println("shallUseOffscreenLayer "+shallUseOffscreenLayer); if(waitForKey) { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java index 86831a6fa..3910d1881 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java @@ -90,6 +90,7 @@ public class TestGearsES2NEWT extends UITestCase { static boolean forceES2 = false; static boolean forceGL3 = false; static boolean mainRun = false; + static boolean exclusiveContext = false; @BeforeClass public static void initClass() { @@ -143,9 +144,11 @@ public class TestGearsES2NEWT extends UITestCase { }); } - Animator animator = new Animator(glWindow); + Animator animator = new Animator(); + animator.setModeBits(false, Animator.MODE_EXPECT_AWT_RENDERING_THREAD); + animator.setExclusiveContext(exclusiveContext); + QuitAdapter quitAdapter = new QuitAdapter(); - //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter)); //glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter)); glWindow.addKeyListener(quitAdapter); @@ -165,62 +168,79 @@ public class TestGearsES2NEWT extends UITestCase { if(e.getKeyChar()=='f') { new Thread() { public void run() { + final Thread t = glWindow.setExclusiveContextThread(null); System.err.println("[set fullscreen pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()); glWindow.setFullscreen(!glWindow.isFullscreen()); System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()); + glWindow.setExclusiveContextThread(t); } }.start(); } else if(e.getKeyChar()=='a') { new Thread() { public void run() { + final Thread t = glWindow.setExclusiveContextThread(null); System.err.println("[set alwaysontop pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()); glWindow.setAlwaysOnTop(!glWindow.isAlwaysOnTop()); System.err.println("[set alwaysontop post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()); + glWindow.setExclusiveContextThread(t); } }.start(); } else if(e.getKeyChar()=='d') { new Thread() { public void run() { + final Thread t = glWindow.setExclusiveContextThread(null); + // while( null != glWindow.getExclusiveContextThread() ) ; System.err.println("[set undecorated pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", d "+glWindow.isUndecorated()+", "+glWindow.getInsets()); glWindow.setUndecorated(!glWindow.isUndecorated()); System.err.println("[set undecorated post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", d "+glWindow.isUndecorated()+", "+glWindow.getInsets()); + glWindow.setExclusiveContextThread(t); } }.start(); } else if(e.getKeyChar()=='s') { new Thread() { public void run() { + final Thread t = glWindow.setExclusiveContextThread(null); System.err.println("[set position pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets()); glWindow.setPosition(100, 100); System.err.println("[set position post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets()); + glWindow.setExclusiveContextThread(t); } }.start(); } else if(e.getKeyChar()=='i') { new Thread() { public void run() { + final Thread t = glWindow.setExclusiveContextThread(null); System.err.println("[set mouse visible pre]: "+glWindow.isPointerVisible()); glWindow.setPointerVisible(!glWindow.isPointerVisible()); System.err.println("[set mouse visible post]: "+glWindow.isPointerVisible()); + glWindow.setExclusiveContextThread(t); } }.start(); } else if(e.getKeyChar()=='j') { new Thread() { public void run() { + final Thread t = glWindow.setExclusiveContextThread(null); System.err.println("[set mouse confined pre]: "+glWindow.isPointerConfined()); glWindow.confinePointer(!glWindow.isPointerConfined()); System.err.println("[set mouse confined post]: "+glWindow.isPointerConfined()); if(!glWindow.isPointerConfined()) { demo.setConfinedFixedCenter(false); } + glWindow.setExclusiveContextThread(t); } }.start(); } else if(e.getKeyChar()=='J') { new Thread() { public void run() { + final Thread t = glWindow.setExclusiveContextThread(null); System.err.println("[set mouse confined pre]: "+glWindow.isPointerConfined()); glWindow.confinePointer(!glWindow.isPointerConfined()); System.err.println("[set mouse confined post]: "+glWindow.isPointerConfined()); demo.setConfinedFixedCenter(glWindow.isPointerConfined()); + glWindow.setExclusiveContextThread(t); } }.start(); } else if(e.getKeyChar()=='w') { new Thread() { public void run() { + final Thread t = glWindow.setExclusiveContextThread(null); System.err.println("[set mouse pos pre]"); glWindow.warpPointer(glWindow.getWidth()/2, glWindow.getHeight()/2); System.err.println("[set mouse pos post]"); + glWindow.setExclusiveContextThread(t); } }.start(); } } @@ -232,24 +252,29 @@ public class TestGearsES2NEWT extends UITestCase { } }); + animator.add(glWindow); animator.start(); - // glWindow.setSkipContextReleaseThread(animator.getThread()); + Assert.assertTrue(animator.isStarted()); + Assert.assertTrue(animator.isAnimating()); + Assert.assertEquals(exclusiveContext ? animator.getThread() : null, glWindow.getExclusiveContextThread()); glWindow.setVisible(true); + animator.setUpdateFPSFrames(60, showFPS ? System.err : null); System.err.println("NW chosen: "+glWindow.getDelegatedWindow().getChosenCapabilities()); System.err.println("GL chosen: "+glWindow.getChosenCapabilities()); System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets()); - animator.setUpdateFPSFrames(60, showFPS ? System.err : null); while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) { Thread.sleep(100); } + Assert.assertEquals(exclusiveContext ? animator.getThread() : null, glWindow.getExclusiveContextThread()); animator.stop(); Assert.assertFalse(animator.isAnimating()); Assert.assertFalse(animator.isStarted()); + Assert.assertEquals(null, glWindow.getExclusiveContextThread()); glWindow.destroy(); Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow, false)); } @@ -316,6 +341,8 @@ public class TestGearsES2NEWT extends UITestCase { } else if(args[i].equals("-vsync")) { i++; swapInterval = MiscUtils.atoi(args[i], swapInterval); + } else if(args[i].equals("-exclctx")) { + exclusiveContext = true; } else if(args[i].equals("-es2")) { forceES2 = true; } else if(args[i].equals("-gl3")) { @@ -365,14 +392,15 @@ public class TestGearsES2NEWT extends UITestCase { System.err.println("undecorated "+undecorated); System.err.println("atop "+alwaysOnTop); System.err.println("fullscreen "+fullscreen); - System.err.println("pmvDirect "+(!pmvUseBackingArray)); - System.err.println("swapInterval "+swapInterval); + System.err.println("pmvDirect "+(!pmvUseBackingArray)); System.err.println("mouseVisible "+mouseVisible); System.err.println("mouseConfined "+mouseConfined); System.err.println("loops "+loops); System.err.println("loop shutdown "+loop_shutdown); System.err.println("forceES2 "+forceES2); System.err.println("forceGL3 "+forceGL3); + System.err.println("swapInterval "+swapInterval); + System.err.println("exclusiveContext "+exclusiveContext); if(waitForKey) { BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); |