From 0ffba122ea5c4b8cc247234ca9f48ccfcce833cd Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Tue, 20 May 2014 21:01:21 +0200 Subject: [PATCH] Bug 742 HiDPI: Add prelim HiDPI support to GLJPanel w/o API change and w/o fixing AWTPrintLifecycle DPI evaluation We also have to re-validating AWTPrintLifecycle's DPI semantics, since we currently are based on pixel dimension w/ 72 dpi! --- make/scripts/tests.sh | 9 ++- .../javax/media/opengl/awt/GLJPanel.java | 66 ++++++++++++++----- 2 files changed, 55 insertions(+), 20 deletions(-) diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index 7ceb836b06..6fbad332fb 100644 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -216,7 +216,8 @@ function jrun() { #D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Window.MouseEvent -Dnewt.debug.Window.KeyEvent" #D_ARGS="-Dnewt.debug.Window" #D_ARGS="-Xprof" - #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.Java2D -Djogl.debug.GLJPanel" + D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.Java2D -Djogl.debug.GLJPanel" + #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.Java2D -Djogl.debug.GLJPanel -Djogl.gljpanel.nohidpi" #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.Java2D -Djogl.debug.GLJPanel -Djogl.debug.GLJPanel.Viewport" #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.Java2D -Djogl.debug.GLJPanel -Djogl.gljpanel.noglsl" #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.Java2D -Djogl.debug.GLJPanel -Djogl.gljpanel.noglsl -Djogl.gljpanel.awtverticalflip" @@ -356,7 +357,9 @@ function testawtswt() { #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestOlympicES1NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestRedSquareES1NEWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT $* -#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelAWT $* +testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelAWT $* +#testawt com.jogamp.opengl.test.junit.jogl.awt.TestHiDPIBufferedImage01AWT $* +#testawt com.jogamp.opengl.test.junit.jogl.awt.TestHiDPIBufferedImage02AWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelsAWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NewtCanvasAWT $* @@ -751,7 +754,7 @@ function testawtswt() { #testnoawt com.jogamp.opengl.test.junit.graph.demos.ui.UINewtDemo01 $* #testnoawt com.jogamp.opengl.test.junit.graph.demos.GPUTextNewtDemo $* #testnoawt com.jogamp.opengl.test.junit.graph.demos.GPURegionNewtDemo $* -testnoawt com.jogamp.opengl.test.junit.graph.demos.GPUUISceneNewtDemo $* +#testnoawt com.jogamp.opengl.test.junit.graph.demos.GPUUISceneNewtDemo $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple $* diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index fbd923a3b7..8bcf97ba12 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -83,6 +83,7 @@ import javax.media.opengl.Threading; import javax.swing.JPanel; +import jogamp.nativewindow.jawt.JAWTUtil; import jogamp.opengl.Debug; import jogamp.opengl.GLContextImpl; import jogamp.opengl.GLDrawableFactoryImpl; @@ -174,6 +175,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing private static final boolean USE_GLSL_TEXTURE_RASTERIZER; private static final boolean SKIP_VERTICAL_FLIP_DEFAULT; + private static final boolean SKIP_HIDPI; + /** Indicates whether the Java 2D OpenGL pipeline is requested by user. */ private static final boolean java2dOGLEnabledByProp; @@ -189,6 +192,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing DEBUG_VIEWPORT = Debug.isPropertyDefined("jogl.debug.GLJPanel.Viewport", true); USE_GLSL_TEXTURE_RASTERIZER = !Debug.isPropertyDefined("jogl.gljpanel.noglsl", true); SKIP_VERTICAL_FLIP_DEFAULT = Debug.isPropertyDefined("jogl.gljpanel.noverticalflip", true); + SKIP_HIDPI = Debug.isPropertyDefined("jogl.gljpanel.nohidpi", true); boolean enabled = Debug.getBooleanProperty("sun.java2d.opengl", false); java2dOGLEnabledByProp = enabled && !Debug.isPropertyDefined("jogl.gljpanel.noogl", true); @@ -246,10 +250,12 @@ private static synchronized SingleAWTGLPixelBufferProvider getSingleAWTGLPixelBu // For handling reshape events lazily: reshapeWidth -> panelWidth -> backend.width private int reshapeWidth; private int reshapeHeight; + private int reshapeScale; // Width of the actual GLJPanel: reshapeWidth -> panelWidth -> backend.width private int panelWidth = 0; private int panelHeight = 0; + private int panelScale = 0; // These are always set to (0, 0) except when the Java2D / OpenGL // pipeline is active @@ -588,15 +594,20 @@ their reshape() method in order to function properly.

public void reshape(int x, int y, int width, int height) { super.reshape(x, y, width, height); + final int scale = getPixelScale(); + final int scaledWidth = scale * width; + final int scaledHeight = scale * height; if( DEBUG ) { - System.err.println(getThreadName()+": GLJPanel.reshape.0 "+this.getName()+" resize"+(printActive?"WithinPrint":"")+" [ this "+getWidth()+"x"+getHeight()+", panel "+ - panelWidth+"x"+panelHeight + + System.err.println(getThreadName()+": GLJPanel.reshape.0 "+this.getName()+" resize"+(printActive?"WithinPrint":"")+ + " [ this "+getWidth()+"x"+getHeight()+", pixelScale "+scale+ + ", panel "+panelWidth+"x"+panelHeight + ", reshape: " +reshapeWidth+"x"+reshapeHeight + - "] -> "+(printActive?"skipped":"") + width+"x"+height); + "] -> "+(printActive?"[skipped] ":"") + width+"x"+height+" * "+scale+" -> "+scaledWidth+"x"+scaledHeight); } if( !printActive ) { - reshapeWidth = width; - reshapeHeight = height; + reshapeWidth = scaledWidth; + reshapeHeight = scaledHeight; + reshapeScale = scale; handleReshape = true; } } @@ -711,17 +722,21 @@ public void run() { // trigger reshape, i.e. gl-viewport and -listener - this component might got resized! final int awtWidth = GLJPanel.this.getWidth(); final int awtHeight= GLJPanel.this.getHeight(); + final int scale = getPixelScale(); + final int scaledAWTWidth = scale * awtWidth; + final int scaledAWTHeight= scale * awtHeight; final GLDrawable drawable = GLJPanel.this.getDelegatedDrawable(); - if( awtWidth != panelWidth || awtHeight != panelHeight || + if( scaledAWTWidth != panelWidth || scaledAWTHeight != panelHeight || drawable.getWidth() != panelWidth || drawable.getHeight() != panelHeight ) { // -> !( awtSize == panelSize == drawableSize ) if ( DEBUG ) { - System.err.println(getThreadName()+": GLJPanel.releasePrintOnEDT.0: resizeWithinPrint panel " +panelWidth+"x"+panelHeight + + System.err.println(getThreadName()+": GLJPanel.releasePrintOnEDT.0: resizeWithinPrint panel " +panelWidth+"x"+panelHeight + " @ scale "+panelScale+ ", draw "+drawable.getWidth()+"x"+drawable.getHeight()+ - " -> " + awtWidth+"x"+awtHeight); + " -> " + awtWidth+"x"+awtHeight+" * "+scale+" -> "+scaledAWTWidth+"x"+scaledAWTHeight); } - reshapeWidth = awtWidth; - reshapeHeight = awtHeight; + reshapeWidth = scaledAWTWidth; + reshapeHeight = scaledAWTHeight; + reshapeScale = scale; sendReshape = handleReshape(); // reshapeSize -> panelSize, backend reshape w/ GL reshape } else { sendReshape = true; // only GL reshape @@ -1126,13 +1141,16 @@ private boolean initializeBackendImpl() { } if (DEBUG) { - System.err.println(getThreadName()+": GLJPanel.createAndInitializeBackend: " +panelWidth+"x"+panelHeight + " -> " + reshapeWidth+"x"+reshapeHeight); + System.err.println(getThreadName()+": GLJPanel.createAndInitializeBackend: " + + panelWidth+"x"+panelHeight+" @ scale "+panelScale + " -> " + + reshapeWidth+"x"+reshapeHeight+" @ scale "+reshapeScale); } // Pull down reshapeWidth and reshapeHeight into panelWidth and // panelHeight eagerly in order to complete initialization, and // force a reshape later panelWidth = reshapeWidth; panelHeight = reshapeHeight; + panelScale = reshapeScale; } if ( null == backend ) { @@ -1154,6 +1172,15 @@ private boolean initializeBackendImpl() { } } + protected final int getPixelScale() { + if( SKIP_HIDPI ) { + return 1; + } else { + final int s = JAWTUtil.getPixelScale(this); + return 0 < s ? s : 1; + } + } + @Override public WindowClosingMode getDefaultCloseOperation() { return awtWindowClosingProtocol.getDefaultCloseOperation(); @@ -1166,10 +1193,13 @@ public WindowClosingMode setDefaultCloseOperation(WindowClosingMode op) { private boolean handleReshape() { if (DEBUG) { - System.err.println(getThreadName()+": GLJPanel.handleReshape: " +panelWidth+"x"+panelHeight + " -> " + reshapeWidth+"x"+reshapeHeight); + System.err.println(getThreadName()+": GLJPanel.handleReshape: "+ + panelWidth+"x"+panelHeight+" @ scale "+panelScale + " -> " + + reshapeWidth+"x"+reshapeHeight+" @ scale "+reshapeScale); } panelWidth = reshapeWidth; panelHeight = reshapeHeight; + panelScale = reshapeScale; return backend.handleReshape(); } @@ -1204,7 +1234,7 @@ public void display(GLAutoDrawable drawable) { } if (sendReshape) { if (DEBUG) { - System.err.println(getThreadName()+": GLJPanel.display: reshape(" + viewportX + "," + viewportY + " " + panelWidth + "x" + panelHeight + ")"); + System.err.println(getThreadName()+": GLJPanel.display: reshape(" + viewportX + "," + viewportY + " " + panelWidth + "x" + panelHeight + " @ scale "+panelScale+")"); } helper.reshape(GLJPanel.this, viewportX, viewportY, panelWidth, panelHeight); sendReshape = false; @@ -1403,6 +1433,7 @@ class OffscreenBackend implements Backend { private final boolean useSingletonBuffer; private AWTGLPixelBuffer pixelBuffer; private BufferedImage alignedImage; + private int alignedImageScale; // One of these is used to store the read back pixels before storing // in the BufferedImage @@ -1643,7 +1674,7 @@ public final void postGL(Graphics g, boolean isDisplay) { System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0: "+GLJPanel.this.getName()+" pixelBufferProvider isSingletonBufferProvider "+useSingletonBuffer+", 0x"+Integer.toHexString(pixelBufferProvider.hashCode())+", "+pixelBufferProvider.getClass().getSimpleName()); System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0: "+GLJPanel.this.getName()+" pixelBuffer 0x"+Integer.toHexString(pixelBuffer.hashCode())+", "+pixelBuffer+", alignment "+alignment); System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0: "+GLJPanel.this.getName()+" flippedVertical "+flipVertical+", glslTextureRaster "+(null!=glslTextureRaster)); - System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0: "+GLJPanel.this.getName()+" panelSize "+panelWidth+"x"+panelHeight); + System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0: "+GLJPanel.this.getName()+" panelSize "+panelWidth+"x"+panelHeight+" @ scale "+panelScale); } } if( offscreenDrawable.getWidth() != panelWidth || offscreenDrawable.getHeight() != panelHeight ) { @@ -1653,8 +1684,9 @@ public final void postGL(Graphics g, boolean isDisplay) { panelWidth != alignedImage.getWidth() || panelHeight != alignedImage.getHeight() || !pixelBuffer.isDataBufferSource(alignedImage) ) { alignedImage = pixelBuffer.getAlignedImage(panelWidth, panelHeight); + alignedImageScale = panelScale; if(DEBUG) { - System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0: "+GLJPanel.this.getName()+" new alignedImage "+alignedImage.getWidth()+"x"+alignedImage.getHeight()+", "+alignedImage+", pixelBuffer "+pixelBuffer.width+"x"+pixelBuffer.height+", "+pixelBuffer); + System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0: "+GLJPanel.this.getName()+" new alignedImage "+alignedImage.getWidth()+"x"+alignedImage.getHeight()+" @ scale "+alignedImageScale+", "+alignedImage+", pixelBuffer "+pixelBuffer.width+"x"+pixelBuffer.height+", "+pixelBuffer); } } final IntBuffer readBackInts; @@ -1781,7 +1813,7 @@ public final void doPaintComponent(Graphics g) { System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.doPaintComponent.drawImage: - frameCount "+frameCount); } // Draw resulting image in one shot - g.drawImage(alignedImage, 0, 0, alignedImage.getWidth(), alignedImage.getHeight(), null); // Null ImageObserver since image data is ready. + g.drawImage(alignedImage, 0, 0, alignedImage.getWidth()/alignedImageScale, alignedImage.getHeight()/alignedImageScale, null); // Null ImageObserver since image data is ready. } frameCount++; } @@ -1803,7 +1835,7 @@ public final boolean handleReshape() { } } if (DEBUG) { - System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.handleReshape: " +panelWidth+"x"+panelHeight + " -> " + _drawable.getWidth()+"x"+_drawable.getHeight()); + System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.handleReshape: " +panelWidth+"x"+panelHeight + " @ scale "+panelScale + " -> " + _drawable.getWidth()+"x"+_drawable.getHeight()); } panelWidth = _drawable.getWidth(); panelHeight = _drawable.getHeight();