aboutsummaryrefslogtreecommitdiffstats
path: root/make/gl-impl-CustomJavaCode.java
diff options
context:
space:
mode:
Diffstat (limited to 'make/gl-impl-CustomJavaCode.java')
-rw-r--r--make/gl-impl-CustomJavaCode.java80
1 files changed, 78 insertions, 2 deletions
diff --git a/make/gl-impl-CustomJavaCode.java b/make/gl-impl-CustomJavaCode.java
index 1669f07bc..949affbc7 100644
--- a/make/gl-impl-CustomJavaCode.java
+++ b/make/gl-impl-CustomJavaCode.java
@@ -64,7 +64,8 @@ public void setObjectTracker(GLObjectTracker tracker) {
should catch most crashes. 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) {
+private int imageSizeInBytes(int format, int type, int w, int h, int d,
+ int dimensions, boolean pack) {
int elements = 0;
int esize = 0;
@@ -146,7 +147,82 @@ private int imageSizeInBytes(int format, int type, int w, int h, int d) {
default:
return 0;
}
- return (elements * esize * w * h * d);
+ return imageSizeInBytes(elements * esize, w, h, d, dimensions, pack);
+}
+
+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 w, int h, int d,
+ int dimensions,
+ 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 (dimensions > 2) {
+ 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 (dimensions > 2) {
+ 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
+ rowLength = Math.max(0, rowLength);
+ skipRows = Math.max(0, skipRows);
+ skipPixels = Math.max(0, skipPixels);
+ alignment = Math.max(1, alignment);
+ imageHeight = Math.max(0, imageHeight);
+ skipImages = Math.max(0, skipImages);
+ rowLength = Math.max(rowLength, w + skipPixels);
+ int rowLengthInBytes = rowLength * bytesPerElement;
+ if (alignment > 1) {
+ int modulus = rowLengthInBytes % alignment;
+ if (modulus > 0) {
+ rowLengthInBytes += alignment - modulus;
+ }
+ }
+
+ int size = 0;
+ if (dimensions == 1) {
+ return (w + skipPixels) * bytesPerElement;
+ } else {
+ int size2D = ((skipRows + h - 1) * rowLengthInBytes) + (w + skipPixels) * bytesPerElement;
+ if (dimensions == 2) {
+ return size2D;
+ }
+ int imageSizeInBytes = imageHeight * rowLength;
+ return ((skipImages + d - 1) * imageSizeInBytes) + size2D;
+ }
}
private boolean bufferObjectExtensionsInitialized = false;