diff options
author | Sven Gothel <[email protected]> | 2011-06-09 00:42:41 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-06-09 00:42:41 +0200 |
commit | 423f5bf7f518433edcbf64accaf2cf5252cb4a63 (patch) | |
tree | 15b4278c893adc5f423a22b85b2b97c6b6cda010 | |
parent | f6bd208d8ef15769e13cb959e614349fd1e7cae1 (diff) |
GLBuffers fix ; GL imageSizeInBytes fix / unit tests.
- Moved implementation of prev GL imageSizeInBytes(..) -> GLBuffers.sizeof() for all GL profiles
- GLBuffers.*: Added missing formats and types (GL2.1, GL3.3 and GL4.1)
- GLBuffers.sizeof(): Fail fast if format/type is unhandled, or alignment invalid
- Added unit test for GLBuffers.sizeof()
-rw-r--r-- | make/config/jogl/gl-es1.cfg | 1 | ||||
-rw-r--r-- | make/config/jogl/gl-es2.cfg | 1 | ||||
-rw-r--r-- | make/config/jogl/gl-gl4bc.cfg | 1 | ||||
-rw-r--r-- | make/config/jogl/gl-impl-CustomJavaCode-desktop.java | 77 | ||||
-rw-r--r-- | make/config/jogl/gl-impl-CustomJavaCode-embedded.java | 41 | ||||
-rw-r--r-- | make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java | 92 | ||||
-rw-r--r-- | make/config/jogl/gl-impl-CustomJavaCode-gles1.java | 54 | ||||
-rw-r--r-- | make/config/jogl/gl-impl-CustomJavaCode-gles2.java | 60 | ||||
-rwxr-xr-x | make/scripts/tests.sh | 4 | ||||
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java | 412 | ||||
-rw-r--r-- | src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGPUMemSec01NEWT.java | 319 |
11 files changed, 721 insertions, 341 deletions
diff --git a/make/config/jogl/gl-es1.cfg b/make/config/jogl/gl-es1.cfg index 5c69be9b7..88ce09569 100644 --- a/make/config/jogl/gl-es1.cfg +++ b/make/config/jogl/gl-es1.cfg @@ -98,3 +98,4 @@ Import javax.media.opengl.GLES1 Import javax.media.opengl.GLES2 Import javax.media.opengl.GL2 Import com.jogamp.common.nio.Buffers +Import com.jogamp.opengl.util.GLBuffers diff --git a/make/config/jogl/gl-es2.cfg b/make/config/jogl/gl-es2.cfg index dcdc39b29..f529ddbf7 100644 --- a/make/config/jogl/gl-es2.cfg +++ b/make/config/jogl/gl-es2.cfg @@ -85,5 +85,6 @@ Import javax.media.opengl.GL2 Import javax.media.opengl.GLArrayData Import javax.media.opengl.GLUniformData Import com.jogamp.common.nio.Buffers +Import com.jogamp.opengl.util.GLBuffers Import java.io.PrintStream diff --git a/make/config/jogl/gl-gl4bc.cfg b/make/config/jogl/gl-gl4bc.cfg index aafb9166b..6833d24d5 100644 --- a/make/config/jogl/gl-gl4bc.cfg +++ b/make/config/jogl/gl-gl4bc.cfg @@ -105,4 +105,5 @@ Import javax.media.opengl.GL3 Import javax.media.opengl.GL3bc Import javax.media.opengl.GL4 Import com.jogamp.common.nio.Buffers +Import com.jogamp.opengl.util.GLBuffers Import java.io.PrintStream diff --git a/make/config/jogl/gl-impl-CustomJavaCode-desktop.java b/make/config/jogl/gl-impl-CustomJavaCode-desktop.java index 93a275269..4edb28272 100644 --- a/make/config/jogl/gl-impl-CustomJavaCode-desktop.java +++ b/make/config/jogl/gl-impl-CustomJavaCode-desktop.java @@ -1,80 +1,7 @@ private int[] imageSizeTemp = new int[1]; - /** Helper for more precise computation of number of bytes that will - be touched by a pixel pack or unpack operation. */ - private int imageSizeInBytes(int bytesPerElement, - int width, int height, int depth, boolean pack) { - int rowLength = 0; - int skipRows = 0; - int skipPixels = 0; - int alignment = 1; - int imageHeight = 0; - int skipImages = 0; - - if (pack) { - glGetIntegerv(GL_PACK_ROW_LENGTH, imageSizeTemp, 0); - rowLength = imageSizeTemp[0]; - glGetIntegerv(GL_PACK_SKIP_ROWS, imageSizeTemp, 0); - skipRows = imageSizeTemp[0]; - glGetIntegerv(GL_PACK_SKIP_PIXELS, imageSizeTemp, 0); - skipPixels = imageSizeTemp[0]; - glGetIntegerv(GL_PACK_ALIGNMENT, imageSizeTemp, 0); - alignment = imageSizeTemp[0]; - if (depth > 1) { - glGetIntegerv(GL_PACK_IMAGE_HEIGHT, imageSizeTemp, 0); - imageHeight = imageSizeTemp[0]; - glGetIntegerv(GL_PACK_SKIP_IMAGES, imageSizeTemp, 0); - skipImages = imageSizeTemp[0]; - } - } else { - glGetIntegerv(GL_UNPACK_ROW_LENGTH, imageSizeTemp, 0); - rowLength = imageSizeTemp[0]; - glGetIntegerv(GL_UNPACK_SKIP_ROWS, imageSizeTemp, 0); - skipRows = imageSizeTemp[0]; - glGetIntegerv(GL_UNPACK_SKIP_PIXELS, imageSizeTemp, 0); - skipPixels = imageSizeTemp[0]; - glGetIntegerv(GL_UNPACK_ALIGNMENT, imageSizeTemp, 0); - alignment = imageSizeTemp[0]; - if (depth > 1) { - glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, imageSizeTemp, 0); - imageHeight = imageSizeTemp[0]; - glGetIntegerv(GL_UNPACK_SKIP_IMAGES, imageSizeTemp, 0); - skipImages = imageSizeTemp[0]; - } - } - // Try to deal somewhat correctly with potentially invalid values - width = Math.max(0, width ); - height = Math.max(1, height); // min 1D - depth = Math.max(1, depth ); // min 1 * imageSize - skipRows = Math.max(0, skipRows); - skipPixels = Math.max(0, skipPixels); - alignment = Math.max(1, alignment); - skipImages = Math.max(0, skipImages); - - imageHeight = ( imageHeight > 0 ) ? imageHeight : height; - rowLength = ( rowLength > 0 ) ? rowLength : width; - - int rowLengthInBytes = rowLength * bytesPerElement; - - if (alignment > 1) { - int padding = rowLengthInBytes % alignment; - if (padding > 0) { - rowLengthInBytes += alignment - padding; - } - } - - /** - * skipPixels and skipRows is a static one time offset. - * - * skipImages and depth are in multiples of image size. - * - * rowlenght is the actual repeating offset - * to go from line n to line n+1 at the same x-axis position. - */ - return - ( skipImages + depth - 1 ) * imageHeight * rowLengthInBytes + // whole images - ( skipRows + height - 1 ) * rowLengthInBytes + // lines with padding - ( skipPixels + width ) * bytesPerElement; // last line + private final int imageSizeInBytes(int format, int type, int width, int height, int depth, boolean pack) { + return GLBuffers.sizeof(this, imageSizeTemp, format, type, width, height, depth, pack) ; } public final boolean isGL4bc() { diff --git a/make/config/jogl/gl-impl-CustomJavaCode-embedded.java b/make/config/jogl/gl-impl-CustomJavaCode-embedded.java index 0408c21a1..e1273e679 100644 --- a/make/config/jogl/gl-impl-CustomJavaCode-embedded.java +++ b/make/config/jogl/gl-impl-CustomJavaCode-embedded.java @@ -1,42 +1,7 @@ -private int[] imageSizeTemp = new int[1]; -/** Helper for more precise computation of number of bytes that will - be touched by a pixel pack or unpack operation. */ -private int imageSizeInBytes(int bytesPerElement, - int rowLength, int imageHeight, int depth, boolean pack) { - int alignment = 1; + private int[] imageSizeTemp = new int[1]; - if (pack) { - glGetIntegerv(GL_PACK_ALIGNMENT, imageSizeTemp, 0); - alignment = imageSizeTemp[0]; - } else { - glGetIntegerv(GL_UNPACK_ALIGNMENT, imageSizeTemp, 0); - alignment = imageSizeTemp[0]; + private final int imageSizeInBytes(int format, int type, int width, int height, int depth, boolean pack) { + return GLBuffers.sizeof(this, imageSizeTemp, format, type, width, height, depth, pack) ; } - // Try to deal somewhat correctly with potentially invalid values - rowLength = Math.max(0, rowLength ); - imageHeight = Math.max(1, imageHeight); // min 1D - depth = Math.max(1, depth ); // min 1 * imageSize - alignment = Math.max(1, alignment); - - int rowLengthInBytes = rowLength * bytesPerElement; - - if (alignment > 1) { - int padding = rowLengthInBytes % alignment; - if (padding > 0) { - rowLengthInBytes += alignment - padding; - } - } - - /** - * depth is in multiples of image size. - * - * rowlenght is the actual repeating offset - * to go from line n to line n+1 at the same x-axis position. - */ - return - ( depth - 1 ) * imageHeight * rowLengthInBytes + // whole images - ( imageHeight - 1 ) * rowLengthInBytes + // lines with padding - ( rowLength ) * bytesPerElement; // last line -} diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java b/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java index dbfa3ef4d..e977204e3 100644 --- a/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java +++ b/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java @@ -35,98 +35,6 @@ public java.nio.ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, // Helpers for ensuring the correct amount of texture data // -/** Returns the number of bytes required to fill in the appropriate - texture. This is computed as closely as possible based on the - pixel pack or unpack parameters. The logic in this routine is - based on code in the SGI OpenGL sample implementation. */ - -private int imageSizeInBytes(int format, int type, int w, int h, int d, - boolean pack) { - int elements = 0; - int esize = 0; - - if (w < 0) return 0; - if (h < 0) return 0; - if (d < 0) return 0; - switch (format) { - case GL_COLOR_INDEX: - case GL_STENCIL_INDEX: - elements = 1; - break; - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_DEPTH_COMPONENT: - elements = 1; - break; - case GL_LUMINANCE_ALPHA: - elements = 2; - break; - case GL_RGB: - case GL_BGR: - elements = 3; - break; - case GL_RGBA: - case GL_BGRA: - case GL_ABGR_EXT: - elements = 4; - break; - /* FIXME ?? - case GL_HILO_NV: - elements = 2; - break; */ - default: - return 0; - } - switch (type) { - case GL_BITMAP: - if (format == GL_COLOR_INDEX) { - return (d * (h * ((w+7)/8))); - } else { - return 0; - } - case GL_BYTE: - case GL_UNSIGNED_BYTE: - esize = 1; - break; - case GL_UNSIGNED_BYTE_3_3_2: - case GL_UNSIGNED_BYTE_2_3_3_REV: - esize = 1; - elements = 1; - break; - case GL_SHORT: - case GL_UNSIGNED_SHORT: - esize = 2; - break; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_5_6_5_REV: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - esize = 2; - elements = 1; - break; - case GL_INT: - case GL_UNSIGNED_INT: - case GL_FLOAT: - esize = 4; - break; - case GL_UNSIGNED_INT_8_8_8_8: - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: - esize = 4; - elements = 1; - break; - default: - return 0; - } - return imageSizeInBytes(elements * esize, w, h, d, pack); -} - private GLBufferSizeTracker bufferSizeTracker; private GLBufferStateTracker bufferStateTracker; private GLStateTracker glStateTracker; diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java index 0a0f87897..98ec4e550 100644 --- a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java +++ b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java @@ -98,60 +98,6 @@ public final GL2GL3 getGL2GL3() throws GLException { // Helpers for ensuring the correct amount of texture data // -/** Returns the number of bytes required to fill in the appropriate - texture. This is computed as closely as possible based on the - pixel pack or unpack parameters. The logic in this routine is - based on code in the SGI OpenGL sample implementation. */ - -private int imageSizeInBytes(int format, int type, int w, int h, int d, - boolean pack) { - int elements = 0; - int esize = 0; - - if (w < 0) return 0; - if (h < 0) return 0; - if (d < 0) return 0; - switch (format) { - case GL_ALPHA: - case GL_LUMINANCE: - elements = 1; - break; - case GL_LUMINANCE_ALPHA: - elements = 2; - break; - case GL_RGB: - elements = 3; - break; - case GL_RGBA: - elements = 4; - break; - default: - return 0; - } - switch (type) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - esize = 1; - break; - case GL_SHORT: - case GL_UNSIGNED_SHORT: - esize = 2; - break; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_5_5_5_1: - esize = 2; - elements = 1; - break; - case GL_FLOAT: - esize = 4; - break; - default: - return 0; - } - return imageSizeInBytes(elements * esize, w, h, d, pack); -} - private GLBufferSizeTracker bufferSizeTracker; private GLBufferStateTracker bufferStateTracker; private GLStateTracker glStateTracker; diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles2.java b/make/config/jogl/gl-impl-CustomJavaCode-gles2.java index e096d2185..760ec375e 100644 --- a/make/config/jogl/gl-impl-CustomJavaCode-gles2.java +++ b/make/config/jogl/gl-impl-CustomJavaCode-gles2.java @@ -102,66 +102,6 @@ public final GL2GL3 getGL2GL3() throws GLException { // Helpers for ensuring the correct amount of texture data // -/** Returns the number of bytes required to fill in the appropriate - texture. This is computed as closely as possible based on the - pixel pack or unpack parameters. The logic in this routine is - based on code in the SGI OpenGL sample implementation. */ - -private int imageSizeInBytes(int format, int type, int w, int h, int d, - boolean pack) { - int elements = 0; - int esize = 0; - - if (w < 0) return 0; - if (h < 0) return 0; - if (d < 0) return 0; - switch (format) { - case GL_STENCIL_INDEX: - elements = 1; - break; - case GL_ALPHA: - case GL_LUMINANCE: - case GL_DEPTH_COMPONENT: - elements = 1; - break; - case GL_LUMINANCE_ALPHA: - elements = 2; - break; - case GL_RGB: - elements = 3; - break; - case GL_RGBA: - elements = 4; - break; - default: - return 0; - } - switch (type) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - esize = 1; - break; - case GL_SHORT: - case GL_UNSIGNED_SHORT: - esize = 2; - break; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_5_5_5_1: - esize = 2; - elements = 1; - break; - case GL_INT: - case GL_UNSIGNED_INT: - case GL_FLOAT: - esize = 4; - break; - default: - return 0; - } - return imageSizeInBytes(elements * esize, w, h, d, pack); -} - private GLBufferSizeTracker bufferSizeTracker; private GLBufferStateTracker bufferStateTracker; private GLStateTracker glStateTracker; diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index 9f9e52817..56a996a5d 100755 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -214,9 +214,11 @@ function testawtmt() { #testnoawt com.jogamp.opengl.test.junit.graph.TestTextRendererNEWT01 $* #testnoawt com.jogamp.opengl.test.junit.graph.demos.ui.UINewtDemo01 $* #testnoawt com.jogamp.opengl.test.junit.graph.demos.GPUTextNewtDemo01 $* -testnoawt com.jogamp.opengl.test.junit.graph.demos.GPUTextNewtDemo02 $* +#testnoawt com.jogamp.opengl.test.junit.graph.demos.GPUTextNewtDemo02 $* #testnoawt com.jogamp.opengl.test.junit.graph.demos.GPURegionNewtDemo01 $* #testnoawt com.jogamp.opengl.test.junit.graph.demos.GPURegionNewtDemo02 $* +testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT $* + $spath/count-edt-start.sh java-run.log diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java index efe3a7675..f2e742cda 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java +++ b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java @@ -42,60 +42,145 @@ import com.jogamp.common.nio.Buffers; import javax.media.opengl.GL; import javax.media.opengl.GL2; import javax.media.opengl.GL2ES2; +import javax.media.opengl.GL2GL3; +import javax.media.opengl.GLException; import java.nio.*; /** * Utility routines for dealing with direct buffers. * @author Kenneth Russel + * @author Sven Gothel * @author Michael Bien */ public class GLBuffers extends Buffers { + /** + * @param glType shall be one of + * GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, + * GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, + * GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV, + * GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, + * GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, + * GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV, + * GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV, + * GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV + * GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV, + * GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV (25) + * @return -1 if glType is unhandled, otherwise the actual value > 0 + */ public static final int sizeOfGLType(int glType) { - switch (glType) { - case GL.GL_UNSIGNED_BYTE: - return SIZEOF_BYTE; + switch (glType) { // 25 case GL.GL_BYTE: + case GL.GL_UNSIGNED_BYTE: + case GL2GL3.GL_UNSIGNED_BYTE_3_3_2: + case GL2GL3.GL_UNSIGNED_BYTE_2_3_3_REV: return SIZEOF_BYTE; - case GL.GL_UNSIGNED_SHORT: - return SIZEOF_SHORT; + case GL.GL_SHORT: + case GL.GL_UNSIGNED_SHORT: + case GL.GL_UNSIGNED_SHORT_5_6_5: + case GL2GL3.GL_UNSIGNED_SHORT_5_6_5_REV: + case GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4: + case GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL2GL3.GL_UNSIGNED_SHORT_5_5_5_1: + case GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV: return SIZEOF_SHORT; - case GL.GL_FLOAT: - return SIZEOF_FLOAT; + case GL.GL_FIXED: - return SIZEOF_INT; case GL2ES2.GL_INT: + case GL.GL_UNSIGNED_INT: + case GL2GL3.GL_UNSIGNED_INT_8_8_8_8: + case GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV: + case GL2GL3.GL_UNSIGNED_INT_10_10_10_2: + case GL2GL3.GL_UNSIGNED_INT_2_10_10_10_REV: + case GL2GL3.GL_UNSIGNED_INT_24_8: + case GL2GL3.GL_UNSIGNED_INT_10F_11F_11F_REV: + case GL2GL3.GL_UNSIGNED_INT_5_9_9_9_REV: return SIZEOF_INT; - case GL2ES2.GL_UNSIGNED_INT: - return SIZEOF_INT; + + case GL2GL3.GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + return SIZEOF_LONG; + + case GL.GL_FLOAT: + return SIZEOF_FLOAT; + case GL2.GL_DOUBLE: return SIZEOF_DOUBLE; } return -1; } - + + /** + * @param glType shall be one of + * GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, + * GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, + * GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV, + * GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, + * GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, + * GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV, + * GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV, + * GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV + * GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV, + * GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV (25) + * @return null if glType is unhandled, otherwise the new Buffer object + */ public static final Buffer newDirectGLBuffer(int glType, int numElements) { switch (glType) { - case GL.GL_UNSIGNED_BYTE: case GL.GL_BYTE: + case GL.GL_UNSIGNED_BYTE: + case GL2GL3.GL_UNSIGNED_BYTE_3_3_2: + case GL2GL3.GL_UNSIGNED_BYTE_2_3_3_REV: return newDirectByteBuffer(numElements); - case GL.GL_UNSIGNED_SHORT: + case GL.GL_SHORT: + case GL.GL_UNSIGNED_SHORT: + case GL.GL_UNSIGNED_SHORT_5_6_5: + case GL2GL3.GL_UNSIGNED_SHORT_5_6_5_REV: + case GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4: + case GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL2GL3.GL_UNSIGNED_SHORT_5_5_5_1: + case GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV: return newDirectShortBuffer(numElements); - case GL.GL_FLOAT: - return newDirectFloatBuffer(numElements); + case GL.GL_FIXED: case GL2ES2.GL_INT: - case GL2ES2.GL_UNSIGNED_INT: + case GL.GL_UNSIGNED_INT: + case GL2GL3.GL_UNSIGNED_INT_8_8_8_8: + case GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV: + case GL2GL3.GL_UNSIGNED_INT_10_10_10_2: + case GL2GL3.GL_UNSIGNED_INT_2_10_10_10_REV: + case GL2GL3.GL_UNSIGNED_INT_24_8: + case GL2GL3.GL_UNSIGNED_INT_10F_11F_11F_REV: + case GL2GL3.GL_UNSIGNED_INT_5_9_9_9_REV: return newDirectIntBuffer(numElements); + + case GL2GL3.GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + return newDirectLongBuffer(numElements); + + case GL.GL_FLOAT: + return newDirectFloatBuffer(numElements); + case GL2.GL_DOUBLE: return newDirectDoubleBuffer(numElements); } return null; } + /** + * @param glType shall be one of + * GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, + * GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, + * GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV, + * GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, + * GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, + * GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV, + * GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV, + * GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV + * GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV, + * GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV (25) + * @return null if glType is unhandled or parent is null or bufLen is 0, otherwise the new Buffer object + */ public static final Buffer sliceGLBuffer(ByteBuffer parent, int bytePos, int byteLen, int glType) { if (parent == null || byteLen == 0) { return null; @@ -104,24 +189,309 @@ public class GLBuffers extends Buffers { parent.limit(bytePos + byteLen); switch (glType) { - case GL.GL_UNSIGNED_BYTE: case GL.GL_BYTE: + case GL.GL_UNSIGNED_BYTE: + case GL2GL3.GL_UNSIGNED_BYTE_3_3_2: + case GL2GL3.GL_UNSIGNED_BYTE_2_3_3_REV: return parent.slice(); - case GL.GL_UNSIGNED_SHORT: + case GL.GL_SHORT: + case GL.GL_UNSIGNED_SHORT: + case GL.GL_UNSIGNED_SHORT_5_6_5: + case GL2GL3.GL_UNSIGNED_SHORT_5_6_5_REV: + case GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4: + case GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL2GL3.GL_UNSIGNED_SHORT_5_5_5_1: + case GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV: return parent.asShortBuffer(); - case GL.GL_FLOAT: - return parent.asFloatBuffer(); + case GL.GL_FIXED: - case GL2ES2.GL_INT: + case GL2GL3.GL_INT: case GL2ES2.GL_UNSIGNED_INT: + case GL2GL3.GL_UNSIGNED_INT_8_8_8_8: + case GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV: + case GL2GL3.GL_UNSIGNED_INT_10_10_10_2: + case GL2GL3.GL_UNSIGNED_INT_2_10_10_10_REV: + case GL2GL3.GL_UNSIGNED_INT_24_8: + case GL2GL3.GL_UNSIGNED_INT_10F_11F_11F_REV: + case GL2GL3.GL_UNSIGNED_INT_5_9_9_9_REV: return parent.asIntBuffer(); + + case GL2GL3.GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + return parent.asLongBuffer(); + + case GL.GL_FLOAT: + return parent.asFloatBuffer(); + case GL2.GL_DOUBLE: return parent.asDoubleBuffer(); } return null; } + private static final int glGetInteger(GL gl, int pname, int[] tmp) { + gl.glGetIntegerv(pname, tmp, 0); + return tmp[0]; + } + + /** + * Returns the number of bytes required to read/write a memory buffer via OpenGL + * using the current GL pixel storage state and the given parameters. + * + * <p>This method is security critical, hence it throws an exception (fail-fast) + * in case of an invalid alignment. In case we forgot to handle + * proper values, please contact the maintainer.</p> + * + * @param gl the current GL object + * + * @param tmp a pass through integer array of size >= 1 used to store temp data (performance) + * + * @param bytesPerElement bytes per element + * @param width in pixels + * @param height in pixels + * @param depth in pixels + * @param pack true for read mode GPU -> CPU (pack), otherwise false for write mode CPU -> GPU (unpack) + * @return required minimum size of the buffer in bytes + * @throws GLException if alignment is invalid. Please contact the maintainer if this is our bug. + */ + public static final int sizeof(GL gl, int tmp[], + int bytesPerElement, int width, int height, int depth, + boolean pack) { + int rowLength = 0; + int skipRows = 0; + int skipPixels = 0; + int alignment = 1; + int imageHeight = 0; + int skipImages = 0; + + if (pack) { + alignment = glGetInteger(gl, GL.GL_PACK_ALIGNMENT, tmp); + if(gl.isGL2GL3()) { + rowLength = glGetInteger(gl, GL2GL3.GL_PACK_ROW_LENGTH, tmp); + skipRows = glGetInteger(gl, GL2GL3.GL_PACK_SKIP_ROWS, tmp); + skipPixels = glGetInteger(gl, GL2GL3.GL_PACK_SKIP_PIXELS, tmp); + if (depth > 1) { + imageHeight = glGetInteger(gl, GL2GL3.GL_PACK_IMAGE_HEIGHT, tmp); + skipImages = glGetInteger(gl, GL2GL3.GL_PACK_SKIP_IMAGES, tmp); + } + } + } else { + alignment = glGetInteger(gl, GL.GL_UNPACK_ALIGNMENT, tmp); + if(gl.isGL2GL3 ()) { + rowLength = glGetInteger(gl, GL2GL3.GL_UNPACK_ROW_LENGTH, tmp); + skipRows = glGetInteger(gl, GL2GL3.GL_UNPACK_SKIP_ROWS, tmp); + skipPixels = glGetInteger(gl, GL2GL3.GL_UNPACK_SKIP_PIXELS, tmp); + if (depth > 1) { + imageHeight = glGetInteger(gl, GL2GL3.GL_UNPACK_IMAGE_HEIGHT, tmp); + skipImages = glGetInteger(gl, GL2GL3.GL_UNPACK_SKIP_IMAGES, tmp); + } + } + } + + // Try to deal somewhat correctly with potentially invalid values + width = Math.max(0, width ); + height = Math.max(1, height); // min 1D + depth = Math.max(1, depth ); // min 1 * imageSize + skipRows = Math.max(0, skipRows); + skipPixels = Math.max(0, skipPixels); + alignment = Math.max(1, alignment); + skipImages = Math.max(0, skipImages); + + imageHeight = ( imageHeight > 0 ) ? imageHeight : height; + rowLength = ( rowLength > 0 ) ? rowLength : width; + + int rowLengthInBytes = rowLength * bytesPerElement; + int skipBytes = skipPixels * bytesPerElement; + + switch(alignment) { + case 1: + break; + case 2: + case 4: + case 8: { + // x % 2n == x & (2n - 1) + int remainder = rowLengthInBytes & ( alignment - 1 ); + if (remainder > 0) { + rowLengthInBytes += alignment - remainder; + } + remainder = skipBytes & ( alignment - 1 ); + if (remainder > 0) { + skipBytes += alignment - remainder; + } + } + break; + default: + throw new GLException("Invalid alignment "+alignment+", must be 2**n (1,2,4,8). Pls notify the maintainer in case this is our bug."); + } + + /** + * skipImages, depth, skipPixels and skipRows are static offsets. + * + * skipImages and depth are in multiples of image size. + * + * skipBytes and rowLengthInBytes are aligned + * + * rowLengthInBytes is the aligned byte offset + * from line n to line n+1 at the same x-axis position. + */ + return + skipBytes + // aligned skipPixels * bpp + ( skipImages + depth - 1 ) * imageHeight * rowLengthInBytes + // aligned whole images + ( skipRows + height - 1 ) * rowLengthInBytes + // aligned lines + width * bytesPerElement; // last line + } + + /** + * Returns the number of bytes required to read/write a memory buffer via OpenGL + * using the current GL pixel storage state and the given parameters. + * + * <p>This method is security critical, hence it throws an exception (fail-fast) + * in case either the format, type or alignment is unhandled. In case we forgot to handle + * proper values, please contact the maintainer.</p> + * + * @param gl the current GL object + * + * @param tmp a pass through integer array of size >= 1 used to store temp data (performance) + * + * @param format must be one of + * GL_COLOR_INDEX, GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, + * GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_LUMINANCE, + * GL_RG, GL_LUMINANCE_ALPHA, + * GL_RGB, GL_BGR, GL_RGBA, GL_BGRA, GL_ABGR_EXT, + * GL_RED_INTEGER, GL_GREEN_INTEGER, GL_BLUE_INTEGER, + * GL_RG_INTEGER, GL_RGB_INTEGER, GL_BGR_INTEGER, + * GL_RGBA_INTEGER, GL_BGRA_INTEGER (24) + * + * @param type must be one of + * GL_BITMAP, + * GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, + * GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, + * GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV, + * GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, + * GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, + * GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV, + * GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV, + * GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV + * GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV, + * GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV (26) + * + * @param width in pixels + * @param height in pixels + * @param depth in pixels + * @param pack true for read mode GPU -> CPU, otherwise false for write mode CPU -> GPU + * @return required minimum size of the buffer in bytes + * @throws GLException if format, type or alignment is not handled. Please contact the maintainer if this is our bug. + */ + public static final int sizeof(GL gl, int tmp[], + int format, int type, int width, int height, int depth, + boolean pack) throws GLException { + int elements = 0; + int esize = 0; + + if (width < 0) return 0; + if (height < 0) return 0; + if (depth < 0) return 0; + + switch (format) /* 24 */ { + case GL2.GL_COLOR_INDEX: + case GL2GL3.GL_STENCIL_INDEX: + case GL2GL3.GL_DEPTH_COMPONENT: + case GL2GL3.GL_DEPTH_STENCIL: + case GL2GL3.GL_RED: + case GL2GL3.GL_RED_INTEGER: + case GL2GL3.GL_GREEN: + case GL2GL3.GL_GREEN_INTEGER: + case GL2GL3.GL_BLUE: + case GL2GL3.GL_BLUE_INTEGER: + case GL.GL_ALPHA: + case GL.GL_LUMINANCE: + elements = 1; + break; + case GL.GL_LUMINANCE_ALPHA: + case GL2GL3.GL_RG: + case GL2GL3.GL_RG_INTEGER: + elements = 2; + break; + case GL.GL_RGB: + case GL2GL3.GL_RGB_INTEGER: + case GL2GL3.GL_BGR: + case GL2GL3.GL_BGR_INTEGER: + elements = 3; + break; + case GL.GL_RGBA: + case GL2GL3.GL_RGBA_INTEGER: + case GL2GL3.GL_BGRA: + case GL2GL3.GL_BGRA_INTEGER: + case GL2.GL_ABGR_EXT: + elements = 4; + break; + /* FIXME ?? + case GL.GL_HILO_NV: + elements = 2; + break; */ + default: + throw new GLException("format 0x"+Integer.toHexString(format)+" not supported [yet], pls notify the maintainer in case this is our bug."); + } + + switch (type) /* 26 */ { + case GL2.GL_BITMAP: + if (GL2.GL_COLOR_INDEX == format || GL2GL3.GL_STENCIL_INDEX == format) { + return (depth * (height * ((width+7)/8))); + } + case GL.GL_BYTE: + case GL.GL_UNSIGNED_BYTE: + esize = 1; + break; + case GL.GL_SHORT: + case GL.GL_UNSIGNED_SHORT: + case GL.GL_HALF_FLOAT: + esize = 2; + break; + case GL2ES2.GL_INT: + case GL.GL_UNSIGNED_INT: + case GL.GL_FLOAT: + esize = 4; + break; + case GL2GL3.GL_DOUBLE: + esize = 8; + break; + + case GL2GL3.GL_UNSIGNED_BYTE_3_3_2: + case GL2GL3.GL_UNSIGNED_BYTE_2_3_3_REV: + esize = 1; + elements = 1; + break; + case GL.GL_UNSIGNED_SHORT_5_6_5: + case GL2GL3.GL_UNSIGNED_SHORT_5_6_5_REV: + case GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4: + case GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL2GL3.GL_UNSIGNED_SHORT_5_5_5_1: + case GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV: + esize = 2; + elements = 1; + break; + case GL2GL3.GL_UNSIGNED_INT_8_8_8_8: + case GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV: + case GL2GL3.GL_UNSIGNED_INT_10_10_10_2: + case GL2GL3.GL_UNSIGNED_INT_2_10_10_10_REV: + case GL2GL3.GL_UNSIGNED_INT_24_8: + case GL2GL3.GL_UNSIGNED_INT_10F_11F_11F_REV: + case GL2GL3.GL_UNSIGNED_INT_5_9_9_9_REV: + esize = 4; + elements = 1; + break; + case GL2GL3.GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + esize = 8; + elements = 1; + break; + + default: + throw new GLException("type 0x"+Integer.toHexString(type)+"/"+"format 0x"+Integer.toHexString(format)+" not supported [yet], pls notify the maintainer in case this is our bug."); + } + + return sizeof(gl, tmp, elements * esize, width, height, depth, pack); + } + //---------------------------------------------------------------------- // Conversion routines // diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGPUMemSec01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGPUMemSec01NEWT.java new file mode 100644 index 000000000..a328a2bac --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGPUMemSec01NEWT.java @@ -0,0 +1,319 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * 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 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * 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.acore; + +import com.jogamp.common.nio.Buffers; +import com.jogamp.opengl.util.GLPixelStorageModes; +import com.jogamp.opengl.test.junit.util.NEWTGLContext; +import com.jogamp.opengl.test.junit.util.UITestCase; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import javax.media.opengl.GL; +import javax.media.opengl.GL2ES2; +import javax.media.opengl.GL2GL3; +import javax.media.opengl.GLDrawable; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; + +import org.junit.Assert; +import org.junit.Test; + +public class TestGPUMemSec01NEWT extends UITestCase { + static String hexString(int i) { + return "0x"+Integer.toHexString(i); + } + static String exceptionMsg(String pre, int format, int type, int components, int width, int height, int rl1, int rl4, int rl8) { + return pre + + ": fmt "+hexString(format)+", type "+hexString(type)+", comps "+components+ + ", "+width+"x"+height+ + ", rowlenA1 "+rl1+", rowlenA4 "+rl4+", rowlenA8 "+rl8; + } + + static NEWTGLContext.WindowContext createCurrentGLOffscreenWindow(int width, int height) throws GLException, InterruptedException { + final NEWTGLContext.WindowContext winctx = NEWTGLContext.createOffscreenWindow(GLProfile.getGL2ES2(), width, height, true); + final GL _gl = winctx.context.getGL(); + Assert.assertTrue(_gl.isGL2GL3()); + final GL2GL3 gl = _gl.getGL2GL3(); + + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + + // misc GL setup + gl.glClearColor(1, 1, 1, 1); + gl.glEnable(GL2ES2.GL_DEPTH_TEST); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + gl.glViewport(0, 0, width, height); + gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + + return winctx; + } + + static int readPixelsCheck(GL gl, int format, int type, int components, int width, int height) throws InterruptedException { + int expectedExceptions = 0; + + final int rowlenA1 = width * components; + + final int rowlenA4 = ( ( width * components + 3 ) / 4 ) * 4 ; + Assert.assertTrue(rowlenA4 % 4 == 0); + + final int rowlenA8 = ( ( width * components + 7 ) / 8 ) * 8 ; + Assert.assertTrue(rowlenA8 % 8 == 0); + + GLPixelStorageModes psm = new GLPixelStorageModes(); + psm.setPackAlignment(gl, 1); + + Exception ee = null; + + // ok size ! + try { + ByteBuffer bb = Buffers.newDirectByteBuffer(height*rowlenA1); + gl.glReadPixels(0, 0, width, height, format, type, bb); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + } catch(IndexOutOfBoundsException e) { + ee = e; + } + Assert.assertNull( + exceptionMsg("Unexpected IndexOutOfBoundsException (size ok, alignment 1)", + format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee); + ee = null; + + + // too small -10 ! + try { + ByteBuffer bb = Buffers.newDirectByteBuffer(height*rowlenA1-10); + gl.glReadPixels(0, 0, width, height, format, type, bb); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + } catch(IndexOutOfBoundsException e) { + ee = e; + System.err.println( + exceptionMsg("OK Expected IndexOutOfBoundsException (size-10 bytes)", + format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8)+ + ": "+ee.getMessage()); + expectedExceptions++; + } + Assert.assertNotNull( + exceptionMsg("Expected IndexOutOfBoundsException (size-10 bytes)", + format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee); + ee = null; + + // too small size/4 ! + try { + ByteBuffer bb = Buffers.newDirectByteBuffer(height*rowlenA1/4); + gl.glReadPixels(0, 0, width, height, format, type, bb); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + } catch(IndexOutOfBoundsException e) { + ee = e; + System.err.println( + exceptionMsg("OK Expected IndexOutOfBoundsException (size/4 bytes)", + format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8)+ + ": "+ee.getMessage()); + expectedExceptions++; + } + Assert.assertNotNull( + exceptionMsg("Expected IndexOutOfBoundsException (size/4 bytes)", + format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee); + ee = null; + + // + // Alignment test + // + psm.setPackAlignment(gl, 4); + + // ok size ! + try { + ByteBuffer bb = Buffers.newDirectByteBuffer(height*rowlenA4); + gl.glReadPixels(0, 0, width, height, format, type, bb); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + } catch(IndexOutOfBoundsException e) { + ee = e; + } + Assert.assertNull( + exceptionMsg("Unexpected IndexOutOfBoundsException (size ok, alignment 4)", + format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee); + ee = null; + + // too small if rowlenA1%4 > 0 + try { + ByteBuffer bb = Buffers.newDirectByteBuffer(height*rowlenA1); + gl.glReadPixels(0, 0, width, height, format, type, bb); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + } catch(IndexOutOfBoundsException e) { + ee = e; + if(rowlenA1%4>0) { + System.err.println( + exceptionMsg("OK Expected IndexOutOfBoundsException (alignment 4)", + format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8)+ + ": "+ee.getMessage()); + expectedExceptions++; + } + } + if(rowlenA1%4>0) { + Assert.assertNotNull( + exceptionMsg("Expected IndexOutOfBoundsException (alignment 4)", + format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee); + } else { + Assert.assertNull( + exceptionMsg("Unexpected IndexOutOfBoundsException (alignment 4)", + format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee); + } + ee = null; + + psm.setPackAlignment(gl, 8); + + // ok size ! + try { + ByteBuffer bb = Buffers.newDirectByteBuffer(height*rowlenA8); + gl.glReadPixels(0, 0, width, height, format, type, bb); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + } catch(IndexOutOfBoundsException e) { + ee = e; + } + Assert.assertNull( + exceptionMsg("Unexpected IndexOutOfBoundsException (size ok, alignment 8)", + format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee); + ee = null; + + // too small if rowlenA1%8 > 0 + try { + ByteBuffer bb = Buffers.newDirectByteBuffer(height*rowlenA1); + gl.glReadPixels(0, 0, width, height, format, type, bb); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + } catch(IndexOutOfBoundsException e) { + ee = e; + if(rowlenA1%8>0) { + System.err.println( + exceptionMsg("OK Expected IndexOutOfBoundsException (alignment 8)", + format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8)+ + ": "+ee.getMessage()); + expectedExceptions++; + } + } + if(rowlenA1%8>0) { + Assert.assertNotNull( + exceptionMsg("Expected IndexOutOfBoundsException (alignment 8)", + format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee); + } else { + Assert.assertNull( + exceptionMsg("Unexpected IndexOutOfBoundsException (alignment 8)", + format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee); + } + ee = null; + + psm.restore(gl); + + return expectedExceptions; + } + + @Test + public void testReadPixels_640x480xREDxUB() throws InterruptedException { + final int width = 640; + final int height= 480; + + // preset .. + final NEWTGLContext.WindowContext winctx = createCurrentGLOffscreenWindow(width, height); + final GLDrawable drawable = winctx.context.getGLDrawable(); + final GL2GL3 gl = winctx.context.getGL().getGL2GL3(); + + // 2 x too small - 0 x alignment + Assert.assertEquals(2, readPixelsCheck(gl, GL2GL3.GL_RED, GL.GL_UNSIGNED_BYTE, 1, width, height)); + + drawable.swapBuffers(); + Thread.sleep(50); + + NEWTGLContext.destroyWindow(winctx); + } + + @Test + public void testReadPixels_640x480xRGBxUB() throws InterruptedException { + final int width = 640; + final int height= 480; + + // preset .. + final NEWTGLContext.WindowContext winctx = createCurrentGLOffscreenWindow(width, height); + final GLDrawable drawable = winctx.context.getGLDrawable(); + final GL2GL3 gl = winctx.context.getGL().getGL2GL3(); + + // 2 x too small - 0 x alignment + Assert.assertEquals(2, readPixelsCheck(gl, GL2GL3.GL_RGB, GL.GL_UNSIGNED_BYTE, 3, width, height)); + + drawable.swapBuffers(); + Thread.sleep(50); + + NEWTGLContext.destroyWindow(winctx); + } + + @Test + public void testReadPixels_102x100xREDxUB() throws InterruptedException { + int wwidth = 640; + int wheight= 480; + int rwidth = 102; + int rheight= 100; + + // preset .. + final NEWTGLContext.WindowContext winctx = createCurrentGLOffscreenWindow(wwidth, wheight); + final GLDrawable drawable = winctx.context.getGLDrawable(); + final GL2GL3 gl = winctx.context.getGL().getGL2GL3(); + + // 2 x too small - 2 x alignment + Assert.assertEquals(4, readPixelsCheck(gl, GL2GL3.GL_RED, GL.GL_UNSIGNED_BYTE, 1, rwidth, rheight)); + + drawable.swapBuffers(); + Thread.sleep(50); + + NEWTGLContext.destroyWindow(winctx); + } + + @Test + public void testReadPixels_102x100xRGBxUB() throws InterruptedException { + final int wwidth = 640; + final int wheight= 480; + final int rwidth = 102; + final int rheight= 100; + + // preset .. + final NEWTGLContext.WindowContext winctx = createCurrentGLOffscreenWindow(wwidth, wheight); + final GLDrawable drawable = winctx.context.getGLDrawable(); + final GL2GL3 gl = winctx.context.getGL().getGL2GL3(); + + // 2 x too small - 2 x alignment + Assert.assertEquals(4, readPixelsCheck(gl, GL2GL3.GL_RGB, GL.GL_UNSIGNED_BYTE, 3, rwidth, rheight)); + + drawable.swapBuffers(); + Thread.sleep(50); + + NEWTGLContext.destroyWindow(winctx); + } + + public static void main(String args[]) throws IOException { + String tstname = TestGPUMemSec01NEWT.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } +} + |