summaryrefslogtreecommitdiffstats
path: root/src/jogl
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-05-09 04:49:29 +0200
committerSven Gothel <[email protected]>2013-05-09 04:49:29 +0200
commit890dabf77593732bd9833350b441a37c60f74d45 (patch)
treec8fe7ead97489bca2a4d7fe7e735baeaf25ab4f9 /src/jogl
parent5e0a5049d873b5896553ee530562c28ffd3fbe0c (diff)
Fix Bug 731: GLJPanel: Access global GLPixelBuffer via SingletonGLPixelBufferProvider, if provided - releasing prev. smaller GLPixelBuffer after resize.
Diffstat (limited to 'src/jogl')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java25
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java49
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java57
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} &gt; 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()) {