JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
ExclusiveContextBase10.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.jogl.acore.ect;
30
31import com.jogamp.newt.NewtFactory;
32import com.jogamp.newt.Window;
33import com.jogamp.opengl.test.junit.util.GLTestUtil;
34import com.jogamp.opengl.test.junit.util.UITestCase;
35
36import com.jogamp.opengl.util.AnimatorBase;
37
38import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
39import com.jogamp.common.os.Platform;
40import com.jogamp.nativewindow.Capabilities;
41import com.jogamp.nativewindow.util.InsetsImmutable;
42
43import com.jogamp.opengl.GLAutoDrawable;
44import com.jogamp.opengl.GLCapabilities;
45import com.jogamp.opengl.GLCapabilitiesImmutable;
46import com.jogamp.opengl.GLProfile;
47
48import org.junit.Assert;
49import org.junit.BeforeClass;
50import org.junit.AfterClass;
51import org.junit.FixMethodOrder;
52import org.junit.Test;
53import org.junit.runners.MethodSorters;
54
55/**
56 * ExclusiveContextThread base implementation to test performance impact of the ExclusiveContext feature with AnimatorBase.
57 */
58@FixMethodOrder(MethodSorters.NAME_ASCENDING)
59public abstract class ExclusiveContextBase10 extends UITestCase {
60 static boolean testExclusiveWithAWT = false;
61 static long duration = 1400;
62
63 static boolean showFPS = false;
64 static int showFPSRate = 60;
65
66 static final int demoWinSize = 128;
67
68 static InsetsImmutable insets = null;
69 static int num_x, num_y;
70
71 static int swapInterval = 0;
72
73 @BeforeClass
74 public static void initClass00() {
75 final Window dummyWindow = NewtFactory.createWindow(new Capabilities());
76 dummyWindow.setSize(demoWinSize, demoWinSize);
77 dummyWindow.setVisible(true);
78 Assert.assertEquals(true, dummyWindow.isVisible());
79 Assert.assertEquals(true, dummyWindow.isNativeValid());
80 insets = dummyWindow.getInsets();
81 final int scrnHeight = dummyWindow.getScreen().getHeight();
82 final int scrnWidth = dummyWindow.getScreen().getWidth();
83 final int[] demoScreenSize = dummyWindow.convertToPixelUnits(new int[] { demoWinSize, demoWinSize });
84 final int[] insetsScreenSize = dummyWindow.convertToPixelUnits(new int[] { insets.getTotalWidth(), insets.getTotalHeight() });
85 num_x = scrnWidth / ( demoScreenSize[0] + insetsScreenSize[0] ) - 2;
86 num_y = scrnHeight / ( demoScreenSize[1] + insetsScreenSize[1] ) - 2;
87 dummyWindow.destroy();
88 }
89
90 @AfterClass
91 public static void releaseClass00() {
92 }
93
94 protected abstract boolean isAWTTestCase();
95 protected abstract Thread getAWTRenderThread();
96 protected abstract AnimatorBase createAnimator();
97 protected abstract GLAutoDrawable createGLAutoDrawable(String title, int x, int y, int width, int height, GLCapabilitiesImmutable caps);
98 protected abstract void setGLAutoDrawableVisible(GLAutoDrawable[] glads);
99 protected abstract void destroyGLAutoDrawableVisible(GLAutoDrawable glad);
100
101 /**
102 * @deprecated Use {@link #runTestGL(GLCapabilitiesImmutable,int,boolean,boolean)} instead
103 */
104 protected void runTestGL(final GLCapabilitiesImmutable caps, final int drawableCount, final boolean exclusive) throws InterruptedException {
105 runTestGL(caps, drawableCount, exclusive, false);
106 }
107
108 protected void runTestGL(final GLCapabilitiesImmutable caps, final int drawableCount, final boolean exclusive, final boolean preVisible) throws InterruptedException {
109 final boolean useAWTRenderThread = isAWTTestCase();
110 if( useAWTRenderThread && exclusive ) {
111 if( testExclusiveWithAWT ) {
112 System.err.println("Warning: Testing AWT + Exclusive -> Not advised!");
113 } else {
114 System.err.println("Info: Skip test: AWT + Exclusive!");
115 return;
116 }
117 }
118 if( useAWTRenderThread && exclusive && !testExclusiveWithAWT) {
119 System.err.println("Skip test: AWT + Exclusive -> Not advised!");
120 return;
121 }
122 final Thread awtRenderThread = getAWTRenderThread();
123 final AnimatorBase[] animators = new AnimatorBase[drawableCount];
124 final GLAutoDrawable[] drawables = new GLAutoDrawable[drawableCount];
125 for(int i=0; i<drawableCount; i++) {
126 animators[i] = createAnimator();
127 if( !useAWTRenderThread ) {
129 }
130
131 final int x = ( i % num_x ) * ( demoWinSize + insets.getTotalHeight() ) + insets.getLeftWidth();
132 final int y = ( (i / num_x) % num_y ) * ( demoWinSize + insets.getTotalHeight() ) + insets.getTopHeight();
133 drawables[i] = createGLAutoDrawable("Win #"+i, x, y, demoWinSize, demoWinSize, caps);
134 Assert.assertNotNull(drawables[i]);
135 final GearsES2 demo = new GearsES2(swapInterval);
136 demo.setVerbose(false);
137 drawables[i].addGLEventListener(demo);
138 }
139
140 if( preVisible ) {
141 setGLAutoDrawableVisible(drawables);
142
143 // Made visible, check if drawables are realized
144 for(int i=0; i<drawableCount; i++) {
145 Assert.assertEquals(true, drawables[i].isRealized());
146 animators[i].setUpdateFPSFrames(showFPSRate, showFPS ? System.err : null);
147 }
148 }
149
150 for(int i=0; i<drawableCount; i++) {
151 animators[i].add(drawables[i]);
152
153 if( exclusive ) {
154 if( useAWTRenderThread ) {
155 Assert.assertEquals(null, animators[i].setExclusiveContext(awtRenderThread));
156 } else {
157 Assert.assertEquals(false, animators[i].setExclusiveContext(true));
158 }
159 }
160 Assert.assertFalse(animators[i].isAnimating());
161 Assert.assertFalse(animators[i].isStarted());
162 }
163
164 // Animator Start
165 for(int i=0; i<drawableCount; i++) {
166 Assert.assertTrue(animators[i].start());
167
168 Assert.assertTrue(animators[i].isStarted());
169 Assert.assertTrue(animators[i].isAnimating());
170 Assert.assertEquals(exclusive, animators[i].isExclusiveContextEnabled());
171 }
172
173 // After start, ExclusiveContextThread is set
174 for(int i=0; i<drawableCount; i++) {
175 final Thread ect = animators[i].getExclusiveContextThread();
176 if(exclusive) {
177 if( useAWTRenderThread ) {
178 Assert.assertEquals(awtRenderThread, ect);
179 } else {
180 Assert.assertEquals(animators[i].getThread(), ect);
181 }
182 } else {
183 Assert.assertEquals(null, ect);
184 }
185 Assert.assertEquals(ect, drawables[i].getExclusiveContextThread());
186 }
187
188 if( !preVisible ) {
189 setGLAutoDrawableVisible(drawables);
190
191 // Made visible, check if drawables are realized
192 for(int i=0; i<drawableCount; i++) {
193 Assert.assertEquals(true, drawables[i].isRealized());
194 animators[i].setUpdateFPSFrames(showFPSRate, showFPS ? System.err : null);
195 }
196 }
197
198 // Normal run ..
199 Thread.sleep(duration);
200
201 // Animator Stop #2
202 for(int i=0; i<drawableCount; i++) {
203 Assert.assertTrue(animators[i].stop());
204 Assert.assertFalse(animators[i].isAnimating());
205 Assert.assertFalse(animators[i].isStarted());
206 Assert.assertFalse(animators[i].isPaused());
207 Assert.assertEquals(exclusive, animators[i].isExclusiveContextEnabled());
208 Assert.assertEquals(null, animators[i].getExclusiveContextThread());
209 }
210
211 // Destroy GLWindows
212 for(int i=0; i<drawableCount; i++) {
213 destroyGLAutoDrawableVisible(drawables[i]);
214 Assert.assertEquals(true, GLTestUtil.waitForRealized(drawables[i], false, null));
215 }
216 }
217
218 @Test
219 public void test01Normal_1WinPostVis() throws InterruptedException {
220 final GLProfile glp = GLProfile.getGL2ES2();
221 final GLCapabilities caps = new GLCapabilities( glp );
222 runTestGL(caps, 1 /* numWin */, false /* exclusive */, false /* preVisible */);
223 }
224
225 @Test
226 public void test03Excl_1WinPostVis() throws InterruptedException {
227 final GLProfile glp = GLProfile.getGL2ES2();
228 final GLCapabilities caps = new GLCapabilities( glp );
229 runTestGL(caps, 1 /* numWin */, true /* exclusive */, false /* preVisible */);
230 }
231
232 @Test
233 public void test05Normal_4WinPostVis() throws InterruptedException {
234 final GLProfile glp = GLProfile.getGL2ES2();
235 final GLCapabilities caps = new GLCapabilities( glp );
236 runTestGL(caps, 4 /* numWin */, false /* exclusive */, false /* preVisible */);
237 }
238
239 @Test
240 public void test07Excl_4WinPostVis() throws InterruptedException {
241 if( Platform.OSType.MACOS == Platform.getOSType() ) {
242 // Bug 1415 - MacOS 10.14.6 + OpenJDK11U occasional freezes having multiple Windows created on a ExclusiveContextThread
243 System.err.println("Disabled, see Bug 1415");
244 return;
245 }
246 final GLProfile glp = GLProfile.getGL2ES2();
247 final GLCapabilities caps = new GLCapabilities( glp );
248 runTestGL(caps, 4 /* numWin */, true /* exclusive */, false /* preVisible */);
249 }
250
251 @Test
252 public void test11Normal_1WinPreVis() throws InterruptedException {
253 final GLProfile glp = GLProfile.getGL2ES2();
254 final GLCapabilities caps = new GLCapabilities( glp );
255 runTestGL(caps, 1 /* numWin */, false /* exclusive */, true /* preVisible */);
256 }
257
258 @Test
259 public void test13Excl_1WinPreVis() throws InterruptedException {
260 final GLProfile glp = GLProfile.getGL2ES2();
261 final GLCapabilities caps = new GLCapabilities( glp );
262 runTestGL(caps, 1 /* numWin */, true /* exclusive */, true /* preVisible */);
263 }
264
265 @Test
266 public void test15Normal_4WinPreVis() throws InterruptedException {
267 final GLProfile glp = GLProfile.getGL2ES2();
268 final GLCapabilities caps = new GLCapabilities( glp );
269 runTestGL(caps, 4 /* numWin */, false /* exclusive */, true /* preVisible */);
270 }
271
272 @Test
273 public void test17Excl_4WinPreVis() throws InterruptedException {
274 final GLProfile glp = GLProfile.getGL2ES2();
275 final GLCapabilities caps = new GLCapabilities( glp );
276 runTestGL(caps, 4 /* numWin */, true /* exclusive */, true /* preVisible */);
277 }
278
279}
Specifies a set of capabilities that a window's rendering context must support, such as color depth p...
static Window createWindow(final CapabilitiesImmutable caps)
Create a top level Window entity on the default Display and default Screen.
abstract int getHeight()
abstract int getWidth()
Specifies a set of OpenGL capabilities.
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
static GLProfile getGL2ES2(final AbstractGraphicsDevice device)
Returns the GL2ES2 profile implementation, hence compatible w/ GL2ES2.
Definition: GLProfile.java:913
ExclusiveContextThread base implementation to test performance impact of the ExclusiveContext feature...
abstract GLAutoDrawable createGLAutoDrawable(String title, int x, int y, int width, int height, GLCapabilitiesImmutable caps)
void runTestGL(final GLCapabilitiesImmutable caps, final int drawableCount, final boolean exclusive)
abstract void setGLAutoDrawableVisible(GLAutoDrawable[] glads)
void runTestGL(final GLCapabilitiesImmutable caps, final int drawableCount, final boolean exclusive, final boolean preVisible)
static boolean waitForRealized(final GLAutoDrawable glad, final boolean realized, final Runnable waitAction)
Definition: GLTestUtil.java:91
Base implementation of GLAnimatorControl
static final int MODE_EXPECT_AWT_RENDERING_THREAD
If present in modeBits field and AWT is available, implementation is aware of the AWT EDT,...
final synchronized void setModeBits(final boolean enable, final int bitValues)
Enables or disables the given bitValues in this Animators modeBits.
final synchronized Thread getExclusiveContextThread()
Returns the exclusive context thread if isExclusiveContextEnabled() and isStarted(),...
final synchronized void add(final GLAutoDrawable drawable)
Adds a drawable to this animator's list of rendering drawables.
final void setUpdateFPSFrames(final int frames, final PrintStream out)
int[] convertToPixelUnits(final int[] windowUnitsAndResult)
Converts the given window units into pixel units in place.
InsetsImmutable getInsets()
Returns the insets defined as the width and height of the window decoration on the left,...
Immutable insets representing rectangular window decoration insets on all four edges in window units.
Specifying NEWT's Window functionality:
Definition: Window.java:115
void setSize(int width, int height)
Sets the size of the window's client area in window units, excluding decorations.
void setVisible(boolean visible)
Calls setVisible(true, visible), i.e.
void destroy()
Destroys this window incl.releasing all related resources.
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.
Specifies an immutable set of OpenGL capabilities.