From 2571ed0b5ef14155d204540d38b564a7d4cd47b6 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sun, 8 Jun 2014 08:11:57 +0200 Subject: Bug 741 HiDPI: Add ScalableSurface interface to get/set pixelScale w/ full OSX impl. Add ScalableSurface interface - To set pixelScale before and after realization - To get pixelScale - Implemented on: - NEWT Window - Generic impl. in WindowImpl - OSX WindowDriver impl. - Also propagetes pixelScale to parent JAWTWindow if offscreen (NewtCanvasAWT) - AWT WindowDriver impl. - JAWTWindow / OSXCalayer - AWT GLCanvas - AWT GLJPanel - NEWTCanvasAWT: - Propagates NEWT Window's pixelScale to underlying JAWTWindow - WrappedSurface for pixelScale propagation using offscreen drawables, i.e. GLJPanel - Generic helper in SurfaceScaleUtils (nativewindow package) - Fully implemented on OSX - Capable to switch pixelScale before realization, i.e. native-creation, as well as on-the-fly. - Impl. uses int[2] for pixelScale to support non-uniform scale. Test cases: - com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT - com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT - com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelAWT - com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT - Press 'x' to toggle HiDPI - Commandline '-pixelScale ' - Added basic auto unit test (setting pre-realization) --- .../junit/jogl/demos/es2/awt/TestGearsES2AWT.java | 54 +++++++ .../demos/es2/awt/TestGearsES2GLJPanelAWT.java | 64 +++++++- .../jogl/demos/es2/newt/TestGearsES2NEWT.java | 46 +++++- .../demos/es2/newt/TestGearsES2NewtCanvasAWT.java | 178 +++++++++++++++------ 4 files changed, 291 insertions(+), 51 deletions(-) (limited to 'src/test/com/jogamp/opengl') diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java index 622f51e45..3dbfeed8f 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java @@ -28,6 +28,7 @@ package com.jogamp.opengl.test.junit.jogl.demos.es2.awt; +import javax.media.nativewindow.ScalableSurface; import javax.media.opengl.*; import com.jogamp.opengl.util.Animator; @@ -37,6 +38,7 @@ import javax.media.opengl.awt.GLCanvas; import com.jogamp.common.os.Platform; import com.jogamp.newt.event.awt.AWTKeyAdapter; import com.jogamp.newt.event.awt.AWTWindowAdapter; +import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.TraceKeyAdapter; import com.jogamp.newt.event.TraceWindowAdapter; import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; @@ -78,6 +80,7 @@ public class TestGearsES2AWT extends UITestCase { static int xpos = 10, ypos = 10; static FrameLayout frameLayout = FrameLayout.None; static ResizeBy resizeBy = ResizeBy.Component; + static int[] reqSurfacePixelScale = new int[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE }; static boolean forceES2 = false; static boolean forceGL3 = false; @@ -167,6 +170,7 @@ public class TestGearsES2AWT extends UITestCase { final GLCanvas glCanvas = new GLCanvas(caps); Assert.assertNotNull(glCanvas); setSize(resizeBy, frame, false, glCanvas, new Dimension(width, height)); + glCanvas.setSurfaceScale(reqSurfacePixelScale); frame.setLocation(xpos, ypos); switch( frameLayout) { @@ -242,6 +246,33 @@ public class TestGearsES2AWT extends UITestCase { new AWTKeyAdapter(new TraceKeyAdapter(quitAdapter), glCanvas).addTo(glCanvas); new AWTWindowAdapter(new TraceWindowAdapter(quitAdapter), glCanvas).addTo(frame); + final com.jogamp.newt.event.KeyListener kl = new com.jogamp.newt.event.KeyAdapter() { + @Override + public void keyPressed(final KeyEvent e) { + if( e.isAutoRepeat() ) { + return; + } + if(e.getKeyChar()=='x') { + final int[] hadSurfacePixelScale = glCanvas.getSurfaceScale(new int[2]); + final int[] reqSurfacePixelScale; + if( hadSurfacePixelScale[0] == ScalableSurface.IDENTITY_PIXELSCALE ) { + reqSurfacePixelScale = new int[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE }; + } else { + reqSurfacePixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE }; + } + System.err.println("[set PixelScale pre]: had "+hadSurfacePixelScale[0]+"x"+hadSurfacePixelScale[1]+" -> req "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]); + glCanvas.setSurfaceScale(reqSurfacePixelScale); + final int[] hasSurfacePixelScale0 = glCanvas.getNativeSurface().convertToPixelUnits(new int[] { 1, 1 }); + final int[] hasSurfacePixelScale1 = glCanvas.getSurfaceScale(new int[2]); + System.err.println("[set PixelScale post]: "+hadSurfacePixelScale[0]+"x"+hadSurfacePixelScale[1]+" (had) -> "+ + reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+ + hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)"); + setTitle(frame, glCanvas, caps); + Assert.assertArrayEquals(hasSurfacePixelScale0, hasSurfacePixelScale1); + } + } }; + new AWTKeyAdapter(kl, glCanvas).addTo(glCanvas); + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { public void run() { if( ResizeBy.Frame == resizeBy ) { @@ -254,6 +285,13 @@ public class TestGearsES2AWT extends UITestCase { Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true)); Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glCanvas, true)); + final int[] hasSurfacePixelScale0 = glCanvas.getNativeSurface().convertToPixelUnits(new int[] { 1, 1 }); + final int[] hasSurfacePixelScale1 = glCanvas.getSurfaceScale(new int[2]); + System.err.println("HiDPI PixelScale: "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+ + hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)"); + setTitle(frame, glCanvas, caps); + Assert.assertArrayEquals(hasSurfacePixelScale0, hasSurfacePixelScale1); + if( useAnimator ) { animator.start(); Assert.assertTrue(animator.isStarted()); @@ -365,6 +403,17 @@ public class TestGearsES2AWT extends UITestCase { runTestGL(caps, resizeBy, frameLayout); } + @Test + public void test99_PixelScale1_DefaultNorm() throws InterruptedException, InvocationTargetException { + if( mainRun ) return; + + reqSurfacePixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE; + reqSurfacePixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE; + + GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES2()); + runTestGL(caps, resizeBy, frameLayout); + } + public static void main(String args[]) { boolean waitForKey = false; int rw=-1, rh=-1; @@ -392,6 +441,11 @@ public class TestGearsES2AWT extends UITestCase { } else if(args[i].equals("-rheight")) { i++; rh = MiscUtils.atoi(args[i], rh); + } else if(args[i].equals("-pixelScale")) { + i++; + final int pS = MiscUtils.atoi(args[i], reqSurfacePixelScale[0]); + reqSurfacePixelScale[0] = pS; + reqSurfacePixelScale[1] = pS; } else if(args[i].equals("-layout")) { i++; frameLayout = FrameLayout.valueOf(args[i]); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelAWT.java index 8172eb335..cfd099062 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelAWT.java @@ -35,6 +35,7 @@ import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.lang.reflect.InvocationTargetException; +import javax.media.nativewindow.ScalableSurface; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLProfile; @@ -50,12 +51,14 @@ import org.junit.Test; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; +import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.TraceKeyAdapter; import com.jogamp.newt.event.TraceWindowAdapter; import com.jogamp.newt.event.awt.AWTKeyAdapter; import com.jogamp.newt.event.awt.AWTWindowAdapter; import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; import com.jogamp.opengl.test.junit.util.MiscUtils; import com.jogamp.opengl.test.junit.util.QuitAdapter; import com.jogamp.opengl.test.junit.util.UITestCase; @@ -75,6 +78,7 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { static boolean manualTest = false; static boolean skipGLOrientationVerticalFlip = false; static int xpos = 10, ypos = 10; + static int[] reqSurfacePixelScale = new int[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE }; @BeforeClass public static void initClass() { @@ -120,6 +124,7 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { glJPanel.setMinimumSize(wsize); glJPanel.setPreferredSize(wsize); glJPanel.setSize(wsize); + glJPanel.setSurfaceScale(reqSurfacePixelScale); if( caps.isBitmap() || caps.getGLProfile().isGL2() ) { final Gears gears = new Gears(swapInterval); gears.setFlipVerticalInGLOrientation(skipGLOrientationVerticalFlip); @@ -161,6 +166,15 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { frame.pack(); frame.setVisible(true); } } ) ; + Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true)); + Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glJPanel, true)); + + final int[] hasSurfacePixelScale0 = glJPanel.getNativeSurface().convertToPixelUnits(new int[] { 1, 1 }); + final int[] hasSurfacePixelScale1 = glJPanel.getSurfaceScale(new int[2]); + System.err.println("HiDPI PixelScale: "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+ + hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)"); + setTitle(frame, glJPanel, caps); + Assert.assertArrayEquals(hasSurfacePixelScale0, hasSurfacePixelScale1); if( useAnimator ) { animator.setUpdateFPSFrames(60, System.err); @@ -172,6 +186,33 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { new AWTKeyAdapter(new TraceKeyAdapter(quitAdapter), glJPanel).addTo(glJPanel); new AWTWindowAdapter(new TraceWindowAdapter(quitAdapter), glJPanel).addTo(frame); + final com.jogamp.newt.event.KeyListener kl = new com.jogamp.newt.event.KeyAdapter() { + @Override + public void keyPressed(final KeyEvent e) { + if( e.isAutoRepeat() ) { + return; + } + if(e.getKeyChar()=='x') { + final int[] hadSurfacePixelScale = glJPanel.getSurfaceScale(new int[2]); + final int[] reqSurfacePixelScale; + if( hadSurfacePixelScale[0] == ScalableSurface.IDENTITY_PIXELSCALE ) { + reqSurfacePixelScale = new int[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE }; + } else { + reqSurfacePixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE }; + } + System.err.println("[set PixelScale pre]: had "+hadSurfacePixelScale[0]+"x"+hadSurfacePixelScale[1]+" -> req "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]); + glJPanel.setSurfaceScale(reqSurfacePixelScale); + final int[] hasSurfacePixelScale0 = glJPanel.getNativeSurface().convertToPixelUnits(new int[] { 1, 1 }); + final int[] hasSurfacePixelScale1 = glJPanel.getSurfaceScale(new int[2]); + System.err.println("[set PixelScale post]: "+hadSurfacePixelScale[0]+"x"+hadSurfacePixelScale[1]+" (had) -> "+ + reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+ + hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)"); + setTitle(frame, glJPanel, caps); + Assert.assertArrayEquals(hasSurfacePixelScale0, hasSurfacePixelScale1); + } + } }; + new AWTKeyAdapter(kl, glJPanel).addTo(glJPanel); + snap.setMakeSnapshot(); if( null != rwsize ) { @@ -198,11 +239,13 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { Assert.assertNotNull(frame); Assert.assertNotNull(glJPanel); - Assert.assertNotNull(animator); if( useAnimator ) { + Assert.assertNotNull(animator); animator.stop(); Assert.assertEquals(false, animator.isAnimating()); + } else { + Assert.assertNull(animator); } SwingUtilities.invokeAndWait(new Runnable() { public void run() { @@ -341,6 +384,20 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { runTestGL(caps); } + @Test + public void test99_PixelScale1_DefaultNorm() + throws AWTException, InterruptedException, InvocationTargetException + { + if( manualTest ) { + return; + } + reqSurfacePixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE; + reqSurfacePixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE; + + GLCapabilities caps = new GLCapabilities(GLProfile.getDefault()); + runTestGL(caps); + } + static long duration = 500; // ms public static void main(String args[]) { @@ -374,6 +431,11 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { } else if(args[i].equals("-rheight")) { i++; rh = MiscUtils.atoi(args[i], rh); + } else if(args[i].equals("-pixelScale")) { + i++; + final int pS = MiscUtils.atoi(args[i], reqSurfacePixelScale[0]); + reqSurfacePixelScale[0] = pS; + reqSurfacePixelScale[1] = pS; } else if(args[i].equals("-userVFlip")) { skipGLOrientationVerticalFlip = true; } else if(args[i].equals("-vsync")) { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java index bc6b5e26f..b916e21d6 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java @@ -29,6 +29,7 @@ package com.jogamp.opengl.test.junit.jogl.demos.es2.newt; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; import java.net.URLConnection; import com.jogamp.common.util.IOUtil; @@ -54,6 +55,7 @@ import com.jogamp.opengl.util.PNGPixelRect; import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; import javax.media.nativewindow.NativeWindowFactory; +import javax.media.nativewindow.ScalableSurface; import javax.media.nativewindow.util.Dimension; import javax.media.nativewindow.util.Point; import javax.media.nativewindow.util.PointImmutable; @@ -79,6 +81,7 @@ public class TestGearsES2NEWT extends UITestCase { static int screenIdx = 0; static PointImmutable wpos; static DimensionImmutable wsize, rwsize=null; + static int[] reqSurfacePixelScale = new int[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE }; static long duration = 500; // ms static boolean opaque = true; @@ -119,7 +122,7 @@ public class TestGearsES2NEWT extends UITestCase { private void setTitle(final Window win, final GLCapabilitiesImmutable caps) { final String capsA = caps.isBackgroundOpaque() ? "opaque" : "transl"; - win.setTitle("GLWindow["+capsA+"], swapI "+swapInterval+", win: "+win.getBounds()+", pix: "+win.getSurfaceBounds()); + win.setTitle("GLWindow["+capsA+"], swapI "+swapInterval+", win: "+win.getBounds()+", pix: "+win.getSurfaceWidth()+"x"+win.getSurfaceHeight()); } protected void runTestGL(final GLCapabilitiesImmutable caps, boolean undecorated) throws InterruptedException { System.err.println("requested: vsync "+swapInterval+", "+caps); @@ -127,6 +130,7 @@ public class TestGearsES2NEWT extends UITestCase { Screen screen = NewtFactory.createScreen(dpy, screenIdx); final GLWindow glWindow = GLWindow.create(screen, caps); Assert.assertNotNull(glWindow); + glWindow.setSurfaceScale(reqSurfacePixelScale); glWindow.setSize(wsize.getWidth(), wsize.getHeight()); if(null != wpos) { glWindow.setPosition(wpos.getX(), wpos.getY()); @@ -342,6 +346,23 @@ public class TestGearsES2NEWT extends UITestCase { System.err.println("[set mouse pos post]"); glWindow.setExclusiveContextThread(t); } }.start(); + } else if(e.getKeyChar()=='x') { + final int[] hadSurfacePixelScale = glWindow.getSurfaceScale(new int[2]); + final int[] reqSurfacePixelScale; + if( hadSurfacePixelScale[0] == ScalableSurface.IDENTITY_PIXELSCALE ) { + reqSurfacePixelScale = new int[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE }; + } else { + reqSurfacePixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE }; + } + System.err.println("[set PixelScale pre]: had "+hadSurfacePixelScale[0]+"x"+hadSurfacePixelScale[1]+" -> req "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]); + glWindow.setSurfaceScale(reqSurfacePixelScale); + final int[] hasSurfacePixelScale0 = glWindow.convertToPixelUnits(new int[] { 1, 1 }); + final int[] hasSurfacePixelScale1 = glWindow.getSurfaceScale(new int[2]); + System.err.println("[set PixelScale post]: "+hadSurfacePixelScale[0]+"x"+hadSurfacePixelScale[1]+" (had) -> "+ + reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+ + hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)"); + setTitle(glWindow, caps); + Assert.assertArrayEquals(hasSurfacePixelScale0, hasSurfacePixelScale1); } } }); @@ -414,6 +435,13 @@ public class TestGearsES2NEWT extends UITestCase { System.err.println("GL chosen: "+glWindow.getChosenCapabilities()); System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", "+glWindow.getInsets()); + final int[] hasSurfacePixelScale0 = glWindow.convertToPixelUnits(new int[] { 1, 1 }); + final int[] hasSurfacePixelScale1 = glWindow.getSurfaceScale(new int[2]); + System.err.println("HiDPI PixelScale: "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+ + hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)"); + setTitle(glWindow, caps); + Assert.assertArrayEquals(hasSurfacePixelScale0, hasSurfacePixelScale1); + snap.setMakeSnapshot(); if( null != rwsize ) { @@ -520,6 +548,17 @@ public class TestGearsES2NEWT extends UITestCase { runTestGL(caps, undecorated); } + @Test + public void test99_PixelScale1_DefaultNorm() throws InterruptedException, InvocationTargetException { + if( mainRun ) return; + + reqSurfacePixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE; + reqSurfacePixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE; + + GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES2()); + runTestGL(caps, undecorated); + } + public static void main(String args[]) throws IOException { mainRun = true; @@ -584,6 +623,11 @@ public class TestGearsES2NEWT extends UITestCase { i++; y = MiscUtils.atoi(args[i], y); usePos = true; + } else if(args[i].equals("-pixelScale")) { + i++; + final int pS = MiscUtils.atoi(args[i], reqSurfacePixelScale[0]); + reqSurfacePixelScale[0] = pS; + reqSurfacePixelScale[1] = pS; } else if(args[i].equals("-rwidth")) { i++; rw = MiscUtils.atoi(args[i], rw); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java index c7a00350b..d3e695659 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java @@ -3,14 +3,14 @@ * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR @@ -20,12 +20,12 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ - + package com.jogamp.opengl.test.junit.jogl.demos.es2.newt; import java.awt.BorderLayout; @@ -34,6 +34,8 @@ import java.awt.Component; import java.awt.Container; import java.awt.Frame; import java.awt.TextArea; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; import java.io.IOException; import java.lang.reflect.InvocationTargetException; @@ -41,7 +43,9 @@ import com.jogamp.common.os.Platform; import com.jogamp.newt.Display; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Screen; +import com.jogamp.newt.Window; import com.jogamp.newt.awt.NewtCanvasAWT; +import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.event.WindowAdapter; import com.jogamp.newt.opengl.GLWindow; @@ -53,6 +57,7 @@ import com.jogamp.opengl.util.Animator; import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; import com.jogamp.opengl.test.junit.newt.parenting.NewtAWTReparentingKeyAdapter; +import javax.media.nativewindow.ScalableSurface; import javax.media.nativewindow.util.Dimension; import javax.media.nativewindow.util.Point; import javax.media.nativewindow.util.PointImmutable; @@ -71,16 +76,17 @@ import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestGearsES2NewtCanvasAWT extends UITestCase { +public class TestGearsES2NewtCanvasAWT extends UITestCase { public enum FrameLayout { None, TextOnBottom, BorderBottom, BorderBottom2, BorderCenter, BorderCenterSurrounded, DoubleBorderCenterSurrounded }; public enum ResizeBy { GLWindow, Component, Frame }; - + static int screenIdx = 0; static PointImmutable wpos; static DimensionImmutable wsize, rwsize = null; static FrameLayout frameLayout = FrameLayout.None; static ResizeBy resizeBy = ResizeBy.Component; - + static int[] reqSurfacePixelScale = new int[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE }; + static long duration = 500; // ms static boolean opaque = true; static int forceAlpha = -1; @@ -96,7 +102,7 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { static boolean mainRun = false; static boolean exclusiveContext = false; static boolean useAnimator = true; - + @BeforeClass public static void initClass() { if(null == wsize) { @@ -120,7 +126,7 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { } catch( Throwable throwable ) { throwable.printStackTrace(); Assume.assumeNoException( throwable ); - } + } } static void setComponentSize(final Frame frame, final Component comp, final DimensionImmutable new_sz) { try { @@ -137,7 +143,7 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { } catch( Throwable throwable ) { throwable.printStackTrace(); Assume.assumeNoException( throwable ); - } + } } static void setFrameSize(final Frame frame, final boolean frameLayout, final DimensionImmutable new_sz) { try { @@ -152,9 +158,9 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { } catch( Throwable throwable ) { throwable.printStackTrace(); Assume.assumeNoException( throwable ); - } + } } - + static void setSize(final ResizeBy resizeBy, final Frame frame, final boolean frameLayout, final Component comp, final GLWindow glw, final DimensionImmutable new_sz) { switch( resizeBy ) { case GLWindow: @@ -166,9 +172,18 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { case Frame: setFrameSize(frame, frameLayout, new_sz); break; - } + } + } + + private void setTitle(final Frame frame, final NewtCanvasAWT glc, final Window win, final GLCapabilitiesImmutable caps) { + final String capsA = caps.isBackgroundOpaque() ? "opaque" : "transl"; + { + final java.awt.Rectangle b = glc.getBounds(); + frame.setTitle("NewtCanvasAWT["+capsA+"], swapI "+swapInterval+", win: ["+b.x+"/"+b.y+" "+b.width+"x"+b.height+"], pix: "+glc.getNativeWindow().getSurfaceWidth()+"x"+glc.getNativeWindow().getSurfaceHeight()); + } + win.setTitle("GLWindow["+capsA+"], swapI "+swapInterval+", win: "+win.getBounds()+", pix: "+win.getSurfaceWidth()+"x"+win.getSurfaceHeight()); } - + // public enum ResizeBy { GLWindow, Component, Frame }; protected void runTestGL(final GLCapabilitiesImmutable caps, final ResizeBy resizeBy, final FrameLayout frameLayout) throws InterruptedException, InvocationTargetException { System.err.println("requested: vsync "+swapInterval+", "+caps); @@ -176,14 +191,15 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { Screen screen = NewtFactory.createScreen(dpy, screenIdx); final GLWindow glWindow = GLWindow.create(screen, caps); Assert.assertNotNull(glWindow); - + glWindow.setSurfaceScale(reqSurfacePixelScale); + final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow); if ( shallUseOffscreenFBOLayer ) { newtCanvasAWT.setShallUseOffscreenLayer(true); } - + final Frame frame = new Frame("AWT Parent Frame"); - + setSize(resizeBy, frame, false, newtCanvasAWT, glWindow, wsize); switch( frameLayout) { @@ -199,7 +215,7 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { frame.setLayout(new BorderLayout()); frame.add(ta, BorderLayout.SOUTH); frame.add(newtCanvasAWT, BorderLayout.CENTER); - break; + break; case BorderBottom: frame.setLayout(new BorderLayout()); frame.add(newtCanvasAWT, BorderLayout.SOUTH); @@ -229,7 +245,7 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { c.add(new Button("east"), BorderLayout.EAST); c.add(new Button("west"), BorderLayout.WEST); c.add(newtCanvasAWT, BorderLayout.CENTER); - + frame.setLayout(new BorderLayout()); frame.add(new Button("NORTH"), BorderLayout.NORTH); frame.add(new Button("SOUTH"), BorderLayout.SOUTH); @@ -238,19 +254,35 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { frame.add(c, BorderLayout.CENTER); break; } - - frame.setTitle("Gears NewtCanvasAWT Test (translucent "+!caps.isBackgroundOpaque()+"), swapInterval "+swapInterval+", size "+wsize+", pos "+wpos); - + final GearsES2 demo = new GearsES2(swapInterval); demo.setPMVUseBackingArray(pmvUseBackingArray); glWindow.addGLEventListener(demo); - + + frame.addComponentListener(new ComponentListener() { + @Override + public void componentResized(ComponentEvent e) { + setTitle(frame, newtCanvasAWT, glWindow, caps); + } + + @Override + public void componentMoved(ComponentEvent e) { + setTitle(frame, newtCanvasAWT, glWindow, caps); + } + + @Override + public void componentShown(ComponentEvent e) { } + + @Override + public void componentHidden(ComponentEvent e) { } + }); + final Animator animator = useAnimator ? new Animator() : null; if( useAnimator ) { animator.setModeBits(false, Animator.MODE_EXPECT_AWT_RENDERING_THREAD); animator.setExclusiveContext(exclusiveContext); } - + final QuitAdapter quitAdapter = new QuitAdapter(); //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter)); //glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter)); @@ -263,11 +295,36 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { } public void windowMoved(WindowEvent e) { System.err.println("window moved: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()); - } + } }); - + glWindow.addKeyListener(new NewtAWTReparentingKeyAdapter(frame, newtCanvasAWT, glWindow, quitAdapter)); - + glWindow.addKeyListener(new com.jogamp.newt.event.KeyAdapter() { + @Override + public void keyPressed(final KeyEvent e) { + if( e.isAutoRepeat() ) { + return; + } + if(e.getKeyChar()=='x') { + final int[] hadSurfacePixelScale = glWindow.getSurfaceScale(new int[2]); + final int[] reqSurfacePixelScale; + if( hadSurfacePixelScale[0] == ScalableSurface.IDENTITY_PIXELSCALE ) { + reqSurfacePixelScale = new int[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE }; + } else { + reqSurfacePixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE }; + } + System.err.println("[set PixelScale pre]: had "+hadSurfacePixelScale[0]+"x"+hadSurfacePixelScale[1]+" -> req "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]); + glWindow.setSurfaceScale(reqSurfacePixelScale); + final int[] hasSurfacePixelScale0 = glWindow.convertToPixelUnits(new int[] { 1, 1 }); + final int[] hasSurfacePixelScale1 = glWindow.getSurfaceScale(new int[2]); + System.err.println("[set PixelScale post]: "+hadSurfacePixelScale[0]+"x"+hadSurfacePixelScale[1]+" (had) -> "+ + reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+ + hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)"); + setTitle(frame, newtCanvasAWT, glWindow, caps); + Assert.assertArrayEquals(hasSurfacePixelScale0, hasSurfacePixelScale1); + } + } } ); + if( useAnimator ) { animator.add(glWindow); animator.start(); @@ -281,28 +338,35 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { if( ResizeBy.Frame == resizeBy ) { frame.validate(); } else { - frame.pack(); - } - frame.setVisible(true); + frame.pack(); + } + frame.setVisible(true); } - }); + }); Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true)); - Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow, true)); - + Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow, true)); + if( useAnimator ) { animator.setUpdateFPSFrames(60, showFPS ? System.err : null); } - + System.err.println("NW chosen: "+glWindow.getDelegatedWindow().getChosenCapabilities()); System.err.println("GL chosen: "+glWindow.getChosenCapabilities()); System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", "+glWindow.getInsets()); - + + final int[] hasSurfacePixelScale0 = glWindow.convertToPixelUnits(new int[] { 1, 1 }); + final int[] hasSurfacePixelScale1 = glWindow.getSurfaceScale(new int[2]); + System.err.println("HiDPI PixelScale: "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+ + hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)"); + setTitle(frame, newtCanvasAWT, glWindow, caps); + Assert.assertArrayEquals(hasSurfacePixelScale0, hasSurfacePixelScale1); + if( null != rwsize ) { - Thread.sleep(500); // 500ms delay + Thread.sleep(500); // 500ms delay setSize(resizeBy, frame, true, newtCanvasAWT, glWindow, rwsize); System.err.println("window resize "+rwsize+" -> pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", "+glWindow.getInsets()); } - + final long t0 = System.currentTimeMillis(); long t1 = t0; while(!quitAdapter.shouldQuit() && t1-t0