JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
TestParenting01dAWT.java
Go to the documentation of this file.
1/**
2 * Copyright 2013 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.newt.parenting;
30
31import org.junit.Assert;
32import org.junit.BeforeClass;
33import org.junit.Test;
34import org.junit.FixMethodOrder;
35import org.junit.runners.MethodSorters;
36
37import java.awt.Button;
38import java.awt.BorderLayout;
39import java.awt.Container;
40import java.awt.Frame;
41
42import com.jogamp.opengl.*;
43import javax.swing.SwingUtilities;
44
45import com.jogamp.common.os.Platform;
46import com.jogamp.junit.util.JunitTracer;
47import com.jogamp.newt.Window;
48import com.jogamp.newt.opengl.*;
49import com.jogamp.newt.awt.NewtCanvasAWT;
50
51import java.io.IOException;
52import java.lang.reflect.InvocationTargetException;
53
54import com.jogamp.opengl.test.junit.util.*;
55import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
56
57/**
58 * Test GL preservation case for reparenting.
59 * <p>
60 * Also simulates adding and attaching an already created GLWindow
61 * to a NewtCanvasAWT in recreation mode, where the GL state shall be preserved.
62 * </p>
63 */
64@FixMethodOrder(MethodSorters.NAME_ASCENDING)
65public class TestParenting01dAWT extends UITestCase {
66 static int width, height;
67 static long durationPerTest = 800;
68 static GLCapabilities glCaps;
69 static boolean manual_test = false;
70
71 @BeforeClass
72 public static void initClass() throws InterruptedException {
73 if( !manual_test ) {
74 if( Platform.OSType.LINUX == Platform.getOSType() ) {
75 JunitTracer.setTestSupported(false);
76 }
77 }
78 width = 640;
79 height = 480;
80 glCaps = new GLCapabilities(null);
81 // Thread.sleep(10000);
82 }
83
84 static class MyGLEventListenerCounter extends GLEventListenerCounter {
85 @Override
86 public void init(final GLAutoDrawable drawable) {
87 super.init(drawable);
88 System.err.println("MyGLEventListenerCounter.init: "+this);
89 // Thread.dumpStack();
90 }
91
92 @Override
93 public void dispose(final GLAutoDrawable drawable) {
94 super.dispose(drawable);
95 System.err.println("MyGLEventListenerCounter.dispose: "+this);
96 // Thread.dumpStack();
97 }
98 }
99
100 @Test
101 public void test01GLWindowReparentRecreateNoPreserve() throws InterruptedException, InvocationTargetException {
102 testGLWindowInvisibleReparentRecreateImpl(false /* triggerPreserveGLState */);
103 }
104
105 @Test
106 public void test02GLWindowReparentRecreateGLPreserve() throws InterruptedException, InvocationTargetException {
107 testGLWindowInvisibleReparentRecreateImpl(true /* triggerPreserveGLState */);
108 }
109
110 private void testGLWindowInvisibleReparentRecreateImpl(final boolean triggerPreserveGLState) throws InterruptedException, InvocationTargetException {
111 final GLWindow glWindow1 = GLWindow.create(glCaps);
112 Assert.assertNotNull(glWindow1);
113 Assert.assertEquals(false, glWindow1.isVisible());
114 Assert.assertEquals(false, glWindow1.isNativeValid());
115 Assert.assertNull(glWindow1.getParent());
116 glWindow1.setTitle("testWindowParenting01CreateVisibleDestroy");
117 final MyGLEventListenerCounter glelCounter = new MyGLEventListenerCounter();
118 glWindow1.addGLEventListener(glelCounter);
119 final GLEventListener demo1 = new RedSquareES2();
120 glWindow1.addGLEventListener(demo1);
121 Assert.assertEquals("Init Counter Invalid "+glelCounter, 0, glelCounter.initCount);
122
123 final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1);
124 Assert.assertNotNull(newtCanvasAWT);
125 Assert.assertEquals(false, glWindow1.isVisible());
126 Assert.assertEquals(false, glWindow1.isNativeValid());
127 Assert.assertNull(glWindow1.getParent());
128 Assert.assertEquals("Init Counter Invalid "+glelCounter, 0, glelCounter.initCount);
129
130 final Frame frame1 = new Frame("AWT Parent Frame");
131 frame1.setLayout(new BorderLayout());
132 frame1.add(new Button("North"), BorderLayout.NORTH);
133 frame1.add(new Button("South"), BorderLayout.SOUTH);
134 frame1.add(new Button("East"), BorderLayout.EAST);
135 frame1.add(new Button("West"), BorderLayout.WEST);
136
137 final Container container1 = new Container();
138 container1.setLayout(new BorderLayout());
139 container1.add(new Button("north"), BorderLayout.NORTH);
140 container1.add(new Button("south"), BorderLayout.SOUTH);
141 container1.add(new Button("east"), BorderLayout.EAST);
142 container1.add(new Button("west"), BorderLayout.WEST);
143 container1.add(newtCanvasAWT, BorderLayout.CENTER);
144
145 frame1.add(container1, BorderLayout.CENTER);
146
147 // visible test
148 SwingUtilities.invokeAndWait(new Runnable() {
149 @Override
150 public void run() {
151 frame1.setSize(width, height);
152 frame1.setVisible(true);
153 }
154 });
155 Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParent());
156
157 Assert.assertTrue(NewtTestUtil.waitForVisible(glWindow1, true, null));
158 Assert.assertTrue(NewtTestUtil.waitForRealized(glWindow1, true, null));
159 glWindow1.display();
160 Assert.assertEquals("Init Counter Invalid "+glelCounter, 1, glelCounter.initCount);
161 Assert.assertEquals("Dispose Counter Invalid "+glelCounter, 0, glelCounter.disposeCount);
162
163 final int reparentingHints = Window.REPARENT_HINT_FORCE_RECREATION |
164 ( triggerPreserveGLState ? Window.REPARENT_HINT_BECOMES_VISIBLE : 0 );
165
166 //
167 // Even though the hint REPARENT_HINT_BECOMES_VISIBLE is not set (triggerPrerveGLState == false),
168 // since GLWindow is visible already the GL state shall be preserved!
169 //
170 System.err.println(getSimpleTestName(".")+": Start Reparent #1");
171 final Window.ReparentOperation rop1 = glWindow1.reparentWindow(null, -1, -1, reparentingHints);
172 System.err.println(getSimpleTestName(".")+": Result Reparent #1: "+rop1);
173 Assert.assertEquals(Window.ReparentOperation.ACTION_NATIVE_CREATION, rop1);
174 glWindow1.display();
175 Assert.assertEquals("Init Counter Invalid (Preserve Failed 1) "+glelCounter, 1, glelCounter.initCount);
176 Assert.assertEquals("Dispose Counter Invalid (Preserve Failed 1) "+glelCounter, 0, glelCounter.disposeCount);
177
178 //
179 // The following step is equivalent with adding and attaching an already created GLWindow
180 // to a NewtCanvasAWT in recreation mode if REPARENT_HINT_BECOMES_VISIBLE hint is set (triggerPrerveGLState == true).
181 // GL state shall be preserved!
182 //
183 glWindow1.setVisible(false);
184 Assert.assertTrue(NewtTestUtil.waitForVisible(glWindow1, false, null));
185 System.err.println(getSimpleTestName(".")+": Start Reparent #2");
186 final Window.ReparentOperation rop2 = glWindow1.reparentWindow(newtCanvasAWT.getNativeWindow(), -1, -1, reparentingHints);
187 System.err.println(getSimpleTestName(".")+": Result Reparent #2: "+rop2);
188 Assert.assertEquals(Window.ReparentOperation.ACTION_NATIVE_CREATION, rop2);
189 glWindow1.setVisible(true);
190 Assert.assertTrue(NewtTestUtil.waitForVisible(glWindow1, true, null));
191 Assert.assertTrue(NewtTestUtil.waitForRealized(glWindow1, true, null));
192 glWindow1.display();
193 if( triggerPreserveGLState ) {
194 Assert.assertEquals("Init Counter Invalid (Preserve Failed 2) "+glelCounter, 1, glelCounter.initCount);
195 Assert.assertEquals("Dispose Counter Invalid (Preserve Failed 2) "+glelCounter, 0, glelCounter.disposeCount);
196 } else {
197 Assert.assertEquals("Init Counter Invalid (Preserve Failed 2) "+glelCounter, 2, glelCounter.initCount);
198 Assert.assertEquals("Dispose Counter Invalid (Preserve Failed 2) "+glelCounter, 1, glelCounter.disposeCount);
199 }
200
201 final long t0 = System.currentTimeMillis();
202 long t1 = t0;
203 while( t1 - t0 < durationPerTest ) {
204 Thread.sleep(100);
205 t1 = System.currentTimeMillis();
206 }
207
208 SwingUtilities.invokeAndWait(new Runnable() {
209 @Override
210 public void run() {
211 frame1.setVisible(false);
212 } } );
213 Assert.assertEquals(true, glWindow1.isNativeValid());
214
215 SwingUtilities.invokeAndWait(new Runnable() {
216 @Override
217 public void run() {
218 frame1.setVisible(true);
219 } } );
220 Assert.assertEquals(true, glWindow1.isNativeValid());
221
222 final boolean wasOnscreen = glWindow1.getChosenCapabilities().isOnscreen();
223
224 SwingUtilities.invokeAndWait(new Runnable() {
225 @Override
226 public void run() {
227 frame1.remove(newtCanvasAWT);
228 } } );
229 // Assert.assertNull(glWindow1.getParent());
230 if( wasOnscreen ) {
231 Assert.assertEquals(true, glWindow1.isNativeValid());
232 } // else OK to be destroyed - due to offscreen/onscreen transition
233
234 SwingUtilities.invokeAndWait(new Runnable() {
235 @Override
236 public void run() {
237 frame1.dispose();
238 } } );
239 if( wasOnscreen ) {
240 Assert.assertEquals(true, glWindow1.isNativeValid());
241 } // else OK to be destroyed - due to offscreen/onscreen transition
242
243 glWindow1.destroy();
244 Assert.assertEquals(false, glWindow1.isNativeValid());
245 if( triggerPreserveGLState ) {
246 Assert.assertEquals("Init Counter Invalid (Preserve Failed 1) "+glelCounter, 1, glelCounter.initCount);
247 Assert.assertEquals("Dispose Counter Invalid (Preserve Failed 1) "+glelCounter, 1, glelCounter.disposeCount);
248 } else {
249 Assert.assertEquals("Init Counter Invalid (Preserve Failed 1) "+glelCounter, 2, glelCounter.initCount);
250 Assert.assertEquals("Dispose Counter Invalid (Preserve Failed 1) "+glelCounter, 2, glelCounter.disposeCount);
251 }
252 }
253
254 public static void main(final String args[]) throws IOException {
255 manual_test = true;
256 for(int i=0; i<args.length; i++) {
257 if(args[i].equals("-time")) {
258 durationPerTest = MiscUtils.atol(args[++i], durationPerTest);
259 }
260 }
261 final String tstname = TestParenting01dAWT.class.getName();
262 org.junit.runner.JUnitCore.main(tstname);
263 }
264
265}
AWT Canvas containing a NEWT Window using native parenting.
NativeWindow getNativeWindow()
Returns the associated NativeWindow of this NativeWindowHolder, which is identical to getNativeSurfac...
An implementation of GLAutoDrawable and Window interface, using a delegated Window instance,...
Definition: GLWindow.java:121
final NativeWindow getParent()
Definition: GLWindow.java:282
final ReparentOperation reparentWindow(final NativeWindow newParent, final int x, final int y, final int hints)
Change this window's parent window.
Definition: GLWindow.java:582
final void setTitle(final String title)
Definition: GLWindow.java:297
final void setVisible(final boolean visible)
Calls setVisible(true, visible), i.e.
Definition: GLWindow.java:615
final CapabilitiesImmutable getChosenCapabilities()
Gets an immutable set of chosen capabilities.
Definition: GLWindow.java:266
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.
void init(final GLAutoDrawable drawable)
Called by the drawable immediately after the OpenGL context is initialized.
static long atol(final String str, final long def)
Definition: MiscUtils.java:66
static boolean waitForRealized(final Screen screen, final boolean realized, final Runnable waitAction)
static boolean waitForVisible(final Window win, final boolean visible, final Runnable waitAction)
Reparenting operation types.
Definition: Window.java:894
ACTION_NATIVE_CREATION
Native window creation after tree change - instead of reparenting.
Definition: Window.java:905
boolean isOnscreen()
Returns whether an on- or offscreen surface is requested, available or chosen.
Specifying NEWT's Window functionality:
Definition: Window.java:115
A higher-level abstraction than GLDrawable which supplies an event based mechanism (GLEventListener) ...
void addGLEventListener(GLEventListener listener)
Adds the given listener to the end of this drawable queue.
Declares events which client code can use to manage OpenGL rendering into a GLAutoDrawable.