Jogamp
Bug 741 HiDPI: Simplify ScalableSurface (2): Add request pixelScale API entry, fixed...
[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         glCanvas.setSurfaceScale(reqSurfacePixelScale);
174         final int[] valReqSurfacePixelScale = glCanvas.getRequestedSurfaceScale(new int[2]);
175         frame.setLocation(xpos, ypos);
176
177         switch( frameLayout) {
178             case None:
179                 frame.add(glCanvas);
180                 break;
181             case TextOnBottom:
182                 final TextArea ta = new TextArea(2, 20);
183                 ta.append("0123456789");
184                 ta.append(Platform.getNewline());
185                 ta.append("Some Text");
186                 ta.append(Platform.getNewline());
187                 frame.setLayout(new BorderLayout());
188                 frame.add(ta, BorderLayout.SOUTH);
189                 frame.add(glCanvas, BorderLayout.CENTER);
190                 break;
191             case BorderCenterSurrounded:
192                 frame.setLayout(new BorderLayout());
193                 frame.add(new Button("NORTH"), BorderLayout.NORTH);
194                 frame.add(new Button("SOUTH"), BorderLayout.SOUTH);
195                 frame.add(new Button("EAST"), BorderLayout.EAST);
196                 frame.add(new Button("WEST"), BorderLayout.WEST);
197                 frame.add(glCanvas, BorderLayout.CENTER);
198                 break;
199             case DoubleBorderCenterSurrounded:
200                 Container c = new Container();
201                 c.setLayout(new BorderLayout());
202                 c.add(new Button("north"), BorderLayout.NORTH);
203                 c.add(new Button("south"), BorderLayout.SOUTH);
204                 c.add(new Button("east"), BorderLayout.EAST);
205                 c.add(new Button("west"), BorderLayout.WEST);
206                 c.add(glCanvas, BorderLayout.CENTER);
207
208                 frame.setLayout(new BorderLayout());
209                 frame.add(new Button("NORTH"), BorderLayout.NORTH);
210                 frame.add(new Button("SOUTH"), BorderLayout.SOUTH);
211                 frame.add(new Button("EAST"), BorderLayout.EAST);
212                 frame.add(new Button("WEST"), BorderLayout.WEST);
213                 frame.add(c, BorderLayout.CENTER);
214                 break;
215         }
216         setTitle(frame, glCanvas, caps);
217
218         frame.addComponentListener(new ComponentListener() {
219             @Override
220             public void componentResized(ComponentEvent e) {
221                 setTitle(frame, glCanvas, caps);
222             }
223
224             @Override
225             public void componentMoved(ComponentEvent e) {
226                 setTitle(frame, glCanvas, caps);
227             }
228
229             @Override
230             public void componentShown(ComponentEvent e) { }
231
232             @Override
233             public void componentHidden(ComponentEvent e) { }
234         });
235
236         final GearsES2 demo = new GearsES2(swapInterval);
237         glCanvas.addGLEventListener(demo);
238
239         final SnapshotGLEventListener snap = new SnapshotGLEventListener();
240         glCanvas.addGLEventListener(snap);
241
242         final Animator animator = useAnimator ? new Animator(glCanvas) : null;
243         if( useAnimator && exclusiveContext ) {
244             animator.setExclusiveContext(awtEDT);
245         }
246         final QuitAdapter quitAdapter = new QuitAdapter();
247         new AWTKeyAdapter(new TraceKeyAdapter(quitAdapter), glCanvas).addTo(glCanvas);
248         new AWTWindowAdapter(new TraceWindowAdapter(quitAdapter), glCanvas).addTo(frame);
249
250         final com.jogamp.newt.event.KeyListener kl = new com.jogamp.newt.event.KeyAdapter() {
251             @Override
252             public void keyPressed(final KeyEvent e) {
253                 if( e.isAutoRepeat() ) {
254                     return;
255                 }
256                 if(e.getKeyChar()=='x') {
257                     final int[] hadSurfacePixelScale = glCanvas.getCurrentSurfaceScale(new int[2]);
258                     final int[] reqSurfacePixelScale;
259                     if( hadSurfacePixelScale[0] == ScalableSurface.IDENTITY_PIXELSCALE ) {
260                         reqSurfacePixelScale = new int[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE };
261                     } else {
262                         reqSurfacePixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE };
263                     }
264                     System.err.println("[set PixelScale pre]: had "+hadSurfacePixelScale[0]+"x"+hadSurfacePixelScale[1]+" -> req "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]);
265                     glCanvas.setSurfaceScale(reqSurfacePixelScale);
266                     final int[] valReqSurfacePixelScale = glCanvas.getRequestedSurfaceScale(new int[2]);
267                     final int[] hasSurfacePixelScale0 = glCanvas.getNativeSurface().convertToPixelUnits(new int[] { 1, 1 });
268                     final int[] hasSurfacePixelScale1 = glCanvas.getCurrentSurfaceScale(new int[2]);
269                     System.err.println("[set PixelScale post]: "+hadSurfacePixelScale[0]+"x"+hadSurfacePixelScale[1]+" (had) -> "+
270                                        reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+
271                                        valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+
272                                        hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)");
273                     setTitle(frame, glCanvas, caps);
274                     Assert.assertArrayEquals(hasSurfacePixelScale0, hasSurfacePixelScale1);
275                 }
276             } };
277         new AWTKeyAdapter(kl, glCanvas).addTo(glCanvas);
278
279         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
280             public void run() {
281                if( ResizeBy.Frame == resizeBy ) {
282                    frame.validate();
283                } else {
284                    frame.pack();
285                }
286                frame.setVisible(true);
287             }});
288         Assert.assertEquals(true,  AWTRobotUtil.waitForVisible(frame, true));
289         Assert.assertEquals(true,  AWTRobotUtil.waitForRealized(glCanvas, true));
290
291         final int[] hasSurfacePixelScale0 = glCanvas.getNativeSurface().convertToPixelUnits(new int[] { 1, 1 });
292         final int[] hasSurfacePixelScale1 = glCanvas.getCurrentSurfaceScale(new int[2]);
293         System.err.println("HiDPI PixelScale: "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+
294                            valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+
295                            hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)");
296         setTitle(frame, glCanvas, caps);
297         Assert.assertArrayEquals(hasSurfacePixelScale0, hasSurfacePixelScale1);
298
299         if( useAnimator ) {
300             animator.start();
301             Assert.assertTrue(animator.isStarted());
302             Assert.assertTrue(animator.isAnimating());
303             Assert.assertEquals(exclusiveContext ? awtEDT : null, glCanvas.getExclusiveContextThread());
304             animator.setUpdateFPSFrames(60, System.err);
305         }
306
307         System.err.println("canvas pos/siz: "+glCanvas.getX()+"/"+glCanvas.getY()+" "+glCanvas.getSurfaceWidth()+"x"+glCanvas.getSurfaceHeight());
308
309         snap.setMakeSnapshot();
310
311         if( null != rwsize ) {
312             Thread.sleep(500); // 500ms delay
313             setSize(resizeBy, frame, true, glCanvas, rwsize);
314             System.err.println("window resize pos/siz: "+glCanvas.getX()+"/"+glCanvas.getY()+" "+glCanvas.getSurfaceWidth()+"x"+glCanvas.getSurfaceHeight());
315         }
316
317         snap.setMakeSnapshot();
318
319         final long t0 = System.currentTimeMillis();
320         long t1 = t0;
321         while(!quitAdapter.shouldQuit() && t1 - t0 < duration) {
322             Thread.sleep(100);
323             t1 = System.currentTimeMillis();
324         }
325
326         Assert.assertNotNull(frame);
327         Assert.assertNotNull(glCanvas);
328
329         if( useAnimator ) {
330             Assert.assertNotNull(animator);
331             Assert.assertEquals(exclusiveContext ? awtEDT : null, glCanvas.getExclusiveContextThread());
332             animator.stop();
333             Assert.assertFalse(animator.isAnimating());
334             Assert.assertFalse(animator.isStarted());
335             Assert.assertEquals(null, glCanvas.getExclusiveContextThread());
336         }
337
338         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
339             public void run() {
340                 frame.setVisible(false);
341             }});
342         Assert.assertEquals(false, frame.isVisible());
343         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
344             public void run() {
345                 if(shutdownRemoveGLCanvas) {
346                     frame.remove(glCanvas);
347                 }
348                 if(shutdownDisposeFrame) {
349                     frame.dispose();
350                 }
351                 if(shutdownSystemExit) {
352                     System.exit(0);
353                 }
354             }});
355     }
356
357     @Test
358     public void test01() throws InterruptedException, InvocationTargetException {
359         final GLProfile glp;
360         if(forceGL3) {
361             glp = GLProfile.get(GLProfile.GL3);
362         } else if(forceES2) {
363             glp = GLProfile.get(GLProfile.GLES2);
364         } else {
365             glp = GLProfile.getGL2ES2();
366         }
367         final GLCapabilities caps = new GLCapabilities(glp);
368         if(useMSAA) {
369             caps.setNumSamples(4);
370             caps.setSampleBuffers(true);
371         }
372         if(useStencil) {
373             caps.setStencilBits(1);
374         }
375         if(shallUseOffscreenFBOLayer) {
376             caps.setOnscreen(false);
377         }
378         if(shallUseOffscreenPBufferLayer) {
379             caps.setPBuffer(true);
380         }
381         runTestGL(caps, resizeBy, frameLayout);
382     }
383
384     @Test
385     public void test02_GLES2() throws InterruptedException, InvocationTargetException {
386         if(manualTest) return;
387
388         if( !GLProfile.isAvailable(GLProfile.GLES2) ) {
389             System.err.println("GLES2 n/a");
390             return;
391         }
392         final GLProfile glp = GLProfile.get(GLProfile.GLES2);
393         final GLCapabilities caps = new GLCapabilities( glp );
394         runTestGL(caps, resizeBy, frameLayout);
395     }
396
397     @Test
398     public void test03_GL3() throws InterruptedException, InvocationTargetException {
399         if(manualTest) return;
400
401         if( !GLProfile.isAvailable(GLProfile.GL3) ) {
402             System.err.println("GL3 n/a");
403             return;
404         }
405         final GLProfile glp = GLProfile.get(GLProfile.GL3);
406         final GLCapabilities caps = new GLCapabilities( glp );
407         runTestGL(caps, resizeBy, frameLayout);
408     }
409
410     @Test
411     public void test99_PixelScale1_DefaultNorm() throws InterruptedException, InvocationTargetException {
412         if( manualTest ) return;
413
414         reqSurfacePixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE;
415         reqSurfacePixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE;
416
417         GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES2());
418         runTestGL(caps, resizeBy, frameLayout);
419     }
420
421     public static void main(String args[]) {
422         boolean waitForKey = false;
423         int rw=-1, rh=-1;
424
425         for(int i=0; i<args.length; i++) {
426             if(args[i].equals("-time")) {
427                 i++;
428                 duration = MiscUtils.atol(args[i], duration);
429             } else if(args[i].equals("-width")) {
430                 i++;
431                 width = MiscUtils.atoi(args[i], width);
432             } else if(args[i].equals("-height")) {
433                 i++;
434                 height = MiscUtils.atoi(args[i], height);
435             } else if(args[i].equals("-x")) {
436                 i++;
437                 xpos = MiscUtils.atoi(args[i], xpos);
438             } else if(args[i].equals("-y")) {
439                 i++;
440                 ypos = MiscUtils.atoi(args[i], ypos);
441             } else if(args[i].equals("-rwidth")) {
442                 i++;
443                 rw = MiscUtils.atoi(args[i], rw);
444             } else if(args[i].equals("-rheight")) {
445                 i++;
446                 rh = MiscUtils.atoi(args[i], rh);
447             } else if(args[i].equals("-pixelScale")) {
448                 i++;
449                 final int pS = MiscUtils.atoi(args[i], reqSurfacePixelScale[0]);
450                 reqSurfacePixelScale[0] = pS;
451                 reqSurfacePixelScale[1] = pS;
452             } else if(args[i].equals("-layout")) {
453                 i++;
454                 frameLayout = FrameLayout.valueOf(args[i]);
455             } else if(args[i].equals("-resizeBy")) {
456                 i++;
457                 resizeBy = ResizeBy.valueOf(args[i]);
458             } else if(args[i].equals("-es2")) {
459                 forceES2 = true;
460             } else if(args[i].equals("-gl3")) {
461                 forceGL3 = true;
462             } else if(args[i].equals("-vsync")) {
463                 i++;
464                 swapInterval = MiscUtils.atoi(args[i], swapInterval);
465             } else if(args[i].equals("-exclctx")) {
466                 exclusiveContext = true;
467             } else if(args[i].equals("-noanim")) {
468                 useAnimator  = false;
469             } else if(args[i].equals("-layeredFBO")) {
470                 shallUseOffscreenFBOLayer = true;
471             } else if(args[i].equals("-layeredPBuffer")) {
472                 shallUseOffscreenPBufferLayer = true;
473             } else if(args[i].equals("-msaa")) {
474                 useMSAA = true;
475             } else if(args[i].equals("-stencil")) {
476                 useStencil = true;
477             } else if(args[i].equals("-wait")) {
478                 waitForKey = true;
479             } else if(args[i].equals("-shutdownKeepGLCanvas")) {
480                 shutdownRemoveGLCanvas = false;
481             } else if(args[i].equals("-shutdownKeepFrame")) {
482                 shutdownDisposeFrame = false;
483             } else if(args[i].equals("-shutdownKeepAll")) {
484                 shutdownRemoveGLCanvas = false;
485                 shutdownDisposeFrame = false;
486             } else if(args[i].equals("-shutdownSystemExit")) {
487                 shutdownSystemExit = true;
488             } else if(args[i].equals("-manual")) {
489                 manualTest = true;
490             }
491         }
492         if( 0 < rw && 0 < rh ) {
493             rwsize = new Dimension(rw, rh);
494         }
495
496         System.err.println("resize "+rwsize);
497         System.err.println("frameLayout "+frameLayout);
498         System.err.println("resizeBy "+resizeBy);
499         System.err.println("forceES2 "+forceES2);
500         System.err.println("forceGL3 "+forceGL3);
501         System.err.println("swapInterval "+swapInterval);
502         System.err.println("exclusiveContext "+exclusiveContext);
503         System.err.println("useMSAA "+useMSAA);
504         System.err.println("useAnimator "+useAnimator);
505
506         System.err.println("shallUseOffscreenFBOLayer     "+shallUseOffscreenFBOLayer);
507         System.err.println("shallUseOffscreenPBufferLayer "+shallUseOffscreenPBufferLayer);
508
509         if(waitForKey) {
510             BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
511             System.err.println("Press enter to continue");
512             try {
513                 System.err.println(stdin.readLine());
514             } catch (IOException e) { }
515         }
516         org.junit.runner.JUnitCore.main(TestGearsES2AWT.class.getName());
517     }
518 }
http://JogAmp.org git info: FAQ, tutorial and man pages.