diff options
author | Sven Gothel <[email protected]> | 2013-05-09 04:49:29 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-05-09 04:49:29 +0200 |
commit | 890dabf77593732bd9833350b441a37c60f74d45 (patch) | |
tree | c8fe7ead97489bca2a4d7fe7e735baeaf25ab4f9 /src/jogl | |
parent | 5e0a5049d873b5896553ee530562c28ffd3fbe0c (diff) |
Fix Bug 731: GLJPanel: Access global GLPixelBuffer via SingletonGLPixelBufferProvider, if provided - releasing prev. smaller GLPixelBuffer after resize.
Diffstat (limited to 'src/jogl')
3 files changed, 97 insertions, 34 deletions
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()) { |