diff options
5 files changed, 107 insertions, 45 deletions
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index 73fa54f38..8fb6c20c6 100755 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -135,7 +135,7 @@ function jrun() { #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable" #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.X11Util" #D_ARGS="-Djogl.debug.GLDrawable" - D_ARGS="-Dnewt.debug.Screen" + #D_ARGS="-Dnewt.debug.Screen" #D_ARGS="-Dnewt.test.Screen.disableRandR13" #D_ARGS="-Dnewt.test.Screen.disableScreenMode -Dnewt.debug.Screen" #D_ARGS="-Dnewt.debug.Screen -Djogl.debug.Animator" @@ -282,9 +282,9 @@ function testawtswt() { #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.TestGearsES2GLJPanelsAWT $* +testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelsAWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT $* -testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* #testawtswt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasSWT $* #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/com/jogamp/opengl/util/GLPixelBuffer.java b/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java index b2e0af2b5..6b9d3bf2c 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java @@ -74,6 +74,18 @@ public class GLPixelBuffer { */ GLPixelBuffer allocate(GL gl, GLPixelAttributes pixelAttributes, int width, int height, int depth, boolean pack, int minByteSize); } + + /** Single {@link GLPixelBuffer} provider. */ + public static interface SingletonGLPixelBufferProvider extends GLPixelBufferProvider { + /** Return the last {@link #allocate(GL, GLPixelAttributes, int, int, int, boolean, int) allocated} {@link GLPixelBuffer} w/ {@link GLPixelAttributes#componentCount}. */ + GLPixelBuffer getSingleBuffer(GLPixelAttributes pixelAttributes); + /** + * Initializes the single {@link GLPixelBuffer} w/ a given size, if not yet {@link #allocate(GL, GLPixelAttributes, int, int, int, boolean, int) allocated}. + * @return the newly initialized single {@link GLPixelBuffer}, or null if already allocated. + */ + GLPixelBuffer initSingleton(int componentCount, int width, int height, int depth, boolean pack); + } + /** * Default {@link GLPixelBufferProvider} utilizing best match for {@link GLPixelAttributes} * and {@link GLPixelBufferProvider#allocate(GL, GLPixelAttributes, int, int, int, boolean, int) allocating} a {@link ByteBuffer}. @@ -118,7 +130,7 @@ public class GLPixelBuffer { /** Undefined instance of {@link GLPixelAttributes}, having componentCount:=0, format:=0 and type:= 0. */ public static final GLPixelAttributes UNDEF = new GLPixelAttributes(0, 0, 0); - /** Pixel component count */ + /** Pixel <i>source</i> component count, i.e. number of meaningful components. */ public final int componentCount; /** The OpenGL pixel data format */ public final int format; @@ -175,12 +187,14 @@ public class GLPixelBuffer { /** Buffer element size in bytes. */ public final int bufferElemSize; + private boolean disposed = false; + public StringBuffer toString(StringBuffer sb) { if(null == sb) { sb = new StringBuffer(); } sb.append(pixelAttributes).append(", dim ").append(width).append("x").append(height).append("x").append(depth).append(", pack ").append(pack) - .append(", buffer[sz [bytes ").append(byteSize).append(", elemSize ").append(bufferElemSize).append(", ").append(buffer).append("]"); + .append(", disposed ").append(disposed).append(", valid ").append(isValid()).append(", buffer[sz [bytes ").append(byteSize).append(", elemSize ").append(bufferElemSize).append(", ").append(buffer).append("]"); return sb; } public String toString() { @@ -198,8 +212,9 @@ public class GLPixelBuffer { this.bufferElemSize = Buffers.sizeOfBufferElem(buffer); } + /** Is not {@link #dispose()} and has {@link #byteSize} > 0. */ public boolean isValid() { - return 0 < byteSize; + return !disposed && 0 < byteSize; } public Buffer rewind() { @@ -226,7 +241,7 @@ public class GLPixelBuffer { /** * Returns true, if implementation requires a new buffer based on the new size - * due to pixel alignment or byte size, otherwise false. + * due to pixel alignment or byte size or if {@link #isValid() invalid}, otherwise false. * <p> * It is assumed that <code>pixelAttributes</code>, <code>depth</code> and <code>pack</code> stays the same! * </p> @@ -242,7 +257,7 @@ public class GLPixelBuffer { * @see GLPixelBufferProvider#allocate(GL, GLPixelAttributes, int, int, int, boolean, int) */ public boolean requiresNewBuffer(GL gl, int newWidth, int newHeight, int minByteSize) { - return this.byteSize < minByteSize; + return !isValid() || this.byteSize < minByteSize; } /** Dispose resources. */ diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java index 2af48cefd..aceb609a1 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java @@ -54,7 +54,8 @@ import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; * </p> */ public class AWTGLPixelBuffer extends GLPixelBuffer { - public static final GLPixelAttributes awtPixelAttributesIntRGB = new GLPixelAttributes(GL.GL_BGRA, GL.GL_UNSIGNED_BYTE); + public static final GLPixelAttributes awtPixelAttributesIntRGBA4 = new GLPixelAttributes(4, GL.GL_BGRA, GL.GL_UNSIGNED_BYTE); + public static final GLPixelAttributes awtPixelAttributesIntRGB3 = new GLPixelAttributes(3, GL.GL_BGRA, GL.GL_UNSIGNED_BYTE); /** Allow {@link GL2GL3#GL_PACK_ROW_LENGTH}, or {@link GL2GL3#GL_UNPACK_ROW_LENGTH}. See {@link #requiresNewBuffer(GL, int, int, int)}. */ public final boolean allowRowStride; @@ -92,6 +93,9 @@ public class AWTGLPixelBuffer extends GLPixelBuffer { */ @Override public boolean requiresNewBuffer(GL gl, int newWidth, int newHeight, int minByteSize) { + if( !isValid() ) { + return true; + } if( allowRowStride && gl.isGL2GL3() ) { return width < newWidth || height < newHeight; } else { @@ -129,7 +133,7 @@ public class AWTGLPixelBuffer extends GLPixelBuffer { } @Override public GLPixelAttributes getAttributes(GL gl, int componentCount) { - return awtPixelAttributesIntRGB; + return 4 == componentCount ? awtPixelAttributesIntRGBA4 : awtPixelAttributesIntRGB3; } /** @@ -157,8 +161,9 @@ public class AWTGLPixelBuffer extends GLPixelBuffer { * The latter is true if size are compatible, hence <code>allowRowStride</code> should be enabled, if possible. * </p> */ - public static class SingleAWTGLPixelBufferProvider extends AWTGLPixelBufferProvider { - private AWTGLPixelBuffer single = null; + public static class SingleAWTGLPixelBufferProvider extends AWTGLPixelBufferProvider implements SingletonGLPixelBufferProvider { + private AWTGLPixelBuffer singleRGBA4 = null; + private AWTGLPixelBuffer singleRGB3 = null; /** * @param allowRowStride If <code>true</code>, allow row-stride, otherwise not. See {@link AWTGLPixelBuffer#requiresNewBuffer(GL, int, int, int)}. @@ -175,10 +180,17 @@ public class AWTGLPixelBuffer extends GLPixelBuffer { */ @Override public AWTGLPixelBuffer allocate(GL gl, GLPixelAttributes pixelAttributes, int width, int height, int depth, boolean pack, int minByteSize) { - if( null == single || single.requiresNewBuffer(gl, width, height, minByteSize) ) { - single = allocateImpl(pixelAttributes, width, height, depth, pack, minByteSize); + if( 4 == pixelAttributes.componentCount ) { + if( null == singleRGBA4 || singleRGBA4.requiresNewBuffer(gl, width, height, minByteSize) ) { + singleRGBA4 = allocateImpl(pixelAttributes, width, height, depth, pack, minByteSize); + } + return singleRGBA4; + } else { + if( null == singleRGB3 || singleRGB3.requiresNewBuffer(gl, width, height, minByteSize) ) { + singleRGB3 = allocateImpl(pixelAttributes, width, height, depth, pack, minByteSize); + } + return singleRGB3; } - return single; } private AWTGLPixelBuffer allocateImpl(GLPixelAttributes pixelAttributes, int width, int height, int depth, boolean pack, int minByteSize) { @@ -188,16 +200,29 @@ public class AWTGLPixelBuffer extends GLPixelBuffer { return new AWTGLPixelBuffer(pixelAttributes, width, height, depth, pack, image, ibuffer, allowRowStride); } + /** Return the last {@link #allocate(GL, GLPixelAttributes, int, int, int, boolean, int) allocated} {@link AWTGLPixelBuffer} w/ {@link GLPixelAttributes#componentCount}. */ + public AWTGLPixelBuffer getSingleBuffer(GLPixelAttributes pixelAttributes) { + return 4 == pixelAttributes.componentCount ? singleRGBA4 : singleRGB3; + } + /** * Initializes the single {@link AWTGLPixelBuffer} w/ a given size, if not yet {@link #allocate(GL, GLPixelAttributes, int, int, int, boolean, int) allocated}. * @return the newly initialized single {@link AWTGLPixelBuffer}, or null if already allocated. */ - public AWTGLPixelBuffer initSingleton(int width, int height, int depth, boolean pack) { - if( null != single ) { - return null; + public AWTGLPixelBuffer initSingleton(int componentCount, int width, int height, int depth, boolean pack) { + if( 4 == componentCount ) { + if( null != singleRGBA4 ) { + return null; + } + singleRGBA4 = allocateImpl(AWTGLPixelBuffer.awtPixelAttributesIntRGBA4, width, height, depth, pack, 0); + return singleRGBA4; + } else { + if( null != singleRGB3 ) { + return null; + } + singleRGB3 = allocateImpl(AWTGLPixelBuffer.awtPixelAttributesIntRGB3, width, height, depth, pack, 0); + return singleRGB3; } - single = allocateImpl(AWTGLPixelBuffer.awtPixelAttributesIntRGB, width, height, depth, pack, 0); - return single; } } }
\ No newline at end of file diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index 3f3e88977..7359e1b47 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -87,6 +87,7 @@ import jogamp.opengl.util.glsl.GLSLTextureRaster; import com.jogamp.nativewindow.awt.AWTWindowClosingProtocol; import com.jogamp.opengl.FBObject; import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; +import com.jogamp.opengl.util.GLPixelBuffer.SingletonGLPixelBufferProvider; import com.jogamp.opengl.util.GLPixelStorageModes; import com.jogamp.opengl.util.awt.AWTGLPixelBuffer; import com.jogamp.opengl.util.awt.AWTGLPixelBuffer.AWTGLPixelBufferProvider; @@ -301,7 +302,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing if( null != backend ) { throw new IllegalStateException("Backend already realized."); } - customPixelBufferProvider = custom; + customPixelBufferProvider = custom; } @Override @@ -975,12 +976,13 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing // buffer and drawing it with a BufferedImage class OffscreenBackend implements Backend { private final AWTGLPixelBufferProvider pixelBufferProvider; + private final boolean useSingletonBuffer; private AWTGLPixelBuffer pixelBuffer; private boolean pixelBufferCheckSize; // One of these is used to store the read back pixels before storing // in the BufferedImage - protected IntBuffer readBackInts; + protected IntBuffer readBackIntsForCPUVFlip; // Implementation using software rendering private GLDrawableImpl offscreenDrawable; @@ -997,10 +999,15 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing OffscreenBackend(GLProfile glp, AWTGLPixelBufferProvider custom) { if(null == custom) { pixelBufferProvider = glp.isGL2GL3() ? getSingleAWTGLPixelBufferProvider() : - new AWTGLPixelBufferProvider( true /* allowRowStride */ ); + new AWTGLPixelBufferProvider( false /* allowRowStride */ ) ; } else { pixelBufferProvider = custom; } + if( pixelBufferProvider instanceof SingletonGLPixelBufferProvider ) { + useSingletonBuffer = true; + } else { + useSingletonBuffer = false; + } } @Override @@ -1104,11 +1111,22 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing adevice.close(); } } + + if( null != readBackIntsForCPUVFlip ) { + readBackIntsForCPUVFlip.clear(); + readBackIntsForCPUVFlip = null; + } + if( null != pixelBuffer ) { + if( !useSingletonBuffer ) { + pixelBuffer.dispose(); + } + pixelBuffer = null; + } } @Override public void setOpaque(boolean opaque) { - if (opaque != isOpaque()) { + if ( opaque != isOpaque() && !useSingletonBuffer ) { pixelBuffer.dispose(); pixelBuffer = null; } @@ -1137,8 +1155,11 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing alignment = 4; } - final GLPixelAttributes pixelAttribs; + final GLPixelAttributes pixelAttribs = pixelBufferProvider.getAttributes(gl, componentCount); + if( useSingletonBuffer ) { // attempt to fetch the latest AWTGLPixelBuffer + pixelBuffer = (AWTGLPixelBuffer) ((SingletonGLPixelBufferProvider)pixelBufferProvider).getSingleBuffer(pixelAttribs); + } if( pixelBufferCheckSize ) { pixelBufferCheckSize = false; if( null != pixelBuffer && pixelBuffer.requiresNewBuffer(gl, panelWidth, panelHeight, 0) ) { @@ -1147,28 +1168,28 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing } } - // Must now copy pixels from offscreen context into surface if ( null == pixelBuffer ) { if (0 >= panelWidth || 0 >= panelHeight ) { return; - } - - pixelAttribs = pixelBufferProvider.getAttributes(gl, componentCount); + } pixelBuffer = pixelBufferProvider.allocate(gl, pixelAttribs, panelWidth, panelHeight, 1, true, 0); - if( !flipVertical || null != glslTextureRaster ) { - readBackInts = (IntBuffer) pixelBuffer.buffer; - } else { - readBackInts = IntBuffer.allocate(pixelBuffer.width * pixelBuffer.height); - } if(DEBUG) { - System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0: pixelBufferProvider 0x"+Integer.toHexString(pixelBufferProvider.hashCode())+", "+pixelBufferProvider.getClass().getSimpleName()); + System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0: pixelBufferProvider isSingletonBufferProvider "+useSingletonBuffer+", 0x"+Integer.toHexString(pixelBufferProvider.hashCode())+", "+pixelBufferProvider.getClass().getSimpleName()); System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0: pixelBuffer 0x"+Integer.toHexString(pixelBuffer.hashCode())+", "+pixelBuffer+", alignment "+alignment); System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0: flippedVertical "+flipVertical+", glslTextureRaster "+(null!=glslTextureRaster)); System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0: panelSize "+panelWidth+"x"+panelHeight); } + } + final IntBuffer readBackInts; + + if( !flipVertical || null != glslTextureRaster ) { + readBackInts = (IntBuffer) pixelBuffer.buffer; } else { - pixelAttribs = pixelBuffer.pixelAttributes; - } + if( null == readBackIntsForCPUVFlip || pixelBuffer.width * pixelBuffer.height > readBackIntsForCPUVFlip.remaining() ) { + readBackIntsForCPUVFlip = IntBuffer.allocate(pixelBuffer.width * pixelBuffer.height); + } + readBackInts = readBackIntsForCPUVFlip; + } if( DEBUG_VIEWPORT ) { int[] vp = new int[] { 0, 0, 0, 0 }; @@ -1176,6 +1197,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL: Viewport: "+vp[0]+"/"+vp[1]+" "+vp[2]+"x"+vp[3]); } + // Must now copy pixels from offscreen context into surface + // Save current modes psm.setAlignment(gl, alignment, alignment); if(gl.isGL2GL3()) { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelsAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelsAWT.java index 0b0030d99..54dfe6726 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelsAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelsAWT.java @@ -59,7 +59,6 @@ import com.jogamp.opengl.test.junit.util.MiscUtils; import com.jogamp.opengl.test.junit.util.QuitAdapter; import com.jogamp.opengl.test.junit.util.UITestCase; import com.jogamp.opengl.util.FPSAnimator; -import com.jogamp.opengl.util.awt.AWTGLPixelBuffer.AWTGLPixelBufferProvider; import com.jogamp.opengl.util.awt.AWTGLPixelBuffer.SingleAWTGLPixelBufferProvider; public class TestGearsES2GLJPanelsAWT extends UITestCase { @@ -75,7 +74,7 @@ public class TestGearsES2GLJPanelsAWT extends UITestCase { static int swapInterval = 0; static boolean useAnimator = true; static boolean manualTest = false; - static boolean useSingleBuffer = true; // default + static boolean initSingleBuffer = false; /** * Even though GLJPanel uses a SingleAWTGLPixelBufferProvider per default, @@ -93,9 +92,9 @@ public class TestGearsES2GLJPanelsAWT extends UITestCase { setTestSupported(false); } - if( useSingleBuffer ) { + if( initSingleBuffer ) { singleAWTGLPixelBufferProvider = new SingleAWTGLPixelBufferProvider( glp.isGL2GL3() /* allowRowStride */); - singleAWTGLPixelBufferProvider.initSingleton(600, 600, 1, true); + singleAWTGLPixelBufferProvider.initSingleton(4, 600, 600, 1, true); } else { singleAWTGLPixelBufferProvider = null; } @@ -112,7 +111,7 @@ public class TestGearsES2GLJPanelsAWT extends UITestCase { throws InterruptedException, InvocationTargetException { final GLJPanel canvas = new GLJPanel(caps); - if( useSingleBuffer ) { + if( initSingleBuffer ) { canvas.setPixelBufferProvider( singleAWTGLPixelBufferProvider ); } canvas.setOpaque(opaque); @@ -377,9 +376,9 @@ public class TestGearsES2GLJPanelsAWT extends UITestCase { } else if(args[i].equals("-alpha")) { i++; glAlpha = MiscUtils.atof(args[i], glAlpha); - } else if(args[i].equals("-singleBuffer")) { + } else if(args[i].equals("-initSingleBuffer")) { i++; - useSingleBuffer = MiscUtils.atob(args[i], useSingleBuffer); + initSingleBuffer = MiscUtils.atob(args[i], initSingleBuffer); } else if(args[i].equals("-jZOrder")) { jZOrder = true; } else if(args[i].equals("-noanim")) { @@ -405,7 +404,7 @@ public class TestGearsES2GLJPanelsAWT extends UITestCase { System.err.println("shallUsePBuffer "+shallUsePBuffer); System.err.println("shallUseBitmap "+shallUseBitmap); System.err.println("manualTest "+manualTest); - System.err.println("useSingleBuffer "+useSingleBuffer); + System.err.println("useSingleBuffer "+initSingleBuffer); org.junit.runner.JUnitCore.main(TestGearsES2GLJPanelsAWT.class.getName()); } |