diff options
-rw-r--r-- | make/gl-common.cfg | 47 | ||||
-rw-r--r-- | make/gl-impl-CustomJavaCode.java | 80 |
2 files changed, 108 insertions, 19 deletions
diff --git a/make/gl-common.cfg b/make/gl-common.cfg index 01afbd8b1..d2b473527 100644 --- a/make/gl-common.cfg +++ b/make/gl-common.cfg @@ -359,25 +359,38 @@ RangeCheck glVertexAttribPointer 5 1 RangeCheck glVertexAttribPointerARB 5 1 RangeCheck glWeightPointerARB 3 1 +# Give ourselves the texture width and height for range checking inside glGetTexImage +JavaPrologue glGetTexImage int width = 0, height = 0, depth = 1; +JavaPrologue glGetTexImage int[] tmp = new int[1]; +JavaPrologue glGetTexImage glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, tmp, 0); +JavaPrologue glGetTexImage width = tmp[0]; +JavaPrologue glGetTexImage glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, tmp, 0); +JavaPrologue glGetTexImage height = tmp[0]; +JavaPrologue glGetTexImage if (target == GL_TEXTURE_3D) { +JavaPrologue glGetTexImage glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, tmp, 0); +JavaPrologue glGetTexImage depth = tmp[0]; +JavaPrologue glGetTexImage } + # Range check directives for various image-related routines -RangeCheckBytes glColorTable 5 imageSizeInBytes({3}, {4}, {2} , 1 , 1) -RangeCheckBytes glColorTableEXT 5 imageSizeInBytes({3}, {4}, {2} , 1 , 1) -RangeCheckBytes glConvolutionFilter1D 5 imageSizeInBytes({3}, {4}, {2} , 1 , 1) -RangeCheckBytes glConvolutionFilter2D 6 imageSizeInBytes({4}, {5}, {2} , {3} , 1) -RangeCheckBytes glDrawPixels 4 imageSizeInBytes({2}, {3}, {0} , {1} , 1) -RangeCheckBytes glReadPixels 6 imageSizeInBytes({4}, {5}, {2} , {3} , 1) -RangeCheckBytes glTexImage1D 7 imageSizeInBytes({5}, {6}, {3} , 1 , 1) -RangeCheckBytes glTexImage2D 8 imageSizeInBytes({6}, {7}, {3} , {4} , 1) -RangeCheckBytes glTexImage3D 9 imageSizeInBytes({7}, {8}, {3} , {4} , {5}) -RangeCheckBytes glTexSubImage1D 6 imageSizeInBytes({4}, {5}, {3} , 1 , 1) -RangeCheckBytes glTexSubImage2D 8 imageSizeInBytes({6}, {7}, {4} , {5} , 1) -RangeCheckBytes glTexSubImage3D 10 imageSizeInBytes({8}, {9}, {5} , {6} , {7}) +RangeCheckBytes glColorTable 5 imageSizeInBytes({3}, {4}, {2} , 1 , 1 , 1, false) +RangeCheckBytes glColorTableEXT 5 imageSizeInBytes({3}, {4}, {2} , 1 , 1 , 1, false) +RangeCheckBytes glConvolutionFilter1D 5 imageSizeInBytes({3}, {4}, {2} , 1 , 1 , 1, false) +RangeCheckBytes glConvolutionFilter2D 6 imageSizeInBytes({4}, {5}, {2} , {3} , 1 , 2, false) +RangeCheckBytes glDrawPixels 4 imageSizeInBytes({2}, {3}, {0} , {1} , 1 , 2, false) +RangeCheckBytes glReadPixels 6 imageSizeInBytes({4}, {5}, {2} , {3} , 1 , 2, true) +RangeCheckBytes glTexImage1D 7 imageSizeInBytes({5}, {6}, {3} , 1 , 1 , 1, false) +RangeCheckBytes glTexImage2D 8 imageSizeInBytes({6}, {7}, {3} , {4} , 1 , 2, false) +RangeCheckBytes glTexImage3D 9 imageSizeInBytes({7}, {8}, {3} , {4} , {5} , 3, false) +RangeCheckBytes glTexSubImage1D 6 imageSizeInBytes({4}, {5}, {3} , 1 , 1 , 1, false) +RangeCheckBytes glTexSubImage2D 8 imageSizeInBytes({6}, {7}, {4} , {5} , 1 , 2, false) +RangeCheckBytes glTexSubImage3D 10 imageSizeInBytes({8}, {9}, {5} , {6} , {7} , 3, false) +# This may produce wrong answers for 1D textures +RangeCheckBytes glGetTexImage 4 imageSizeInBytes({2}, {3}, width , height , depth, ((depth > 1) ? 3 : 2), true) # Note we don't support glTexImage4DSGIS / glTexSubImage4DSGIS - -# Not simple to produce good range checks for these as we would need -# to query the pipeline to see the size of the returned data before -# fetching it -# RangeCheckBytes glGetTexImage +# FIXME: add the following unpack operations: +# glBitmap, glPolygonStipple +# and the following pack operations: +# glGetColorTable, glGetConvolutionFilter, glGetSeparableFilter, glGetHistogram, glGetMinmax # Range checks for server-side object creation and deletion methods RangeCheck glGenBuffers 1 {0} 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; |