lwjgl2-arm64/src/java/org/lwjgl/opengl/BufferChecks.java

320 lines
9 KiB
Java
Raw Normal View History

2004-06-12 22:28:34 +02:00
/*
* Copyright (c) 2002-2004 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
2004-06-12 22:28:34 +02:00
* modification, are permitted provided that the following conditions are
* met:
*
2004-06-12 22:28:34 +02:00
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * 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.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "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 THE COPYRIGHT OWNER 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.
*/
package org.lwjgl.opengl;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ShortBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.DoubleBuffer;
2004-04-03 23:08:23 +02:00
/**
2004-02-15 20:41:51 +01:00
* $Id$ A class to
* check buffer boundaries in GL methods. Many GL methods read data from the GL
* into a native Buffer at its current position. If there is unsufficient space
* in the buffer when the call is made then a buffer overflow would otherwise
* occur and cause unexpected behaviour, a crash, or worse, a security risk.
* Therefore in those methods where GL reads data back into a buffer, we will
* call a bounds check method from this class to ensure that there is
* sufficient space in the buffer.
*
* Thrown by the debug build library of the LWJGL if any OpenGL operation
* causes an error.
*
* @author cix_foo <cix_foo@users.sourceforge.net>
* @version $Revision$
*/
2004-02-08 21:41:00 +01:00
class BufferChecks {
/** Static methods only! */
2004-02-15 20:41:51 +01:00
private BufferChecks() {
}
2004-02-18 23:31:00 +01:00
2004-02-15 20:41:51 +01:00
/**
2004-02-18 23:31:00 +01:00
* Default buffer size for most buffer checks.
2004-02-15 20:41:51 +01:00
*/
2004-02-18 23:31:00 +01:00
private static final int DEFAULT_BUFFER_SIZE = 4;
/**
* Helper methods to ensure a buffer is direct or null.
*/
static void checkDirectOrNull(ByteBuffer buf) {
if (buf != null) {
checkDirect(buf);
}
}
static void checkDirectOrNull(FloatBuffer buf) {
if (buf != null) {
checkDirect(buf);
}
}
static void checkDirectOrNull(ShortBuffer buf) {
if (buf != null) {
checkDirect(buf);
}
}
static void checkDirectOrNull(IntBuffer buf) {
if (buf != null) {
checkDirect(buf);
}
}
static void checkDirectOrNull(DoubleBuffer buf) {
if (buf != null) {
checkDirect(buf);
}
}
/**
* Helper methods to ensure a buffer is direct (and, implicitly, non-null).
*/
static void checkDirectBuffer(Buffer buf) {
if (buf instanceof ByteBuffer)
checkDirect((ByteBuffer)buf);
else if (buf instanceof ShortBuffer)
checkDirect((ShortBuffer)buf);
else if (buf instanceof IntBuffer)
checkDirect((IntBuffer)buf);
else if (buf instanceof FloatBuffer)
checkDirect((FloatBuffer)buf);
else if (buf instanceof DoubleBuffer)
checkDirect((DoubleBuffer)buf);
else
throw new IllegalStateException("Unsupported buffer type");
}
static void checkDirect(ByteBuffer buf) {
if (!buf.isDirect()) {
throw new IllegalArgumentException("ByteBuffer is not direct");
}
}
static void checkDirect(FloatBuffer buf) {
if (!buf.isDirect()) {
throw new IllegalArgumentException("FloatBuffer is not direct");
}
}
static void checkDirect(ShortBuffer buf) {
if (!buf.isDirect()) {
throw new IllegalArgumentException("ShortBuffer is not direct");
}
}
static void checkDirect(IntBuffer buf) {
if (!buf.isDirect()) {
throw new IllegalArgumentException("IntBuffer is not direct");
}
}
static void checkDirect(DoubleBuffer buf) {
if (!buf.isDirect()) {
throw new IllegalArgumentException("IntBuffer is not direct");
}
}
/**
2004-02-15 20:41:51 +01:00
* Helper method to ensure a buffer is big enough to receive data from a
2004-02-18 23:31:00 +01:00
* glGet* operation.
2004-02-15 20:41:51 +01:00
*
* @param buf
* The buffer to check
2004-02-18 23:31:00 +01:00
* @param size
* The minimum buffer size
2004-02-15 20:41:51 +01:00
* @throws BufferOverflowException
*/
private static void checkBufferSize(Buffer buf, int size) {
2004-02-18 23:31:00 +01:00
if (buf.remaining() < size) {
throw new IllegalArgumentException("Number of remaining buffer elements is " + buf.remaining() + ", must be at least " + size);
}
}
static void checkBuffer(ByteBuffer buf, int size) {
checkBufferSize(buf, size);
checkDirect(buf);
}
static void checkBuffer(IntBuffer buf, int size) {
checkBufferSize(buf, size);
checkDirect(buf);
}
static void checkBuffer(ShortBuffer buf, int size) {
checkBufferSize(buf, size);
checkDirect(buf);
}
static void checkBuffer(FloatBuffer buf, int size) {
checkBufferSize(buf, size);
checkDirect(buf);
}
static void checkBuffer(DoubleBuffer buf, int size) {
checkBufferSize(buf, size);
checkDirect(buf);
}
/**
* Helper methods to ensure a buffer is big enough to receive data from a
2004-02-18 23:31:00 +01:00
* glGet* operation. To avoid unnecessarily complex buffer size checking
* we've just set the bar artificially high and insist that any receiving
* buffer has at least 4 remaining().
2004-02-15 20:41:51 +01:00
*
* @param buf
* The buffer to check
* @throws BufferOverflowException
*/
static void checkBuffer(ByteBuffer buf) {
checkBuffer(buf, DEFAULT_BUFFER_SIZE);
}
static void checkBuffer(ShortBuffer buf) {
checkBuffer(buf, DEFAULT_BUFFER_SIZE);
}
static void checkBuffer(FloatBuffer buf) {
checkBuffer(buf, DEFAULT_BUFFER_SIZE);
}
static void checkBuffer(IntBuffer buf) {
checkBuffer(buf, DEFAULT_BUFFER_SIZE);
}
static void checkBuffer(DoubleBuffer buf) {
2004-02-18 23:31:00 +01:00
checkBuffer(buf, DEFAULT_BUFFER_SIZE);
}
2004-02-18 23:31:00 +01:00
/**
2004-02-15 20:41:51 +01:00
* Helper method to ensure that vertex buffer objects are disabled. If they
* are enabled, we'll throw an OpenGLException
*/
static void ensureArrayVBOdisabled() {
if (VBOTracker.getVBOArrayStack().getState() != 0) {
throw new OpenGLException("Cannot use Buffers when VBO is enabled");
}
}
/**
2004-02-15 20:41:51 +01:00
* Helper method to ensure that vertex buffer objects are enabled. If they
* are disabled, we'll throw an OpenGLException
*/
static void ensureArrayVBOenabled() {
if (VBOTracker.getVBOArrayStack().getState() == 0) {
throw new OpenGLException("Cannot use offsets when VBO is disabled");
}
}
/**
* Helper method to ensure that vertex buffer objects are disabled. If they
* are enabled, we'll throw an OpenGLException
*/
static void ensureElementVBOdisabled() {
if (VBOTracker.getVBOElementStack().getState() != 0) {
throw new OpenGLException("Cannot use Buffers when VBO is enabled");
}
}
/**
* Helper method to ensure that vertex buffer objects are enabled. If they
* are disabled, we'll throw an OpenGLException
*/
static void ensureElementVBOenabled() {
if (VBOTracker.getVBOElementStack().getState() == 0) {
throw new OpenGLException("Cannot use offsets when VBO is disabled");
}
}
2004-02-15 20:41:51 +01:00
/**
* Calculate the storage required for an image.
*
* @param format
* The format of the image (example: GL_RGBA)
* @param type
* The type of the image elements (example: GL_UNSIGNED_BYTE)
* @param width
* The width of the image
* @param height
* The height of the image (1 for 1D images)
* @param depth
* The depth of the image (1 for 2D images)
* @return the size, in bytes, of the image
*/
static int calculateImageStorage(int format, int type, int width,
int height, int depth) {
int bpe;
switch (type) {
case GL11.GL_UNSIGNED_BYTE :
case GL11.GL_BYTE :
bpe = 1;
break;
case GL11.GL_UNSIGNED_SHORT :
case GL11.GL_SHORT :
bpe = 2;
break;
case GL11.GL_UNSIGNED_INT :
case GL11.GL_INT :
case GL11.GL_FLOAT :
bpe = 4;
break;
default :
// TODO: Add more types (like the GL12 types GL_UNSIGNED_INT_8_8_8_8
return 0;
// throw new IllegalArgumentException("Unknown type " + type);
2004-02-15 20:41:51 +01:00
}
int epp;
switch (format) {
case GL11.GL_LUMINANCE:
case GL11.GL_ALPHA:
epp = 1;
break;
case GL11.GL_LUMINANCE_ALPHA:
epp = 2;
break;
case GL11.GL_RGB :
case EXTBgra.GL_BGR_EXT :
epp = 3;
break;
case GL11.GL_RGBA :
case EXTAbgr.GL_ABGR_EXT :
case EXTBgra.GL_BGRA_EXT :
epp = 4;
break;
default :
// TODO: Add more formats. Assuming 4 is too wasteful on buffer sizes where e.g. 1 is enough (like GL_DEPTH_COMPONENT)
return 0;
/* // Assume 4 elements per pixel
epp = 4;*/
2004-02-15 20:41:51 +01:00
}
return epp * bpe * width * height * depth;
}
}