JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
TestSharedContextVBOES2NEWT2.java
Go to the documentation of this file.
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
29package com.jogamp.opengl.test.junit.jogl.acore;
30
31import java.util.List;
32
33import com.jogamp.newt.opengl.GLWindow;
34
35import com.jogamp.nativewindow.util.InsetsImmutable;
36import com.jogamp.opengl.GLCapabilities;
37import com.jogamp.opengl.GLContext;
38import com.jogamp.opengl.GLProfile;
39
40import com.jogamp.opengl.util.Animator;
41import com.jogamp.opengl.test.junit.util.NewtTestUtil;
42import com.jogamp.opengl.test.junit.util.GLTestUtil;
43import com.jogamp.opengl.test.junit.util.MiscUtils;
44import com.jogamp.opengl.test.junit.util.UITestCase;
45import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
46
47import org.junit.Assert;
48import org.junit.BeforeClass;
49import org.junit.Test;
50import org.junit.FixMethodOrder;
51import org.junit.runners.MethodSorters;
52
53/**
54 * Sharing the VBO of 3 GearsES2 instances, each in their own GLWindow.
55 * <p>
56 * This is achieved by using the 1st GLWindow's GLContext as the <i>master</i>
57 * and synchronizing via GLSharedContextSetter to postpone creation
58 * of the 2nd and 3rd GLWindow until the 1st GLWindow's GLContext becomes created.
59 * </p>
60 * <p>
61 * Above method allows random creation of the 1st GLWindow, which triggers
62 * creation of the <i>dependent</i> other GLWindow sharing it's GLContext.
63 * </p>
64 */
65@FixMethodOrder(MethodSorters.NAME_ASCENDING)
67 static GLProfile glp;
68 static GLCapabilities caps;
69 static int width, height;
70
71 @BeforeClass
72 public static void initClass() {
75 Assert.assertNotNull(glp);
76 caps = new GLCapabilities(glp);
77 Assert.assertNotNull(caps);
78 width = 256;
79 height = 256;
80 } else {
81 setTestSupported(false);
82 }
83 }
84
85 protected GLWindow createGLWindow(final int x, final int y, final GearsES2 gears) throws InterruptedException {
86 final GLWindow glWindow = GLWindow.create(caps);
87 Assert.assertNotNull(glWindow);
88 glWindow.setPosition(x, y);
89 glWindow.setTitle("Shared Gears NEWT Test: "+x+"/"+y+" shared true");
90 glWindow.setSize(width, height);
91 glWindow.addGLEventListener(gears);
92
93 return glWindow;
94 }
95
96 @Test
97 public void test01SyncedOneAnimatorCleanDtorOrder() throws InterruptedException {
98 syncedOneAnimator(true);
99 }
100
101 @Test
102 public void test02SyncedOneAnimatorDirtyDtorOrder() throws InterruptedException {
103 syncedOneAnimator(false);
104 }
105
106 public void syncedOneAnimator(final boolean destroyCleanOrder) throws InterruptedException {
107 final Animator animator = new Animator(0 /* w/o AWT */);
108 animator.start();
109
110 final GearsES2 g1 = new GearsES2(0);
111 g1.setSyncObjects(g1); // this is master, since rendered we must use it as sync
112 final GLWindow f1 = createGLWindow(0, 0, g1);
113 animator.add(f1);
114 final InsetsImmutable insets = f1.getInsets();
115
116 final GearsES2 g2 = new GearsES2(0);
117 g2.setSharedGears(g1); // also uses master g1 as sync, if required
118 final GLWindow f2 = createGLWindow(f1.getX()+width+insets.getTotalWidth(),
119 f1.getY()+0, g2);
120 f2.setSharedAutoDrawable(f1);
121 animator.add(f2);
122 f2.setVisible(true);
123
124 final GearsES2 g3 = new GearsES2(0);
125 g3.setSharedGears(g1); // also uses master g1 as sync, if required
126 final GLWindow f3 = createGLWindow(f1.getX()+0,
127 f1.getY()+height+insets.getTotalHeight(), g3);
128 f3.setSharedAutoDrawable(f1);
129 animator.add(f3);
130 f3.setVisible(true);
131
132 Assert.assertTrue(NewtTestUtil.waitForRealized(f1, false, null));
133 Assert.assertTrue(NewtTestUtil.waitForVisible(f1, false, null));
134 Assert.assertTrue(GLTestUtil.waitForContextCreated(f1, false, null));
135
136 Assert.assertTrue(NewtTestUtil.waitForRealized(f2, true, null));
137 Assert.assertTrue(NewtTestUtil.waitForVisible(f2, true, null));
138 Assert.assertTrue(GLTestUtil.waitForContextCreated(f2, false, null));
139
140 Assert.assertTrue(NewtTestUtil.waitForRealized(f3, true, null));
141 Assert.assertTrue(NewtTestUtil.waitForVisible(f3, true, null));
142 Assert.assertTrue(GLTestUtil.waitForContextCreated(f3, false, null));
143
144 f1.setVisible(true); // kick off f1 GLContext .. and hence allow f2 + f3 creation
145
146 Assert.assertTrue(NewtTestUtil.waitForRealized(f1, true, null));
147 Assert.assertTrue(NewtTestUtil.waitForVisible(f1, true, null));
148 Assert.assertTrue(GLTestUtil.waitForContextCreated(f1, true, null));
149 Assert.assertTrue("Gears1 not initialized", g1.waitForInit(true));
150
151 Assert.assertTrue(NewtTestUtil.waitForRealized(f2, true, null));
152 Assert.assertTrue(NewtTestUtil.waitForVisible(f2, true, null));
153 Assert.assertTrue(GLTestUtil.waitForContextCreated(f2, true, null));
154 Assert.assertTrue("Gears2 not initialized", g2.waitForInit(true));
155
156 Assert.assertTrue(NewtTestUtil.waitForRealized(f3, true, null));
157 Assert.assertTrue(NewtTestUtil.waitForVisible(f3, true, null));
158 Assert.assertTrue(GLTestUtil.waitForContextCreated(f3, true, null));
159 Assert.assertTrue("Gears3 not initialized", g3.waitForInit(true));
160
161 final GLContext ctx1 = f1.getContext();
162 final GLContext ctx2 = f2.getContext();
163 final GLContext ctx3 = f3.getContext();
164 {
165 final List<GLContext> ctx1Shares = ctx1.getCreatedShares();
166 final List<GLContext> ctx2Shares = ctx2.getCreatedShares();
167 final List<GLContext> ctx3Shares = ctx3.getCreatedShares();
168 MiscUtils.dumpSharedGLContext("XXX-C-3.1", ctx1);
169 MiscUtils.dumpSharedGLContext("XXX-C-3.2", ctx2);
170 MiscUtils.dumpSharedGLContext("XXX-C-3.3", ctx3);
171
172 Assert.assertTrue("Ctx1 is not shared", ctx1.isShared());
173 Assert.assertTrue("Ctx2 is not shared", ctx2.isShared());
174 Assert.assertTrue("Ctx3 is not shared", ctx3.isShared());
175 Assert.assertEquals("Ctx1 has unexpected number of created shares", 2, ctx1Shares.size());
176 Assert.assertEquals("Ctx2 has unexpected number of created shares", 2, ctx2Shares.size());
177 Assert.assertEquals("Ctx3 has unexpected number of created shares", 2, ctx3Shares.size());
178 Assert.assertEquals("Ctx1 Master Context is different", ctx1, ctx1.getSharedMaster());
179 Assert.assertEquals("Ctx2 Master Context is different", ctx1, ctx2.getSharedMaster());
180 Assert.assertEquals("Ctx3 Master Context is different", ctx1, ctx3.getSharedMaster());
181 }
182
183 Assert.assertTrue("Gears1 is shared", !g1.usesSharedGears());
184 Assert.assertTrue("Gears2 is not shared", g2.usesSharedGears());
185 Assert.assertTrue("Gears3 is not shared", g3.usesSharedGears());
186
187 try {
188 Thread.sleep(duration);
189 } catch(final Exception e) {
190 e.printStackTrace();
191 }
192 animator.stop();
193 Assert.assertEquals(false, animator.isAnimating());
194
195 if( destroyCleanOrder ) {
196 System.err.println("XXX Destroy in clean order NOW");
197 f3.destroy();
198 f2.destroy();
199 f1.destroy();
200 } else {
201 System.err.println("XXX Destroy in creation order NOW - Driver Impl. May trigger driver Bug i.e. not postponing GL ctx destruction after releasing all refs.");
202 f1.destroy();
203 f2.destroy();
204 f3.destroy();
205 }
206 Assert.assertTrue(NewtTestUtil.waitForVisible(f1, false, null));
207 Assert.assertTrue(NewtTestUtil.waitForRealized(f1, false, null));
208 Assert.assertTrue(NewtTestUtil.waitForVisible(f2, false, null));
209 Assert.assertTrue(NewtTestUtil.waitForRealized(f2, false, null));
210 Assert.assertTrue(NewtTestUtil.waitForVisible(f3, false, null));
211 Assert.assertTrue(NewtTestUtil.waitForRealized(f3, false, null));
212 }
213
214 @Test
215 public void test11AsyncEachAnimatorCleanDtorOrder() throws InterruptedException {
216 asyncEachAnimator(true);
217 }
218
219 @Test
220 public void test12AsyncEachAnimatorDirtyDtorOrder() throws InterruptedException {
221 asyncEachAnimator(false);
222 }
223
224 public void asyncEachAnimator(final boolean destroyCleanOrder) throws InterruptedException {
225 final Animator a1 = new Animator(0 /* w/o AWT */);
226 final GearsES2 g1 = new GearsES2(0);
227 g1.setSyncObjects(g1); // this is master, since rendered we must use it as sync
228 final GLWindow f1 = createGLWindow(0, 0, g1);
229 a1.add(f1);
230 a1.start();
231
232 final InsetsImmutable insets = f1.getInsets();
233
234 final Animator a2 = new Animator(0 /* w/o AWT */);
235 final GearsES2 g2 = new GearsES2(0);
236 g2.setSharedGears(g1); // also uses master g1 as sync, if required
237 final GLWindow f2 = createGLWindow(f1.getX()+width+insets.getTotalWidth(),
238 f1.getY()+0, g2);
239 f2.setSharedAutoDrawable(f1);
240 a2.add(f2);
241 a2.start();
242 f2.setVisible(true);
243
244 final Animator a3 = new Animator(0 /* w/o AWT */);
245 final GearsES2 g3 = new GearsES2(0);
246 g3.setSharedGears(g1); // also uses master g1 as sync, if required
247 final GLWindow f3 = createGLWindow(f1.getX()+0,
248 f1.getY()+height+insets.getTotalHeight(), g3);
249 f3.setSharedAutoDrawable(f1);
250 a3.add(f3);
251 a3.start();
252 f3.setVisible(true);
253
254 Assert.assertTrue(NewtTestUtil.waitForRealized(f1, false, null));
255 Assert.assertTrue(NewtTestUtil.waitForVisible(f1, false, null));
256 Assert.assertTrue(GLTestUtil.waitForContextCreated(f1, false, null));
257
258 Assert.assertTrue(NewtTestUtil.waitForRealized(f2, true, null));
259 Assert.assertTrue(NewtTestUtil.waitForVisible(f2, true, null));
260 Assert.assertTrue(GLTestUtil.waitForContextCreated(f2, false, null));
261
262 Assert.assertTrue(NewtTestUtil.waitForRealized(f3, true, null));
263 Assert.assertTrue(NewtTestUtil.waitForVisible(f3, true, null));
264 Assert.assertTrue(GLTestUtil.waitForContextCreated(f3, false, null));
265
266 f1.setVisible(true); // kicks off f1 GLContext .. and hence gears of f2 + f3 completion
267
268 Assert.assertTrue(NewtTestUtil.waitForRealized(f1, true, null));
269 Assert.assertTrue(NewtTestUtil.waitForVisible(f1, true, null));
270 Assert.assertTrue(GLTestUtil.waitForContextCreated(f1, true, null));
271 Assert.assertTrue("Gears1 not initialized", g1.waitForInit(true));
272
273 Assert.assertTrue(NewtTestUtil.waitForRealized(f2, true, null));
274 Assert.assertTrue(NewtTestUtil.waitForVisible(f2, true, null));
275 Assert.assertTrue(GLTestUtil.waitForContextCreated(f2, true, null));
276 Assert.assertTrue("Gears2 not initialized", g2.waitForInit(true));
277 Assert.assertTrue(NewtTestUtil.waitForRealized(f3, true, null));
278 Assert.assertTrue(NewtTestUtil.waitForVisible(f3, true, null));
279 Assert.assertTrue(GLTestUtil.waitForContextCreated(f3, true, null));
280 Assert.assertTrue("Gears3 not initialized", g3.waitForInit(true));
281
282 final GLContext ctx1 = f1.getContext();
283 final GLContext ctx2 = f2.getContext();
284 final GLContext ctx3 = f3.getContext();
285 {
286 final List<GLContext> ctx1Shares = ctx1.getCreatedShares();
287 final List<GLContext> ctx2Shares = ctx2.getCreatedShares();
288 final List<GLContext> ctx3Shares = ctx3.getCreatedShares();
289 MiscUtils.dumpSharedGLContext("XXX-C-3.1", ctx1);
290 MiscUtils.dumpSharedGLContext("XXX-C-3.2", ctx2);
291 MiscUtils.dumpSharedGLContext("XXX-C-3.3", ctx3);
292
293 Assert.assertTrue("Ctx1 is not shared", ctx1.isShared());
294 Assert.assertTrue("Ctx2 is not shared", ctx2.isShared());
295 Assert.assertTrue("Ctx3 is not shared", ctx3.isShared());
296 Assert.assertEquals("Ctx1 has unexpected number of created shares", 2, ctx1Shares.size());
297 Assert.assertEquals("Ctx2 has unexpected number of created shares", 2, ctx2Shares.size());
298 Assert.assertEquals("Ctx3 has unexpected number of created shares", 2, ctx3Shares.size());
299 Assert.assertEquals("Ctx1 Master Context is different", ctx1, ctx1.getSharedMaster());
300 Assert.assertEquals("Ctx2 Master Context is different", ctx1, ctx2.getSharedMaster());
301 Assert.assertEquals("Ctx3 Master Context is different", ctx1, ctx3.getSharedMaster());
302 }
303
304 Assert.assertTrue("Gears1 is shared", !g1.usesSharedGears());
305 Assert.assertTrue("Gears2 is not shared", g2.usesSharedGears());
306 Assert.assertTrue("Gears3 is not shared", g3.usesSharedGears());
307
308 try {
309 Thread.sleep(duration);
310 } catch(final Exception e) {
311 e.printStackTrace();
312 }
313 // Stopped animator allows native windowing system 'repaint' event
314 // to trigger GLAD 'display'
315 a1.stop();
316 Assert.assertEquals(false, a1.isAnimating());
317 a2.stop();
318 Assert.assertEquals(false, a2.isAnimating());
319 a3.stop();
320 Assert.assertEquals(false, a3.isAnimating());
321
322 if( destroyCleanOrder ) {
323 System.err.println("XXX Destroy in clean order NOW");
324 f3.destroy();
325 f2.destroy();
326 f1.destroy();
327 } else {
328 System.err.println("XXX Destroy in creation order NOW - Driver Impl. May trigger driver Bug i.e. not postponing GL ctx destruction after releasing all refs.");
329 f1.destroy();
330 f2.destroy();
331 f3.destroy();
332 }
333 Assert.assertTrue(NewtTestUtil.waitForVisible(f1, false, null));
334 Assert.assertTrue(NewtTestUtil.waitForRealized(f1, false, null));
335 Assert.assertTrue(NewtTestUtil.waitForVisible(f2, false, null));
336 Assert.assertTrue(NewtTestUtil.waitForRealized(f2, false, null));
337 Assert.assertTrue(NewtTestUtil.waitForVisible(f3, false, null));
338 Assert.assertTrue(NewtTestUtil.waitForRealized(f3, false, null));
339 }
340
341 static long duration = 1000; // ms
342 static boolean mainRun = false;
343
344 public static void main(final String args[]) {
345 mainRun = true;
346 for(int i=0; i<args.length; i++) {
347 if(args[i].equals("-time")) {
348 i++;
349 try {
350 duration = Integer.parseInt(args[i]);
351 } catch (final Exception ex) { ex.printStackTrace(); }
352 }
353 }
354 /**
355 BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
356 System.err.println("Press enter to continue");
357 System.err.println(stdin.readLine()); */
358 org.junit.runner.JUnitCore.main(TestSharedContextVBOES2NEWT2.class.getName());
359 }
360}
An implementation of GLAutoDrawable and Window interface, using a delegated Window instance,...
Definition: GLWindow.java:121
final void setPosition(final int x, final int y)
Sets the location of the window's client area excluding insets (window decorations) in window units.
Definition: GLWindow.java:525
final void setTitle(final String title)
Definition: GLWindow.java:297
final int getX()
Returns the current x position of this window, relative to it's parent.
Definition: GLWindow.java:436
final int getY()
Returns the current y position of the top-left corner of the client area relative to it's parent in w...
Definition: GLWindow.java:441
final void setSize(final int width, final int height)
Sets the size of the window's client area in window units, excluding decorations.
Definition: GLWindow.java:625
final void setVisible(final boolean visible)
Calls setVisible(true, visible), i.e.
Definition: GLWindow.java:615
final InsetsImmutable getInsets()
Returns the insets defined as the width and height of the window decoration on the left,...
Definition: GLWindow.java:431
final void destroy()
Destroys all resources associated with this GLAutoDrawable, inclusive the GLContext.
Definition: GLWindow.java:605
static GLWindow create(final GLCapabilitiesImmutable caps)
Creates a new GLWindow attaching a new Window referencing a new default Screen and default Display wi...
Definition: GLWindow.java:169
Specifies a set of OpenGL capabilities.
Abstraction for an OpenGL rendering context.
Definition: GLContext.java:74
final boolean isShared()
Returns true if this GLContext is shared, otherwise false.
Definition: GLContext.java:261
final GLContext getSharedMaster()
Returns the shared master GLContext of this GLContext if shared, otherwise return null.
Definition: GLContext.java:272
final List< GLContext > getCreatedShares()
Returns a new list of created GLContext shared with this GLContext.
Definition: GLContext.java:277
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
static boolean isAvailable(final AbstractGraphicsDevice device, final String profile)
Returns the availability of a profile on a device.
Definition: GLProfile.java:305
static final String GL2ES2
The intersection of the desktop GL3, GL2 and embedded ES2 profile.
Definition: GLProfile.java:594
static GLProfile get(final AbstractGraphicsDevice device, String profile)
Returns a GLProfile object.
Sharing the VBO of 3 GearsES2 instances, each in their own GLWindow.
GLWindow createGLWindow(final int x, final int y, final GearsES2 gears)
boolean waitForInit(final boolean initialized)
Definition: GearsES2.java:187
static boolean waitForContextCreated(final GLAutoDrawable autoDrawable, final boolean created, final Runnable waitAction)
Definition: GLTestUtil.java:42
static void dumpSharedGLContext(final String prefix, final GLContext self)
Definition: MiscUtils.java:271
static boolean waitForRealized(final Screen screen, final boolean realized, final Runnable waitAction)
static boolean waitForVisible(final Window win, final boolean visible, final Runnable waitAction)
final synchronized void add(final GLAutoDrawable drawable)
Adds a drawable to this animator's list of rendering drawables.
final synchronized boolean start()
Starts this animator, if not running.
Definition: Animator.java:344
final synchronized boolean stop()
Stops this animator.
Definition: Animator.java:368
Immutable insets representing rectangular window decoration insets on all four edges in window units.
void addGLEventListener(GLEventListener listener)
Adds the given listener to the end of this drawable queue.
GLContext getContext()
Returns the context associated with this drawable.