Jogamp
374c06514b3df79d61e235a146354b07f5d4b8af
[jogl.git] / src / test / com / jogamp / opengl / test / junit / jogl / demos / es2 / awt / TestGearsES2AWT.java
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
29 package com.jogamp.opengl.test.junit.jogl.demos.es2.awt;
30
31 import javax.media.nativewindow.ScalableSurface;
32 import javax.media.opengl.*;
33
34 import com.jogamp.opengl.util.Animator;
35
36 import javax.media.opengl.awt.GLCanvas;
37
38 import com.jogamp.common.os.Platform;
39 import com.jogamp.newt.event.awt.AWTKeyAdapter;
40 import com.jogamp.newt.event.awt.AWTWindowAdapter;
41 import com.jogamp.newt.event.KeyEvent;
42 import com.jogamp.newt.event.TraceKeyAdapter;
43 import com.jogamp.newt.event.TraceWindowAdapter;
44 import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
45 import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
46 import com.jogamp.opengl.test.junit.util.MiscUtils;
47 import com.jogamp.opengl.test.junit.util.UITestCase;
48 import com.jogamp.opengl.test.junit.util.QuitAdapter;
49
50 import java.awt.BorderLayout;
51 import java.awt.Button;
52 import java.awt.Component;
53 import java.awt.Container;
54 import java.awt.Dimension;
55 import java.awt.EventQueue;
56 import java.awt.Frame;
57 import java.awt.TextArea;
58 import java.awt.event.ComponentEvent;
59 import java.awt.event.ComponentListener;
60 import java.io.BufferedReader;
61 import java.io.IOException;
62 import java.io.InputStreamReader;
63 import java.lang.reflect.InvocationTargetException;
64
65 import org.junit.Assert;
66 import org.junit.Assume;
67 import org.junit.BeforeClass;
68 import org.junit.AfterClass;
69 import org.junit.Test;
70 import org.junit.FixMethodOrder;
71 import org.junit.runners.MethodSorters;
72
73 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
74 public class TestGearsES2AWT extends UITestCase {
75     public enum FrameLayout { None, TextOnBottom, BorderCenterSurrounded, DoubleBorderCenterSurrounded };
76     public enum ResizeBy { Component, Frame };
77
78     static long duration = 500; // ms
79     static int width = 640, height = 480;
80     static int xpos = 10, ypos = 10;
81     static FrameLayout frameLayout = FrameLayout.None;
82     static ResizeBy resizeBy = ResizeBy.Component;
83     static int[] reqSurfacePixelScale = new int[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE };
84
85     static boolean forceES2 = false;
86     static boolean forceGL3 = false;
87     static boolean manualTest = false;
88     static boolean shallUseOffscreenFBOLayer = false;
89     static boolean shallUseOffscreenPBufferLayer = false;
90     static boolean useMSAA = false;
91     static boolean useStencil = false;
92     static boolean shutdownRemoveGLCanvas = true;
93     static boolean shutdownDisposeFrame = true;
94     static boolean shutdownSystemExit = false;
95     static int swapInterval = 1;
96     static boolean exclusiveContext = false;
97     static boolean useAnimator = true;
98     static Thread awtEDT;
99     static java.awt.Dimension rwsize = null;
100
101     @BeforeClass
102     public static void initClass() {
103         try {
104             EventQueue.invokeAndWait(new Runnable() {
105                 public void run() {
106                     awtEDT = Thread.currentThread();
107                 } } );
108         } catch (Exception e) {
109             e.printStackTrace();
110             Assert.assertNull(e);
111         }
112     }
113
114     @AfterClass
115     public static void releaseClass() {
116     }
117
118     static void setComponentSize(final Frame frame, final Component comp, final java.awt.Dimension new_sz) {
119         try {
120             javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
121                 public void run() {
122                     comp.setMinimumSize(new_sz);
123                     comp.setPreferredSize(new_sz);
124                     comp.setSize(new_sz);
125                     if( null != frame ) {
126                         frame.pack();
127                     }
128                 } } );
129         } catch( Throwable throwable ) {
130             throwable.printStackTrace();
131             Assume.assumeNoException( throwable );
132         }
133     }
134     static void setFrameSize(final Frame frame, final boolean frameLayout, final java.awt.Dimension new_sz) {
135         try {
136             javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
137                 public void run() {
138                     frame.setSize(new_sz);
139                     if( frameLayout ) {
140                         frame.validate();
141                     }
142                 } } );
143         } catch( Throwable throwable ) {
144             throwable.printStackTrace();
145             Assume.assumeNoException( throwable );
146         }
147     }
148
149     static void setSize(final ResizeBy resizeBy, final Frame frame, final boolean frameLayout, final Component comp, final java.awt.Dimension new_sz) {
150         switch( resizeBy ) {
151             case Component:
152                 setComponentSize(frameLayout ? frame : null, comp, new_sz);
153                 break;
154             case Frame:
155                 setFrameSize(frame, frameLayout, new_sz);
156                 break;
157         }
158     }
159
160     private void setTitle(final Frame frame, final GLCanvas glc, final GLCapabilitiesImmutable caps) {
161         final String capsA = caps.isBackgroundOpaque() ? "opaque" : "transl";
162         final java.awt.Rectangle b = glc.getBounds();
163         frame.setTitle("GLCanvas["+capsA+"], swapI "+swapInterval+", win: ["+b.x+"/"+b.y+" "+b.width+"x"+b.height+"], pix: "+glc.getSurfaceWidth()+"x"+glc.getSurfaceHeight());
164     }
165
166     protected void runTestGL(final GLCapabilities caps, final ResizeBy resizeBy, FrameLayout frameLayout) throws InterruptedException, InvocationTargetException {
167         final Frame frame = new Frame("GearsES2 AWT Test");
168         Assert.assertNotNull(frame);
169
170         final GLCanvas glCanvas = new GLCanvas(caps);
171         Assert.assertNotNull(glCanvas);
172         setSize(resizeBy, frame, false, glCanvas, new Dimension(width, height));
173         final int[] valReqSurfacePixelScale = glCanvas.setSurfaceScale(new int[2], reqSurfacePixelScale);
174         frame.setLocation(xpos, ypos);
175
176         switch( frameLayout) {
177             case None:
178                 frame.add(glCanvas);
179                 break;
180             case TextOnBottom:
181                 final TextArea ta = new TextArea(2, 20);
182                 ta.append("0123456789");
183                 ta.append(Platform.getNewline());
184                 ta.append("Some Text");
185                 ta.append(Platform.getNewline());
186                 frame.setLayout(new BorderLayout());
187                 frame.add(ta, BorderLayout.SOUTH);
188                 frame.add(glCanvas, BorderLayout.CENTER);
189                 break;
190             case BorderCenterSurrounded:
191                 frame.setLayout(new BorderLayout());
192                 frame.add(new Button("NORTH"), BorderLayout.NORTH);
193                 frame.add(new Button("SOUTH"), BorderLayout.SOUTH);
194                 frame.add(new Button("EAST"), BorderLayout.EAST);
195                 frame.add(new Button("WEST"), BorderLayout.WEST);
196                 frame.add(glCanvas, BorderLayout.CENTER);
197                 break;
198             case DoubleBorderCenterSurrounded:
199                 Container c = new Container();
200                 c.setLayout(new BorderLayout());
201                 c.add(new Button("north"), BorderLayout.NORTH);
202                 c.add(new Button("south"), BorderLayout.SOUTH);
203                 c.add(new Button("east"), BorderLayout.EAST);
204                 c.add(new Button("west"), BorderLayout.WEST);
205                 c.add(glCanvas, BorderLayout.CENTER);
206
207                 frame.setLayout(new BorderLayout());
208                 frame.add(new Button("NORTH"), BorderLayout.NORTH);
209                 frame.add(new Button("SOUTH"), BorderLayout.SOUTH);
210                 frame.add(new Button("EAST"), BorderLayout.EAST);
211                 frame.add(new Button("WEST"), BorderLayout.WEST);
212                 frame.add(c, BorderLayout.CENTER);
213                 break;
214         }
215         setTitle(frame, glCanvas, caps);
216
217         frame.addComponentListener(new ComponentListener() {
218             @Override
219             public void componentResized(ComponentEvent e) {
220                 setTitle(frame, glCanvas, caps);
221             }
222
223             @Override
224             public void componentMoved(ComponentEvent e) {
225                 setTitle(frame, glCanvas, caps);
226             }
227
228             @Override
229             public void componentShown(ComponentEvent e) { }
230
231             @Override
232             public void componentHidden(ComponentEvent e) { }
233         });
234
235         final GearsES2 demo = new GearsES2(swapInterval);
236         glCanvas.addGLEventListener(demo);
237
238         final SnapshotGLEventListener snap = new SnapshotGLEventListener();
239         glCanvas.addGLEventListener(snap);
240
241         final Animator animator = useAnimator ? new Animator(glCanvas) : null;
242         if( useAnimator && exclusiveContext ) {
243             animator.setExclusiveContext(awtEDT);
244         }
245         final QuitAdapter quitAdapter = new QuitAdapter();
246         new AWTKeyAdapter(new TraceKeyAdapter(quitAdapter), glCanvas).addTo(glCanvas);
247         new AWTWindowAdapter(new TraceWindowAdapter(quitAdapter), glCanvas).addTo(frame);
248
249         final com.jogamp.newt.event.KeyListener kl = new com.jogamp.newt.event.KeyAdapter() {
250             @Override
251             public void keyPressed(final KeyEvent e) {
252                 if( e.isAutoRepeat() ) {
253                     return;
254                 }
255                 if(e.getKeyChar()=='x') {
256                     final int[] hadSurfacePixelScale = glCanvas.getSurfaceScale(new int[2]);
257                     final int[] reqSurfacePixelScale;
258                     if( hadSurfacePixelScale[0] == ScalableSurface.IDENTITY_PIXELSCALE ) {
259                         reqSurfacePixelScale = new int[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE };
260                     } else {
261                         reqSurfacePixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE };
262                     }
263                     System.err.println("[set PixelScale pre]: had "+hadSurfacePixelScale[0]+"x"+hadSurfacePixelScale[1]+" -> req "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]);
264                     final int[] valReqSurfacePixelScale = glCanvas.setSurfaceScale(new int[2], reqSurfacePixelScale);
265                     final int[] hasSurfacePixelScale0 = glCanvas.getNativeSurface().convertToPixelUnits(new int[] { 1, 1 });
266                     final int[] hasSurfacePixelScale1 = glCanvas.getSurfaceScale(new int[2]);
267                     System.err.println("[set PixelScale post]: "+hadSurfacePixelScale[0]+"x"+hadSurfacePixelScale[1]+" (had) -> "+
268                                        reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+
269                                        valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+
270                                        hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)");
271                     setTitle(frame, glCanvas, caps);
272                     Assert.assertArrayEquals(hasSurfacePixelScale0, hasSurfacePixelScale1);
273                 }
274             } };
275         new AWTKeyAdapter(kl, glCanvas).addTo(glCanvas);
276
277         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
278             public void run() {
279                if( ResizeBy.Frame == resizeBy ) {
280                    frame.validate();
281                } else {
282                    frame.pack();
283                }
284                frame.setVisible(true);
285             }});
286         Assert.assertEquals(true,  AWTRobotUtil.waitForVisible(frame, true));
287         Assert.assertEquals(true,  AWTRobotUtil.waitForRealized(glCanvas, true));
288
289         final int[] hasSurfacePixelScale0 = glCanvas.getNativeSurface().convertToPixelUnits(new int[] { 1, 1 });
290         final int[] hasSurfacePixelScale1 = glCanvas.getSurfaceScale(new int[2]);
291         System.err.println("HiDPI PixelScale: "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+
292                            valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+
293                            hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)");
294         setTitle(frame, glCanvas, caps);
295         Assert.assertArrayEquals(hasSurfacePixelScale0, hasSurfacePixelScale1);
296
297         if( useAnimator ) {
298             animator.start();
299             Assert.assertTrue(animator.isStarted());
300             Assert.assertTrue(animator.isAnimating());
301             Assert.assertEquals(exclusiveContext ? awtEDT : null, glCanvas.getExclusiveContextThread());
302             animator.setUpdateFPSFrames(60, System.err);
303         }
304
305         System.err.println("canvas pos/siz: "+glCanvas.getX()+"/"+glCanvas.getY()+" "+glCanvas.getSurfaceWidth()+"x"+glCanvas.getSurfaceHeight());
306
307         snap.setMakeSnapshot();
308
309         if( null != rwsize ) {
310             Thread.sleep(500); // 500ms delay
311             setSize(resizeBy, frame, true, glCanvas, rwsize);
312             System.err.println("window resize pos/siz: "+glCanvas.getX()+"/"+glCanvas.getY()+" "+glCanvas.getSurfaceWidth()+"x"+glCanvas.getSurfaceHeight());
313         }
314
315         snap.setMakeSnapshot();
316
317         final long t0 = System.currentTimeMillis();
318         long t1 = t0;
319         while(!quitAdapter.shouldQuit() && t1 - t0 < duration) {
320             Thread.sleep(100);
321             t1 = System.currentTimeMillis();
322         }
323
324         Assert.assertNotNull(frame);
325         Assert.assertNotNull(glCanvas);
326
327         if( useAnimator ) {
328             Assert.assertNotNull(animator);
329             Assert.assertEquals(exclusiveContext ? awtEDT : null, glCanvas.getExclusiveContextThread());
330             animator.stop();
331             Assert.assertFalse(animator.isAnimating());
332             Assert.assertFalse(animator.isStarted());
333             Assert.assertEquals(null, glCanvas.getExclusiveContextThread());
334         }
335
336         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
337             public void run() {
338                 frame.setVisible(false);
339             }});
340         Assert.assertEquals(false, frame.isVisible());
341         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
342             public void run() {
343                 if(shutdownRemoveGLCanvas) {
344                     frame.remove(glCanvas);
345                 }
346                 if(shutdownDisposeFrame) {
347                     frame.dispose();
348                 }
349                 if(shutdownSystemExit) {
350                     System.exit(0);
351                 }
352             }});
353     }
354
355     @Test
356     public void test01() throws InterruptedException, InvocationTargetException {
357         final GLProfile glp;
358         if(forceGL3) {
359             glp = GLProfile.get(GLProfile.GL3);
360         } else if(forceES2) {
361             glp = GLProfile.get(GLProfile.GLES2);
362         } else {
363             glp = GLProfile.getGL2ES2();
364         }
365         final GLCapabilities caps = new GLCapabilities(glp);
366         if(useMSAA) {
367             caps.setNumSamples(4);
368             caps.setSampleBuffers(true);
369         }
370         if(useStencil) {
371             caps.setStencilBits(1);
372         }
373         if(shallUseOffscreenFBOLayer) {
374             caps.setOnscreen(false);
375         }
376         if(shallUseOffscreenPBufferLayer) {
377             caps.setPBuffer(true);
378         }
379         runTestGL(caps, resizeBy, frameLayout);
380     }
381
382     @Test
383     public void test02_GLES2() throws InterruptedException, InvocationTargetException {
384         if(manualTest) return;
385
386         if( !GLProfile.isAvailable(GLProfile.GLES2) ) {
387             System.err.println("GLES2 n/a");
388             return;
389         }
390         final GLProfile glp = GLProfile.get(GLProfile.GLES2);
391         final GLCapabilities caps = new GLCapabilities( glp );
392         runTestGL(caps, resizeBy, frameLayout);
393     }
394
395     @Test
396     public void test03_GL3() throws InterruptedException, InvocationTargetException {
397         if(manualTest) return;
398
399         if( !GLProfile.isAvailable(GLProfile.GL3) ) {
400             System.err.println("GL3 n/a");
401             return;
402         }
403         final GLProfile glp = GLProfile.get(GLProfile.GL3);
404         final GLCapabilities caps = new GLCapabilities( glp );
405         runTestGL(caps, resizeBy, frameLayout);
406     }
407
408     @Test
409     public void test99_PixelScale1_DefaultNorm() throws InterruptedException, InvocationTargetException {
410         if( manualTest ) return;
411
412         reqSurfacePixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE;
413         reqSurfacePixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE;
414
415         GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES2());
416         runTestGL(caps, resizeBy, frameLayout);
417     }
418
419     public static void main(String args[]) {
420         boolean waitForKey = false;
421         int rw=-1, rh=-1;
422
423         for(int i=0; i<args.length; i++) {
424             if(args[i].equals("-time")) {
425                 i++;
426                 duration = MiscUtils.atol(args[i], duration);
427             } else if(args[i].equals("-width")) {
428                 i++;
429                 width = MiscUtils.atoi(args[i], width);
430             } else if(args[i].equals("-height")) {
431                 i++;
432                 height = MiscUtils.atoi(args[i], height);
433             } else if(args[i].equals("-x")) {
434                 i++;
435                 xpos = MiscUtils.atoi(args[i], xpos);
436             } else if(args[i].equals("-y")) {
437                 i++;
438                 ypos = MiscUtils.atoi(args[i], ypos);
439             } else if(args[i].equals("-rwidth")) {
440                 i++;
441                 rw = MiscUtils.atoi(args[i], rw);
442             } else if(args[i].equals("-rheight")) {
443                 i++;
444                 rh = MiscUtils.atoi(args[i], rh);
445             } else if(args[i].equals("-pixelScale")) {
446                 i++;
447                 final int pS = MiscUtils.atoi(args[i], reqSurfacePixelScale[0]);
448                 reqSurfacePixelScale[0] = pS;
449                 reqSurfacePixelScale[1] = pS;
450             } else if(args[i].equals("-layout")) {
451                 i++;
452                 frameLayout = FrameLayout.valueOf(args[i]);
453             } else if(args[i].equals("-resizeBy")) {
454                 i++;
455                 resizeBy = ResizeBy.valueOf(args[i]);
456             } else if(args[i].equals("-es2")) {
457                 forceES2 = true;
458             } else if(args[i].equals("-gl3")) {
459                 forceGL3 = true;
460             } else if(args[i].equals("-vsync")) {
461                 i++;
462                 swapInterval = MiscUtils.atoi(args[i], swapInterval);
463             } else if(args[i].equals("-exclctx")) {
464                 exclusiveContext = true;
465             } else if(args[i].equals("-noanim")) {
466                 useAnimator  = false;
467             } else if(args[i].equals("-layeredFBO")) {
468                 shallUseOffscreenFBOLayer = true;
469             } else if(args[i].equals("-layeredPBuffer")) {
470                 shallUseOffscreenPBufferLayer = true;
471             } else if(args[i].equals("-msaa")) {
472                 useMSAA = true;
473             } else if(args[i].equals("-stencil")) {
474                 useStencil = true;
475             } else if(args[i].equals("-wait")) {
476                 waitForKey = true;
477             } else if(args[i].equals("-shutdownKeepGLCanvas")) {
478                 shutdownRemoveGLCanvas = false;
479             } else if(args[i].equals("-shutdownKeepFrame")) {
480                 shutdownDisposeFrame = false;
481             } else if(args[i].equals("-shutdownKeepAll")) {
482                 shutdownRemoveGLCanvas = false;
483                 shutdownDisposeFrame = false;
484             } else if(args[i].equals("-shutdownSystemExit")) {
485                 shutdownSystemExit = true;
486             } else if(args[i].equals("-manual")) {
487                 manualTest = true;
488             }
489         }
490         if( 0 < rw && 0 < rh ) {
491             rwsize = new Dimension(rw, rh);
492         }
493
494         System.err.println("resize "+rwsize);
495         System.err.println("frameLayout "+frameLayout);
496         System.err.println("resizeBy "+resizeBy);
497         System.err.println("forceES2 "+forceES2);
498         System.err.println("forceGL3 "+forceGL3);
499         System.err.println("swapInterval "+swapInterval);
500         System.err.println("exclusiveContext "+exclusiveContext);
501         System.err.println("useMSAA "+useMSAA);
502         System.err.println("useAnimator "+useAnimator);
503
504         System.err.println("shallUseOffscreenFBOLayer     "+shallUseOffscreenFBOLayer);
505         System.err.println("shallUseOffscreenPBufferLayer "+shallUseOffscreenPBufferLayer);
506
507         if(waitForKey) {
508             BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
509             System.err.println("Press enter to continue");
510             try {
511                 System.err.println(stdin.readLine());
512             } catch (IOException e) { }
513         }
514         org.junit.runner.JUnitCore.main(TestGearsES2AWT.class.getName());
515     }
516 }
http://JogAmp.org git info: FAQ, tutorial and man pages.