JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
TestSharedContextVBOES2AWT3b.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.awt.Frame;
32import java.lang.reflect.InvocationTargetException;
33import java.util.List;
34
35import com.jogamp.opengl.GLCapabilities;
36import com.jogamp.opengl.GLContext;
37import com.jogamp.opengl.GLProfile;
38import com.jogamp.opengl.awt.GLJPanel;
39
40import com.jogamp.opengl.util.Animator;
41import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
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 AWT GLJPanel.
55 * <p>
56 * This is achieved by using the 1st GLJPanel as the <i>master</i>
57 * and using the build-in blocking mechanism to postpone creation
58 * of the 2nd and 3rd GLJPanel until the 1st GLJPanel 's GLContext becomes created.
59 * </p>
60 * <p>
61 * Above method allows random creation of the 1st GLJPanel, which triggers
62 * creation of the <i>dependent</i> other GLJPanel 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 GLJPanel createGLJPanel(final Frame frame, final int x, final int y, final GearsES2 gears) throws InterruptedException {
86 final GLJPanel glCanvas = new GLJPanel(caps);
87 Assert.assertNotNull(glCanvas);
88 glCanvas.addGLEventListener(gears);
89 frame.add(glCanvas);
90 frame.setLocation(x, y);
91 frame.setSize(width, height);
92 frame.setTitle("AWT GLJPanel Shared Gears Test: "+x+"/"+y+" shared true");
93 return glCanvas;
94 }
95
96 @Test
97 public void test01SyncedOneAnimator() throws InterruptedException, InvocationTargetException {
98 final Frame f1 = new Frame();
99 final Animator animator = new Animator();
100 final GearsES2 g1 = new GearsES2(0);
101 // g1.setUseMappedBuffers(useMappedBuffers);
102 g1.setValidateBuffers(true);
103 final GLJPanel c1 = createGLJPanel(f1, 0, 0, g1);
104 animator.add(c1);
105
106 final Frame f2 = new Frame();
107 final GearsES2 g2 = new GearsES2(0);
108 g2.setSharedGears(g1);
109 final GLJPanel c2 = createGLJPanel(f2, f1.getX()+width,
110 f1.getY()+0, g2);
112 animator.add(c2);
113
114 final Frame f3 = new Frame();
115 final GearsES2 g3 = new GearsES2(0);
116 g3.setSharedGears(g1);
117 final GLJPanel c3 = createGLJPanel(f3, f1.getX()+0,
118 f1.getY()+height, g3);
120 animator.add(c3);
121
122 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
123 public void run() {
124 f2.setVisible(true); // shall wait until f1 is ready
125 f1.setVisible(true); // master ..
126 f3.setVisible(true); // shall wait until f1 is ready
127 } } );
128 animator.start(); // kicks off GLContext .. and hence gears of f2 + f3 completion
129
130 Thread.sleep(1000/60*10); // wait ~10 frames giving a chance to create (blocking until master share is valid)
131
132 Assert.assertTrue(AWTRobotUtil.waitForRealized(c1, true, null));
133 Assert.assertTrue(AWTRobotUtil.waitForVisible(c1, true, null));
134 Assert.assertTrue(GLTestUtil.waitForContextCreated(c1, true, null));
135 Assert.assertTrue("Gears1 not initialized", g1.waitForInit(true));
136
137 Assert.assertTrue(AWTRobotUtil.waitForRealized(c2, true, null));
138 Assert.assertTrue(AWTRobotUtil.waitForVisible(c2, true, null));
139 Assert.assertTrue(GLTestUtil.waitForContextCreated(c2, true, null));
140 Assert.assertTrue("Gears2 not initialized", g2.waitForInit(true));
141
142 Assert.assertTrue(AWTRobotUtil.waitForRealized(c3, true, null));
143 Assert.assertTrue(AWTRobotUtil.waitForVisible(c3, true, null));
144 Assert.assertTrue(GLTestUtil.waitForContextCreated(c3, true, null));
145 Assert.assertTrue("Gears3 not initialized", g3.waitForInit(true));
146
147 final GLContext ctx1 = c1.getContext();
148 final GLContext ctx2 = c2.getContext();
149 final GLContext ctx3 = c3.getContext();
150 {
151 final List<GLContext> ctx1Shares = ctx1.getCreatedShares();
152 final List<GLContext> ctx2Shares = ctx2.getCreatedShares();
153 final List<GLContext> ctx3Shares = ctx3.getCreatedShares();
154 MiscUtils.dumpSharedGLContext("XXX-C-3.1", ctx1);
155 MiscUtils.dumpSharedGLContext("XXX-C-3.2", ctx2);
156 MiscUtils.dumpSharedGLContext("XXX-C-3.3", ctx3);
157
158 Assert.assertTrue("Ctx1 is not shared", ctx1.isShared());
159 Assert.assertTrue("Ctx2 is not shared", ctx2.isShared());
160 Assert.assertTrue("Ctx3 is not shared", ctx3.isShared());
161 Assert.assertEquals("Ctx1 has unexpected number of created shares", 2, ctx1Shares.size());
162 Assert.assertEquals("Ctx2 has unexpected number of created shares", 2, ctx2Shares.size());
163 Assert.assertEquals("Ctx3 has unexpected number of created shares", 2, ctx3Shares.size());
164 }
165
166 Assert.assertTrue("Gears1 is shared", !g1.usesSharedGears());
167 Assert.assertTrue("Gears2 is not shared", g2.usesSharedGears());
168 Assert.assertTrue("Gears3 is not shared", g3.usesSharedGears());
169
170 try {
171 Thread.sleep(duration);
172 } catch(final Exception e) {
173 e.printStackTrace();
174 }
175 // Stopped animator allows native windowing system 'repaint' event
176 // to trigger GLAD 'display'
177 animator.stop();
178 Assert.assertEquals(false, animator.isAnimating());
179
180 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
181 public void run() {
182 try {
183 f3.dispose();
184 f2.dispose();
185 f1.dispose();
186 } catch (final Throwable t) {
187 throw new RuntimeException(t);
188 }
189 }});
190
191 Assert.assertTrue(AWTRobotUtil.waitForRealized(c1, false, null));
192 Assert.assertTrue(AWTRobotUtil.waitForRealized(c2, false, null));
193 Assert.assertTrue(AWTRobotUtil.waitForRealized(c3, false, null));
194 }
195
196 @Test
197 public void test02AsyncEachAnimator() throws InterruptedException, InvocationTargetException {
198 final Frame f1 = new Frame();
199 final Animator a1 = new Animator();
200 final GearsES2 g1 = new GearsES2(0);
201 g1.setSyncObjects(g1); // this is master, since rendered we must use it as sync
202 // g1.setUseMappedBuffers(useMappedBuffers);
203 g1.setValidateBuffers(true);
204 final GLJPanel c1 = createGLJPanel(f1, 0, 0, g1);
205 a1.add(c1);
206 a1.start();
207 // f1.setVisible(true); // we do this post f2 .. to test pending creation!
208
209 final Frame f2 = new Frame();
210 final Animator a2 = new Animator();
211 final GearsES2 g2 = new GearsES2(0);
212 g2.setSharedGears(g1);
213 final GLJPanel c2 = createGLJPanel(f2, f1.getX()+width, f1.getY()+0, g2);
215 a2.add(c2);
216 a2.start();
217 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
218 public void run() {
219 f2.setVisible(true);
220 } } );
221
222 Thread.sleep(200); // wait a while ..
223
224 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
225 public void run() {
226 f1.setVisible(true); // test pending creation of f2
227 } } );
228
229 final Frame f3 = new Frame();
230 final Animator a3 = new Animator();
231 final GearsES2 g3 = new GearsES2(0);
232 g3.setSharedGears(g1);
233 final GLJPanel c3 = createGLJPanel(f3, f1.getX()+0, f1.getY()+height, g3);
235 a3.add(c3);
236 a3.start();
237 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
238 public void run() {
239 f3.setVisible(true);
240 } } );
241
242 Thread.sleep(1000/60*10); // wait ~10 frames giving a chance to create (blocking until master share is valid)
243
244 Assert.assertTrue(AWTRobotUtil.waitForRealized(c1, true, null));
245 Assert.assertTrue(AWTRobotUtil.waitForVisible(c1, true, null));
246 Assert.assertTrue(GLTestUtil.waitForContextCreated(c1, true, null));
247 Assert.assertTrue("Gears1 not initialized", g1.waitForInit(true));
248
249 Assert.assertTrue(AWTRobotUtil.waitForRealized(c2, true, null));
250 Assert.assertTrue(AWTRobotUtil.waitForVisible(c2, true, null));
251 Assert.assertTrue(GLTestUtil.waitForContextCreated(c2, true, null));
252 Assert.assertTrue("Gears2 not initialized", g2.waitForInit(true));
253
254 Assert.assertTrue(AWTRobotUtil.waitForRealized(c3, true, null));
255 Assert.assertTrue(AWTRobotUtil.waitForVisible(c3, true, null));
256 Assert.assertTrue(GLTestUtil.waitForContextCreated(c3, true, null));
257 Assert.assertTrue("Gears3 not initialized", g3.waitForInit(true));
258
259 final GLContext ctx1 = c1.getContext();
260 final GLContext ctx2 = c2.getContext();
261 final GLContext ctx3 = c3.getContext();
262 {
263 final List<GLContext> ctx1Shares = ctx1.getCreatedShares();
264 final List<GLContext> ctx2Shares = ctx2.getCreatedShares();
265 final List<GLContext> ctx3Shares = ctx3.getCreatedShares();
266 MiscUtils.dumpSharedGLContext("XXX-C-3.1", ctx1);
267 MiscUtils.dumpSharedGLContext("XXX-C-3.2", ctx2);
268 MiscUtils.dumpSharedGLContext("XXX-C-3.3", ctx3);
269
270 Assert.assertTrue("Ctx1 is not shared", ctx1.isShared());
271 Assert.assertTrue("Ctx2 is not shared", ctx2.isShared());
272 Assert.assertTrue("Ctx3 is not shared", ctx3.isShared());
273 Assert.assertEquals("Ctx1 has unexpected number of created shares", 2, ctx1Shares.size());
274 Assert.assertEquals("Ctx2 has unexpected number of created shares", 2, ctx2Shares.size());
275 Assert.assertEquals("Ctx3 has unexpected number of created shares", 2, ctx3Shares.size());
276 }
277
278 Assert.assertTrue("Gears1 is shared", !g1.usesSharedGears());
279 Assert.assertTrue("Gears2 is not shared", g2.usesSharedGears());
280 Assert.assertTrue("Gears3 is not shared", g3.usesSharedGears());
281
282 try {
283 Thread.sleep(duration);
284 } catch(final Exception e) {
285 e.printStackTrace();
286 }
287 // Stopped animator allows native windowing system 'repaint' event
288 // to trigger GLAD 'display'
289 a1.stop();
290 Assert.assertEquals(false, a1.isAnimating());
291 a2.stop();
292 Assert.assertEquals(false, a2.isAnimating());
293 a3.stop();
294 Assert.assertEquals(false, a3.isAnimating());
295
296 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
297 public void run() {
298 try {
299 f3.dispose();
300 f2.dispose();
301 f1.dispose();
302 } catch (final Throwable t) {
303 throw new RuntimeException(t);
304 }
305 }});
306
307 Assert.assertTrue(AWTRobotUtil.waitForRealized(c1, false, null));
308 Assert.assertTrue(AWTRobotUtil.waitForRealized(c2, false, null));
309 Assert.assertTrue(AWTRobotUtil.waitForRealized(c3, false, null));
310 }
311
312 static long duration = 1000; // ms
313
314 public static void main(final String args[]) {
315 for(int i=0; i<args.length; i++) {
316 if(args[i].equals("-time")) {
317 i++;
318 try {
319 duration = Integer.parseInt(args[i]);
320 } catch (final Exception ex) { ex.printStackTrace(); }
321 }
322 }
323 /**
324 BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
325 System.err.println("Press enter to continue");
326 System.err.println(stdin.readLine()); */
327 org.junit.runner.JUnitCore.main(TestSharedContextVBOES2AWT3b.class.getName());
328 }
329}
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 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.
A lightweight Swing component which provides OpenGL rendering support.
Definition: GLJPanel.java:189
final void setSharedAutoDrawable(final GLAutoDrawable sharedAutoDrawable)
Specifies an GLAutoDrawable, which OpenGL context shall be shared by this GLAutoDrawable's GLContext.
Definition: GLJPanel.java:430
GLContext getContext()
Returns the context associated with this drawable.
Definition: GLJPanel.java:1133
void addGLEventListener(final GLEventListener listener)
Adds the given listener to the end of this drawable queue.
Definition: GLJPanel.java:989
Sharing the VBO of 3 GearsES2 instances, each in their own AWT GLJPanel.
GLJPanel createGLJPanel(final Frame frame, final int x, final int y, final GearsES2 gears)
boolean waitForInit(final boolean initialized)
Definition: GearsES2.java:187
static boolean waitForRealized(final java.awt.Component comp, final boolean realized, final Runnable waitAction)
static boolean waitForVisible(final java.awt.Component comp, final boolean visible, final Runnable waitAction)
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
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