1 /**
2  * Copyright 2010 JogAmp Community. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are
5  * permitted provided that the following conditions are met:
6  *
7  *    1. Redistributions of source code must retain the above copyright notice, this list of
8  *       conditions and the following disclaimer.
9  *
10  *    2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *       of conditions and the following disclaimer in the documentation and/or other materials
12  *       provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  * The views and conclusions contained in the software and documentation are those of the
25  * authors and should not be interpreted as representing official policies, either expressed
26  * or implied, of JogAmp Community.
27  */
28 
29 package com.jogamp.opengl.test.junit.jogl.acore;
30 
31 import com.jogamp.newt.opengl.GLWindow;
32 
33 import com.jogamp.nativewindow.util.InsetsImmutable;
34 import com.jogamp.opengl.GLAutoDrawable;
35 import com.jogamp.opengl.GLCapabilities;
36 import com.jogamp.opengl.GLContext;
37 import com.jogamp.opengl.GLDrawable;
38 import com.jogamp.opengl.GLDrawableFactory;
39 import com.jogamp.opengl.GLProfile;
40 
41 import com.jogamp.opengl.GLAutoDrawableDelegate;
42 import com.jogamp.opengl.util.Animator;
43 import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
44 import com.jogamp.opengl.test.junit.util.MiscUtils;
45 import com.jogamp.opengl.test.junit.util.UITestCase;
46 import com.jogamp.opengl.test.junit.jogl.demos.es1.GearsES1;
47 
48 import org.junit.Assert;
49 import org.junit.BeforeClass;
50 import org.junit.Test;
51 import org.junit.FixMethodOrder;
52 import org.junit.runners.MethodSorters;
53 
54 /**
55  * Sharing the VBO of 3 GearsES1 instances, each in their own GLWindow.
56  * <p>
57  * This is achieved by creating a <i>master</i> GLContext to an offscreen invisible GLAutoDrawable,
58  * which is then shared by the 3 GLContext of the three GLWindow instances.
59  * </p>
60  * <p>
61  * The original VBO is created by attaching a GearsES1 instance to
62  * the <i>master</i> GLAutoDrawable and initializing it.
63  * </p>
64  * <p>
65  * Above method allows random creation of all GLWindow instances.
66  * </p>
67  * <p>
68  * One animator is being used, hence the GLWindow, GLDrawable and GLContext
69  * creation of all 3 GLWindows is sequential.
70  * </p>
71  */
72 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
73 public class TestSharedContextVBOES1NEWT extends UITestCase {
74     static GLProfile glp;
75     static GLCapabilities caps;
76     static int width, height;
77     GLAutoDrawable sharedDrawable;
78     GearsES1 sharedGears;
79 
80     @BeforeClass
initClass()81     public static void initClass() {
82         if(GLProfile.isAvailable(GLProfile.GL2ES1)) {
83             glp = GLProfile.get(GLProfile.GL2ES1);
84             Assert.assertNotNull(glp);
85             caps = new GLCapabilities(glp);
86             Assert.assertNotNull(caps);
87             width  = 256;
88             height = 256;
89         } else {
90             setTestSupported(false);
91         }
92     }
93 
initShared()94     private void initShared() throws InterruptedException {
95         final GLDrawable dummyDrawable = GLDrawableFactory.getFactory(glp).createDummyDrawable(null, true /* createNewDevice */, caps, null);
96         dummyDrawable.setRealized(true);
97         sharedDrawable = new GLAutoDrawableDelegate(dummyDrawable, null, null, true /*ownDevice*/, null) { };
98         Assert.assertNotNull(sharedDrawable);
99         Assert.assertTrue(AWTRobotUtil.waitForRealized(sharedDrawable, true));
100 
101         sharedGears = new GearsES1();
102         Assert.assertNotNull(sharedGears);
103         sharedDrawable.addGLEventListener(sharedGears);
104         // init and render one frame, which will setup the Gears display lists
105         sharedDrawable.display();
106         final GLContext ctxM = sharedDrawable.getContext();
107         Assert.assertTrue("Master ctx not created", AWTRobotUtil.waitForContextCreated(sharedDrawable, true));
108         Assert.assertTrue("Master Ctx is shared before shared creation", !ctxM.isShared());
109         Assert.assertTrue("Master Gears is shared", !sharedGears.usesSharedGears());
110     }
111 
releaseShared()112     private void releaseShared() {
113         Assert.assertNotNull(sharedDrawable);
114         sharedDrawable.destroy();
115     }
116 
runTestGL(final Animator animator, final int x, final int y, final boolean useShared, final boolean vsync)117     protected GLWindow runTestGL(final Animator animator, final int x, final int y, final boolean useShared, final boolean vsync) throws InterruptedException {
118         final GLWindow glWindow = GLWindow.create(caps);
119         Assert.assertNotNull(glWindow);
120         glWindow.setPosition(x, y);
121         glWindow.setTitle("Shared Gears NEWT Test: "+x+"/"+y+" shared "+useShared);
122         if(useShared) {
123             glWindow.setSharedAutoDrawable(sharedDrawable);
124         }
125 
126         glWindow.setSize(width, height);
127 
128         final GearsES1 gears = new GearsES1(vsync ? 1 : 0);
129         if(useShared) {
130             gears.setSharedGears(sharedGears);
131         }
132         glWindow.addGLEventListener(gears);
133 
134         animator.add(glWindow);
135 
136         glWindow.setVisible(true);
137         Assert.assertTrue(AWTRobotUtil.waitForRealized(glWindow, true));
138         Assert.assertTrue(AWTRobotUtil.waitForVisible(glWindow, true));
139         Assert.assertTrue(AWTRobotUtil.waitForContextCreated(glWindow, true));
140 
141         MiscUtils.dumpSharedGLContext("Master Context", sharedDrawable.getContext());
142         MiscUtils.dumpSharedGLContext("New    Context", glWindow.getContext());
143         if( useShared ) {
144             Assert.assertEquals("Master Context not shared as expected", true, sharedDrawable.getContext().isShared());
145             Assert.assertEquals("Master Context is different", sharedDrawable.getContext(), glWindow.getContext().getSharedMaster());
146         } else {
147 
148         }
149         Assert.assertEquals("New    Context not shared as expected", useShared, glWindow.getContext().isShared());
150         Assert.assertEquals("Gears is not shared as expected", useShared, gears.usesSharedGears());
151         return glWindow;
152     }
153 
154     @Test
test01()155     public void test01() throws InterruptedException {
156         initShared();
157         final Animator animator = new Animator();
158         final GLWindow f1 = runTestGL(animator, 0, 0, true, false);
159         final InsetsImmutable insets = f1.getInsets();
160         final GLWindow f2 = runTestGL(animator, f1.getX()+width+insets.getTotalWidth(),
161                                           f1.getY()+0, true, false);
162         final GLWindow f3 = runTestGL(animator, f1.getX()+0,
163                                           f1.getY()+height+insets.getTotalHeight(), false, true);
164         animator.setUpdateFPSFrames(1, null);
165         animator.start();
166         while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
167             Thread.sleep(100);
168         }
169         animator.stop();
170 
171         f1.destroy();
172         f2.destroy();
173         f3.destroy();
174 
175         releaseShared();
176     }
177 
178     static long duration = 500; // ms
179 
main(final String args[])180     public static void main(final String args[]) {
181         for(int i=0; i<args.length; i++) {
182             if(args[i].equals("-time")) {
183                 i++;
184                 try {
185                     duration = Integer.parseInt(args[i]);
186                 } catch (final Exception ex) { ex.printStackTrace(); }
187             }
188         }
189         org.junit.runner.JUnitCore.main(TestSharedContextVBOES1NEWT.class.getName());
190     }
191 }
192