JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
TestParenting04SWT.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.newt.parenting;
30
31import java.io.IOException;
32import java.lang.reflect.InvocationTargetException;
33
34import com.jogamp.opengl.GLCapabilities;
35import com.jogamp.opengl.GLEventListener;
36
37import org.eclipse.swt.SWT;
38import org.eclipse.swt.layout.FillLayout;
39import org.eclipse.swt.widgets.Composite;
40import org.eclipse.swt.widgets.Display;
41import org.eclipse.swt.widgets.Shell;
42import org.junit.After;
43import org.junit.Assert;
44import org.junit.Assume;
45import org.junit.Before;
46import org.junit.BeforeClass;
47import org.junit.Test;
48import org.junit.FixMethodOrder;
49import org.junit.runners.MethodSorters;
50
51import com.jogamp.nativewindow.swt.SWTAccessor;
52import com.jogamp.newt.NewtFactory;
53import com.jogamp.newt.Window;
54import com.jogamp.newt.opengl.GLWindow;
55import com.jogamp.newt.swt.NewtCanvasSWT;
56import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
57import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
58import com.jogamp.opengl.test.junit.jogl.demos.es2.swt.TestGearsES2SWT;
59import com.jogamp.opengl.test.junit.util.MiscUtils;
60import com.jogamp.opengl.test.junit.util.SWTTestUtil;
61import com.jogamp.opengl.test.junit.util.UITestCase;
62import com.jogamp.opengl.util.Animator;
63
64/**
65 * Using {@link NewtCanvasSWT#setNEWTChild(Window)} for reparenting, i.e. NEWT/AWT hopping
66 */
67@FixMethodOrder(MethodSorters.NAME_ASCENDING)
68public class TestParenting04SWT extends UITestCase {
69 static int width, height;
70 static long durationPerTest = 800;
71 static GLCapabilities glCaps;
72
73 Display display = null;
74 Shell shell1 = null;
75 Shell shell2 = null;
76 Composite composite1 = null;
77 Composite composite2 = null;
78 com.jogamp.newt.Display swtNewtDisplay = null;
79
80 @BeforeClass
81 public static void initClass() {
82 width = 400;
83 height = 400;
84 glCaps = new GLCapabilities(null);
85 }
86
87 @Before
88 public void init() {
89 SWTAccessor.invokeOnOSTKThread(true, new Runnable() {
90 public void run() {
91 display = new Display();
92 Assert.assertNotNull( display );
93
94 shell1 = new Shell( display );
95 Assert.assertNotNull( shell1 );
96 shell1.setLayout( new FillLayout() );
97 composite1 = new Composite( shell1, SWT.NONE );
98 composite1.setLayout( new FillLayout() );
99 Assert.assertNotNull( composite1 );
100
101 shell2 = new Shell( display );
102 Assert.assertNotNull( shell2 );
103 shell2.setLayout( new FillLayout() );
104 composite2 = new Composite( shell2, SWT.NONE );
105 composite2.setLayout( new FillLayout() );
106 Assert.assertNotNull( composite2 );
107 }});
108 swtNewtDisplay = NewtFactory.createDisplay(null, false); // no-reuse
109 }
110
111 @After
112 public void release() {
113 Assert.assertNotNull( display );
114 Assert.assertNotNull( shell1 );
115 Assert.assertNotNull( shell2 );
116 Assert.assertNotNull( composite1 );
117 Assert.assertNotNull( composite2 );
118 try {
119 SWTAccessor.invokeOnOSTKThread(true, new Runnable() {
120 public void run() {
121 composite1.dispose();
122 composite2.dispose();
123 shell1.dispose();
124 shell2.dispose();
125 display.dispose();
126 }});
127 }
128 catch( final Throwable throwable ) {
129 throwable.printStackTrace();
130 Assume.assumeNoException( throwable );
131 }
132 swtNewtDisplay = null;
133 display = null;
134 shell1 = null;
135 shell2 = null;
136 composite1 = null;
137 composite2 = null;
138 }
139
140 @Test
141 public void test01WinHopFrame2FrameDirectHop() throws InterruptedException, InvocationTargetException {
142 // Will produce some artifacts .. resizing etc
143 winHopFrame2Frame(false);
144 }
145
146 @Test
147 public void test02WinHopFrame2FrameDetachFirst() throws InterruptedException, InvocationTargetException {
148 // Note: detaching first setNEWTChild(null) is much cleaner visually
149 winHopFrame2Frame(true);
150 }
151
152 protected void winHopFrame2Frame(final boolean detachFirst) throws InterruptedException, InvocationTargetException {
153 final com.jogamp.newt.Screen screen = NewtFactory.createScreen(swtNewtDisplay, 0);
154
155 final GLWindow glWindow1 = GLWindow.create(screen, glCaps);
156 final GLEventListener demo1 = new RedSquareES2();
157 setDemoFields(demo1, glWindow1, false);
158 glWindow1.addGLEventListener(demo1);
159 final Animator anim1 = new Animator(glWindow1);
160
161 final GLWindow glWindow2 = GLWindow.create(screen, glCaps);
162 final GLEventListener demo2 = new GearsES2();
163 setDemoFields(demo2, glWindow2, false);
164 glWindow2.addGLEventListener(demo2);
165 final Animator anim2 = new Animator(glWindow2);
166
167 final NewtCanvasSWT canvas1 = NewtCanvasSWT.create( composite1, 0, glWindow1 );
168 final NewtCanvasSWT canvas2 = NewtCanvasSWT.create( composite2, 0, glWindow2 );
169
170 SWTAccessor.invokeOnSWTThread(display, true, new Runnable() {
171 public void run() {
172 shell1.setText( getSimpleTestName(".")+"-Win1" );
173 shell1.setSize( width, height);
174 shell1.setLocation(0, 0);
175 shell1.open();
176 shell2.setText( getSimpleTestName(".")+"-Win2" );
177 shell2.setSize( width, height);
178 shell2.setLocation(width + 50, 0);
179 shell2.open();
180 }
181 });
182 Assert.assertEquals(canvas1.getNativeWindow(),glWindow1.getParent());
183 Assert.assertEquals(canvas2.getNativeWindow(),glWindow2.getParent());
184
185 anim1.start();
186 anim2.start();
187
188 final SWTTestUtil.WaitAction waitAction = new SWTTestUtil.WaitAction(display, true, 16);
189 int state;
190 for(state=0; state<3; state++) {
191 for(int i=0; i*10<durationPerTest; i++) {
192 waitAction.run();
193 }
194 switch(state) {
195 case 0:
196 SWTAccessor.invokeOnSWTThread(display, true, new Runnable() {
197 public void run() {
198 // 1 -> 2
199 if(detachFirst) {
200 canvas1.setNEWTChild(null);
201 canvas2.setNEWTChild(null);
202 } else {
203 canvas2.setNEWTChild(null); // free g2 of w2
204 }
205 canvas1.setNEWTChild(glWindow2); // put g2 -> w1. free g1 of w1
206 canvas2.setNEWTChild(glWindow1); // put g1 -> w2
207 } } );
208 break;
209 case 1:
210 SWTAccessor.invokeOnSWTThread(display, true, new Runnable() {
211 public void run() {
212 // 2 -> 1
213 if(detachFirst) {
214 canvas1.setNEWTChild(null);
215 canvas2.setNEWTChild(null);
216 } else {
217 canvas2.setNEWTChild(null);
218 }
219 canvas1.setNEWTChild(glWindow1);
220 canvas2.setNEWTChild(glWindow2);
221 } } );
222 break;
223 }
224 }
225
226 SWTAccessor.invokeOnSWTThread(display, true, new Runnable() {
227 public void run() {
228 canvas1.dispose();
229 canvas2.dispose();
230 } } );
231 Assert.assertEquals(false, glWindow1.isNativeValid());
232 Assert.assertEquals(false, glWindow2.isNativeValid());
233 }
234
235 public static void setDemoFields(final GLEventListener demo, final GLWindow glWindow, final boolean debug) {
236 Assert.assertNotNull(demo);
237 Assert.assertNotNull(glWindow);
238 final Window window = glWindow.getDelegatedWindow();
239 if(debug) {
240 MiscUtils.setFieldIfExists(demo, "glDebug", true);
241 MiscUtils.setFieldIfExists(demo, "glTrace", true);
242 }
243 if(!MiscUtils.setFieldIfExists(demo, "window", window)) {
244 MiscUtils.setFieldIfExists(demo, "glWindow", glWindow);
245 }
246 }
247
248 static int atoi(final String a) {
249 int i=0;
250 try {
251 i = Integer.parseInt(a);
252 } catch (final Exception ex) { ex.printStackTrace(); }
253 return i;
254 }
255
256 public static void main(final String args[]) throws IOException {
257 for(int i=0; i<args.length; i++) {
258 if(args[i].equals("-time")) {
259 durationPerTest = atoi(args[++i]);
260 }
261 }
262 org.junit.runner.JUnitCore.main(TestParenting04SWT.class.getName());
263 }
264
265}
static void invokeOnOSTKThread(final boolean blocking, final Runnable runnable)
Runs the specified action in an SWT compatible OS toolkit thread, which is:
static void invokeOnSWTThread(final org.eclipse.swt.widgets.Display display, final boolean blocking, final Runnable runnable)
Runs the specified action on the SWT UI thread.
static Display createDisplay(final String name)
Create a Display entity.
static Screen createScreen(final Display display, final int index)
Create a Screen entity.
A screen may span multiple MonitorDevices representing their combined virtual size.
Definition: Screen.java:58
An implementation of GLAutoDrawable and Window interface, using a delegated Window instance,...
Definition: GLWindow.java:121
final NativeWindow getParent()
Definition: GLWindow.java:282
final Window getDelegatedWindow()
If the implementation uses delegation, return the delegated Window instance, otherwise return this in...
Definition: GLWindow.java:277
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
SWT Canvas containing a NEWT Window using native parenting.
NativeWindow getNativeWindow()
Returns the associated NativeWindow of this NativeWindowHolder, which is identical to getNativeSurfac...
static NewtCanvasSWT create(final Composite parent, final int style, final Window child)
Creates an instance using NewtCanvasSWT(Composite, int, Window) on the SWT thread.
void dispose()
Destroys this resource:
Window setNEWTChild(final Window newChild)
Sets a new NEWT child, provoking reparenting.
Specifies a set of OpenGL capabilities.
Using NewtCanvasSWT#setNEWTChild(Window) for reparenting, i.e.
static void setDemoFields(final GLEventListener demo, final GLWindow glWindow, final boolean debug)
static boolean setFieldIfExists(final Object instance, final String fieldName, final Object value)
Definition: MiscUtils.java:193
final synchronized boolean start()
Starts this animator, if not running.
Definition: Animator.java:344
Specifying NEWT's Window functionality:
Definition: Window.java:115
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.