diff options
Diffstat (limited to 'src/net/java/games')
9 files changed, 291 insertions, 30 deletions
diff --git a/src/net/java/games/gluegen/CMethodBindingEmitter.java b/src/net/java/games/gluegen/CMethodBindingEmitter.java index 8abcdcd78..ffe0ebbd3 100644 --- a/src/net/java/games/gluegen/CMethodBindingEmitter.java +++ b/src/net/java/games/gluegen/CMethodBindingEmitter.java @@ -303,6 +303,7 @@ public class CMethodBindingEmitter extends FunctionEmitter protected int emitArguments(PrintWriter writer) { + int numBufferOffsetArgs = 0, numBufferOffsetArrayArgs = 0; writer.print("JNIEnv *env, "); int numEmitted = 1; // initially just the JNIEnv if (isJavaMethodStatic && !binding.hasContainingType()) @@ -320,6 +321,9 @@ public class CMethodBindingEmitter extends FunctionEmitter { // "this" argument always comes down in argument 0 as direct buffer writer.print(", jobject " + JavaMethodBindingEmitter.javaThisArgumentName()); + numBufferOffsetArgs++; + // add Buffer offset argument for Buffer types + writer.print(", jint " + byteOffsetConversionArgName(numBufferOffsetArgs)); } for (int i = 0; i < binding.getNumArguments(); i++) { JavaType javaArgType = binding.getJavaArgumentType(i); @@ -338,8 +342,18 @@ public class CMethodBindingEmitter extends FunctionEmitter writer.print(" "); writer.print(binding.getArgumentName(i)); ++numEmitted; + // Add Buffer offset argument immediately after any Buffer arguments + if(javaArgType.isNIOBuffer() || javaArgType.isNIOBufferArray()) { + if(!javaArgType.isArray()) { + numBufferOffsetArgs++; + writer.print(", jint " + byteOffsetConversionArgName(numBufferOffsetArgs)); + } else { + numBufferOffsetArrayArgs++; + writer.print(", jintArray " + + byteOffsetArrayConversionArgName(numBufferOffsetArrayArgs)); + } + } } - return numEmitted; } @@ -393,6 +407,10 @@ public class CMethodBindingEmitter extends FunctionEmitter writer.println(" jobject _tmpObj;"); writer.println(" int _copyIndex;"); writer.println(" jsize _tmpArrayLen;"); + + // Pointer to the data in the Buffer, taking the offset into account + writer.println(" GLint * _offsetHandle = NULL;"); + emittedDataCopyTemps = true; } } else if (type.isString()) { @@ -468,16 +486,20 @@ public class CMethodBindingEmitter extends FunctionEmitter protected void emitBodyVariablePreCallSetup(PrintWriter writer, boolean emittingPrimitiveArrayCritical) { + int byteOffsetCounter=0, byteOffsetArrayCounter=0; + if (!emittingPrimitiveArrayCritical) { // Convert all Buffers to pointers first so we don't have to // call ReleasePrimitiveArrayCritical for any arrays if any // incoming buffers aren't direct if (binding.hasContainingType()) { + byteOffsetCounter++; emitPointerConversion(writer, binding, binding.getContainingType(), binding.getContainingCType(), JavaMethodBindingEmitter.javaThisArgumentName(), - CMethodBindingEmitter.cThisArgumentName()); + CMethodBindingEmitter.cThisArgumentName(), + byteOffsetConversionArgName(byteOffsetCounter)); } for (int i = 0; i < binding.getNumArguments(); i++) { @@ -486,10 +508,12 @@ public class CMethodBindingEmitter extends FunctionEmitter continue; } if (type.isNIOBuffer()) { + byteOffsetCounter++; emitPointerConversion(writer, binding, type, binding.getCArgumentType(i), binding.getArgumentName(i), - pointerConversionArgumentName(i)); + pointerConversionArgumentName(i), + byteOffsetConversionArgName(byteOffsetCounter)); } } } @@ -506,6 +530,7 @@ public class CMethodBindingEmitter extends FunctionEmitter boolean needsDataCopy = javaArgTypeNeedsDataCopy(javaArgType); Class subArrayElementJavaType = javaArgType.getJavaClass().getComponentType(); + // We only defer the emission of GetPrimitiveArrayCritical // calls that won't be matched up until after the function // we're calling @@ -592,6 +617,18 @@ public class CMethodBindingEmitter extends FunctionEmitter arrayLenName, "Could not allocate buffer for copying data in argument \\\""+binding.getArgumentName(i)+"\\\""); + // Get the handle for the byte offset array sent down for Buffers + // But avoid doing this if the Array is a string array, the one exception since + // that type is never converted to a Buffer according to JOGL semantics (for instance, + // glShaderSourceARB Java signature is String[], not Buffer) + byteOffsetArrayCounter++; + if(subArrayElementJavaType != java.lang.String.class) + writer.println + (" _offsetHandle = (GLint *) (*env)->GetPrimitiveArrayCritical(env, " + + byteOffsetArrayConversionArgName(byteOffsetArrayCounter) + + ", NULL);"); + + // process each element in the array writer.println(" for (_copyIndex = 0; _copyIndex < "+arrayLenName+"; ++_copyIndex) {"); @@ -609,14 +646,17 @@ public class CMethodBindingEmitter extends FunctionEmitter writer.print(" "); emitGetStringUTFChars(writer, "(jstring) _tmpObj", - convName+"_copy[_copyIndex]"); + "(const char*)"+convName+"_copy[_copyIndex]"); } else if (isNIOBufferClass(subArrayElementJavaType)) { + /* We always assume an integer "byte offset" argument follows any Buffer + in the method binding. */ emitGetDirectBufferAddress(writer, "_tmpObj", cArgElementType.getName(), - convName + "_copy[_copyIndex]"); + convName + "_copy[_copyIndex]", + "_offsetHandle[_copyIndex]"); } else { @@ -641,6 +681,13 @@ public class CMethodBindingEmitter extends FunctionEmitter } writer.println(" }"); + if(subArrayElementJavaType != java.lang.String.class) { + writer.println + (" (*env)->ReleasePrimitiveArrayCritical(env, " + + byteOffsetArrayConversionArgName(byteOffsetArrayCounter) + + ", _offsetHandle, JNI_ABORT);"); + } + writer.println(); } // end of data copy @@ -781,7 +828,7 @@ public class CMethodBindingEmitter extends FunctionEmitter } // free the main array - writer.print(" free((void*) "); + writer.print(" free("); writer.print(convName+"_copy"); writer.println(");"); } // end of cleaning up copied data @@ -1019,6 +1066,7 @@ public class CMethodBindingEmitter extends FunctionEmitter protected String jniMangle(MethodBinding binding) { StringBuffer buf = new StringBuffer(); + int numBufferOffsetArgs = 0; buf.append(jniMangle(binding.getName())); buf.append("__"); for (int i = 0; i < binding.getNumArguments(); i++) { @@ -1026,11 +1074,28 @@ public class CMethodBindingEmitter extends FunctionEmitter Class c = type.getJavaClass(); if (c != null) { jniMangle(c, buf); + // If Buffer offset arguments were added, we need to mangle the JNI for the + // extra arguments + if(type == JavaType.forNIOBufferClass() || + type == JavaType.forNIOByteBufferClass() || + type == JavaType.forNIOShortBufferClass() || + type == JavaType.forNIOIntBufferClass() || + type == JavaType.forNIOLongBufferClass() || + type == JavaType.forNIOFloatBufferClass() || + type == JavaType.forNIODoubleBufferClass()) { + jniMangle(Integer.TYPE, buf); + } else if (type.isNIOByteBufferArray() || + type.isNIOBufferArray()) { + int[] intArrayType = new int[0]; + c = intArrayType.getClass(); + jniMangle(c , buf); + } } else { // FIXME: add support for char* -> String conversion throw new RuntimeException("Unknown kind of JavaType: name="+type.getName()); } } + return buf.toString(); } @@ -1138,22 +1203,53 @@ public class CMethodBindingEmitter extends FunctionEmitter writer.println(" }"); } + + private void emitGetDirectBufferAddress(PrintWriter writer, String sourceVarName, String receivingVarTypeString, - String receivingVarName) { + String receivingVarName, + String byteOffsetVarName) { if (EMIT_NULL_CHECKS) { writer.print(" if ("); writer.print(sourceVarName); writer.println(" != NULL) {"); } - writer.print(" "); - writer.print(receivingVarName); - writer.print(" = ("); - writer.print(receivingVarTypeString); - writer.print(") (*env)->GetDirectBufferAddress(env, "); - writer.print(sourceVarName); - writer.println(");"); + /* Pre Buffer Offset code: In the case where there is NOT an integer offset + in bytes for the direct buffer, we used to use: + (type*) (*env)->GetDirectBufferAddress(env, buf); + generated as follows: + if(byteOffsetVarName == null) { + writer.print(" "); + writer.print(receivingVarName); + writer.print(" = ("); + writer.print(receivingVarTypeString); + writer.print(") (*env)->GetDirectBufferAddress(env, "); + writer.print(sourceVarName); + writer.println(");"); + */ + + /* In the case (now always the case) where there is an integer offset in bytes for + the direct buffer, we want to use: + _ptrX = (type*) (*env)->GetDirectBufferAddress(env, buf); + _ptrX = (type*) ((char*)buf + __byteOffset); + Note that __byteOffset is an int */ + writer.print(" "); + writer.print(receivingVarName); + writer.print(" = ("); + writer.print(receivingVarTypeString); + + writer.print(") (*env)->GetDirectBufferAddress(env, "); + writer.print(sourceVarName); + writer.println(");"); + + writer.print(" "); + writer.print(receivingVarName); + writer.print(" = ("); + writer.print(receivingVarTypeString); + writer.print(") ((char*)" + receivingVarName + " + "); + writer.println(byteOffsetVarName + ");"); + if (EMIT_NULL_CHECKS) { writer.println(" } else {"); writer.print(" "); @@ -1270,11 +1366,13 @@ public class CMethodBindingEmitter extends FunctionEmitter JavaType type, Type cType, String incomingArgumentName, - String cVariableName) { + String cVariableName, + String byteOffsetVarName) { emitGetDirectBufferAddress(writer, incomingArgumentName, cType.getName(), - cVariableName); + cVariableName, + byteOffsetVarName); /* if (EMIT_NULL_CHECKS) { @@ -1301,6 +1399,15 @@ public class CMethodBindingEmitter extends FunctionEmitter return "_ptr" + i; } + protected String byteOffsetConversionArgName(int i) { + return "__byteOffset" + i; + } + + protected String byteOffsetArrayConversionArgName(int i) { + return "__byteOffsetArray" + i; + } + + /** * Class that emits a generic comment for CMethodBindingEmitters; the comment * includes the C signature of the native method that is being bound by the diff --git a/src/net/java/games/gluegen/CMethodBindingImplEmitter.java b/src/net/java/games/gluegen/CMethodBindingImplEmitter.java index 95f04d235..43e4f4d86 100644 --- a/src/net/java/games/gluegen/CMethodBindingImplEmitter.java +++ b/src/net/java/games/gluegen/CMethodBindingImplEmitter.java @@ -83,6 +83,14 @@ public class CMethodBindingImplEmitter extends CMethodBindingEmitter Class c = type.getJavaClass(); if (c != null) { jniMangle(c, buf); + // Add mangling for buffer offset arguments + if(type.isNIOBuffer()) { + jniMangle(Integer.TYPE, buf); + } else if (type.isNIOBufferArray()) { + int[] intArrayType = new int[0]; + c = intArrayType.getClass(); + jniMangle(c , buf); + } } else { // FIXME: add support for char* -> String conversion throw new RuntimeException("Unknown kind of JavaType: name="+type.getName()); diff --git a/src/net/java/games/gluegen/JavaConfiguration.java b/src/net/java/games/gluegen/JavaConfiguration.java index 73aebb5a8..e4bc0278b 100644 --- a/src/net/java/games/gluegen/JavaConfiguration.java +++ b/src/net/java/games/gluegen/JavaConfiguration.java @@ -119,7 +119,7 @@ public class JavaConfiguration { private Set/*<Pattern>*/ ignores = new HashSet(); private Set/*<Pattern>*/ ignoreNots = new HashSet(); private Set/*<Pattern>*/ unimplemented = new HashSet(); - private Set/*<String>*/ nioOnly = new HashSet(); + private Set/*<String>*/ nioDirectOnly = new HashSet(); /** See {@link #nioMode} */ public static final int NIO_MODE_VOID_ONLY = 1; /** See {@link #nioMode} */ @@ -363,8 +363,8 @@ public class JavaConfiguration { /** Returns true if the given function should only create a java.nio variant, and no array variants, for <code>void*</code> and other C primitive pointers. */ - public boolean nioOnly(String functionName) { - return nioOnly.contains(functionName); + public boolean nioDirectOnly(String functionName) { + return nioDirectOnly.contains(functionName); } /** Returns true if the user requested that the given function @@ -674,8 +674,8 @@ public class JavaConfiguration { readClassJavadoc(tok, filename, lineNo); // Warning: make sure delimiters are reset at the top of this loop // because readClassJavadoc changes them. - } else if (cmd.equalsIgnoreCase("NioOnly")) { - nioOnly.add(readString("NioOnly", tok, filename, lineNo)); + } else if (cmd.equalsIgnoreCase("NioDirectOnly")) { + nioDirectOnly.add(readString("NioDirectOnly", tok, filename, lineNo)); } else if (cmd.equalsIgnoreCase("NoNio")) { noNio.add(readString("NoNio", tok, filename, lineNo)); } else if (cmd.equalsIgnoreCase("ForcedNio")) { @@ -909,7 +909,7 @@ public class JavaConfiguration { * other types (i.e., <code>int*</code>) will have java.nio variants * generated for them (i.e., <code>IntBuffer</code> as opposed to * merely <code>int[]</code>). This default mode can be overridden - * with the NioOnly and NoNio directives. The default for this mode + * with the NioDirectOnly and NoNio directives. The default for this mode * is currently VOID_ONLY. */ protected void readNioMode(StringTokenizer tok, String filename, int lineNo) { diff --git a/src/net/java/games/gluegen/JavaEmitter.java b/src/net/java/games/gluegen/JavaEmitter.java index f635c2d44..0b0186cdd 100644 --- a/src/net/java/games/gluegen/JavaEmitter.java +++ b/src/net/java/games/gluegen/JavaEmitter.java @@ -1256,7 +1256,7 @@ public class JavaEmitter implements GlueEmitter { MethodBinding variant = null; // Non-NIO variants for non-void C primitive pointer types - if (!cfg.nioOnly(mb.getCSymbol().getName()) && !t.isCVoidPointerType() + if (!cfg.nioDirectOnly(mb.getCSymbol().getName()) && !t.isCVoidPointerType() && !cfg.isPrimArrayExpModeNoPtrs()) { if (t.isCCharPointerType()) { variant = mb.createCPrimitivePointerVariant(j, javaType(ArrayTypes.byteArrayClass)); @@ -1286,7 +1286,7 @@ public class JavaEmitter implements GlueEmitter { // Non-NIO variants for void* C primitive pointer type - if (!cfg.nioOnly(mb.getCSymbol().getName()) && t.isCVoidPointerType() + if (!cfg.nioDirectOnly(mb.getCSymbol().getName()) && t.isCVoidPointerType() && cfg.isPrimArrayExpModeAllPtrs()) { if (cfg.voidPointerExpansionToBoolean()) { variant = mb.createCPrimitivePointerVariant(j, javaType(ArrayTypes.booleanArrayClass)); @@ -1332,8 +1332,10 @@ public class JavaEmitter implements GlueEmitter { } // NIO variants for non-void* C primitive pointer types - if ((cfg.nioMode() == JavaConfiguration.NIO_MODE_ALL_POINTERS && !cfg.noNio(mb.getCSymbol().getName())) || - (cfg.nioMode() == JavaConfiguration.NIO_MODE_VOID_ONLY && cfg.forcedNio(mb.getCSymbol().getName()))) { + if ((cfg.nioMode() == JavaConfiguration.NIO_MODE_ALL_POINTERS && + !cfg.noNio(mb.getCSymbol().getName())) || + (cfg.nioMode() == JavaConfiguration.NIO_MODE_VOID_ONLY && + cfg.forcedNio(mb.getCSymbol().getName()))) { if (t.isCCharPointerType()) { variant = mb.createCPrimitivePointerVariant(j, JavaType.forNIOByteBufferClass()); if (! result.contains(variant)) result.add(variant); diff --git a/src/net/java/games/gluegen/JavaMethodBindingEmitter.java b/src/net/java/games/gluegen/JavaMethodBindingEmitter.java index e5b83a26c..d6a34c1d3 100644 --- a/src/net/java/games/gluegen/JavaMethodBindingEmitter.java +++ b/src/net/java/games/gluegen/JavaMethodBindingEmitter.java @@ -65,8 +65,10 @@ public class JavaMethodBindingEmitter extends FunctionEmitter // Exception type raised in the generated code if runtime checks fail private String runtimeExceptionType; - private MethodBinding binding; - private boolean forImplementingMethodCall; + protected MethodBinding binding; + protected boolean forImplementingMethodCall; + + protected boolean prefixedMethod = false; // A non-null value indicates that rather than returning a compound // type accessor we are returning an array of such accessors; this @@ -149,13 +151,16 @@ public class JavaMethodBindingEmitter extends FunctionEmitter { boolean needComma = false; int numEmitted = 0; + int numBufferOffsetArgs = 0, numBufferOffsetArrayArgs = 0; - if (forImplementingMethodCall && binding.hasContainingType()) { + if (forImplementingMethodCall && binding.hasContainingType()) { // Always emit outgoing "this" argument writer.print("java.nio.Buffer "); writer.print(javaThisArgumentName()); ++numEmitted; needComma = true; + numBufferOffsetArgs++; + writer.print(", int " + byteOffsetConversionArgName(numBufferOffsetArgs)); } for (int i = 0; i < binding.getNumArguments(); i++) { @@ -185,15 +190,38 @@ public class JavaMethodBindingEmitter extends FunctionEmitter writer.print(binding.getArgumentName(i)); ++numEmitted; needComma = true; + // Add Buffer offset argument to store the buffer offset + if((forImplementingMethodCall || prefixedMethod) && + (type.isNIOBuffer() || type.isNIOBufferArray())) { + if(!type.isArray()) { + numBufferOffsetArgs++; + writer.print(", int " + byteOffsetConversionArgName(numBufferOffsetArgs)); + } else { + numBufferOffsetArrayArgs++; + writer.print(", int[] " + + byteOffsetArrayConversionArgName(numBufferOffsetArrayArgs)); + } + } } return numEmitted; } + protected String getImplMethodName() { return binding.getName() + "0"; } + + protected String byteOffsetConversionArgName(int i) { + return "__byteOffset" + i; + } + + protected String byteOffsetArrayConversionArgName(int i) { + return "__byteOffsetArray" + i; + } + + protected void emitBody(PrintWriter writer) { writer.println(';'); diff --git a/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java b/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java index dc3dfa629..c1f05b564 100644 --- a/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java +++ b/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java @@ -106,7 +106,9 @@ public class JavaMethodBindingImplEmitter extends JavaMethodBindingEmitter emitArrayLengthAndNIOBufferChecks(binding, writer); } + protected void emitArrayLengthAndNIOBufferChecks(MethodBinding binding, PrintWriter writer) { + int numBufferOffsetArrayArgs = 0; // Check lengths of any incoming arrays if necessary for (int i = 0; i < binding.getNumArguments(); i++) { Type type = binding.getCArgumentType(i); @@ -122,14 +124,21 @@ public class JavaMethodBindingImplEmitter extends JavaMethodBindingEmitter writer.println(" throw new " + getRuntimeExceptionType() + "(\"Argument \\\"" + binding.getArgumentName(i) + "\\\" was not a direct buffer\");"); } else if (javaType.isNIOBufferArray()) { + numBufferOffsetArrayArgs++; String argName = binding.getArgumentName(i); + String arrayName = byteOffsetArrayConversionArgName(numBufferOffsetArrayArgs); + writer.println(" int[] " + arrayName + " = new int[" + argName + ".length];"); // Check direct buffer properties of all buffers within writer.println(" if (" + argName + " != null) {"); writer.println(" for (int _ctr = 0; _ctr < " + argName + ".length; _ctr++) {"); writer.println(" if (!BufferFactory.isDirect(" + argName + "[_ctr])) {"); - writer.println(" throw new " + getRuntimeExceptionType() + "(\"Element \" + _ctr + \" of argument \\\"" + + writer.println(" throw new " + getRuntimeExceptionType() + + "(\"Element \" + _ctr + \" of argument \\\"" + binding.getArgumentName(i) + "\\\" was not a direct buffer\");"); writer.println(" }"); + // get the Buffer Array offset values and save them into another array to send down to JNI + writer.print(" " + arrayName + "[_ctr] = BufferFactory.getPositionByteOffset("); + writer.println(argName + "[_ctr]);"); writer.println(" }"); writer.println(" }"); } @@ -165,12 +174,16 @@ public class JavaMethodBindingImplEmitter extends JavaMethodBindingEmitter protected int emitCallArguments(MethodBinding binding, PrintWriter writer) { boolean needComma = false; int numArgsEmitted = 0; + int numBufferOffsetArgs = 0, numBufferOffsetArrayArgs = 0; if (binding.hasContainingType()) { // Emit this pointer assert(binding.getContainingType().isCompoundTypeWrapper()); writer.print("getBuffer()"); needComma = true; ++numArgsEmitted; + numBufferOffsetArgs++; + //writer.print(", " + byteOffsetConversionArgName(numBufferOffsetArgs)); + writer.print(", BufferFactory.getPositionByteOffset(getBuffer())"); } for (int i = 0; i < binding.getNumArguments(); i++) { JavaType type = binding.getJavaArgumentType(i); @@ -198,9 +211,23 @@ public class JavaMethodBindingImplEmitter extends JavaMethodBindingEmitter writer.print(" == null) ? null : "); writer.print(binding.getArgumentName(i)); writer.print(".getBuffer())"); + numBufferOffsetArgs++; + //writer.print(", " + byteOffsetConversionArgName(numBufferOffsetArgs)); + writer.print(", BufferFactory.getPositionByteOffset(((" + binding.getArgumentName(i)); + writer.print(" == null) ? null : " + binding.getArgumentName(i) + ".getBuffer()))"); } needComma = true; ++numArgsEmitted; + if(type.isNIOBuffer() || type.isNIOBufferArray()) { + if(!type.isArray()) { + numBufferOffsetArgs++; + writer.print + (", BufferFactory.getPositionByteOffset(" + binding.getArgumentName(i) + ")"); + } else { + numBufferOffsetArrayArgs++; + writer.print(", " + byteOffsetArrayConversionArgName(numBufferOffsetArrayArgs)); + } + } } return numArgsEmitted; } diff --git a/src/net/java/games/gluegen/opengl/JavaGLPAWrapperEmitter.java b/src/net/java/games/gluegen/opengl/JavaGLPAWrapperEmitter.java index 1bb06b791..c0bfef081 100644 --- a/src/net/java/games/gluegen/opengl/JavaGLPAWrapperEmitter.java +++ b/src/net/java/games/gluegen/opengl/JavaGLPAWrapperEmitter.java @@ -82,11 +82,15 @@ public class JavaGLPAWrapperEmitter extends JavaMethodBindingImplEmitter } protected int emitArguments(PrintWriter writer) { + // following is set to true so that Buffer offset parameters are generated + // in parent class method, when appropriate + prefixedMethod = true; int numEmitted = super.emitArguments(writer); if (numEmitted > 0) { writer.print(", "); } + writer.print("long glProcAddress"); ++numEmitted; diff --git a/src/net/java/games/gluegen/runtime/BufferFactory.java b/src/net/java/games/gluegen/runtime/BufferFactory.java index 67ffea1d8..67205db5f 100644 --- a/src/net/java/games/gluegen/runtime/BufferFactory.java +++ b/src/net/java/games/gluegen/runtime/BufferFactory.java @@ -40,6 +40,7 @@ package net.java.games.gluegen.runtime; import java.nio.*; +import net.java.games.jogl.util.BufferUtils; public class BufferFactory { public static ByteBuffer newDirectByteBuffer(int size) { @@ -72,4 +73,86 @@ public class BufferFactory { } throw new RuntimeException("Unknown buffer type " + buf.getClass().getName()); } + + + /** Helper routine to get the Buffer byte offset by taking into + account the Buffer position and the underlying type. This is + the total offset for Direct Buffers. */ + + public static int getPositionByteOffset(Buffer buf) { + if(buf == null) { + return 0; + } + if(buf instanceof ByteBuffer) { + return (buf.position()); + } else if (buf instanceof FloatBuffer) { + return (buf.position() * BufferUtils.SIZEOF_FLOAT); + } else if (buf instanceof IntBuffer) { + return (buf.position() * BufferUtils.SIZEOF_INT); + } else if (buf instanceof ShortBuffer) { + return (buf.position() * BufferUtils.SIZEOF_SHORT); + } else if (buf instanceof DoubleBuffer) { + return (buf.position() * BufferUtils.SIZEOF_DOUBLE); + } else if (buf instanceof LongBuffer) { + return (buf.position() * BufferUtils.SIZEOF_LONG); + } + + throw new RuntimeException("Disallowed array backing store type in buffer " + + buf.getClass().getName()); + } + + + /** Helper routine to return the array backing store reference from + a Buffer object. */ + + public static Object getArray(Buffer buf) { + if (buf == null) { + return null; + } + if(buf instanceof ByteBuffer) { + return ((ByteBuffer) buf).array(); + } else if (buf instanceof FloatBuffer) { + return ((FloatBuffer) buf).array(); + } else if (buf instanceof IntBuffer) { + return ((IntBuffer) buf).array(); + } else if (buf instanceof ShortBuffer) { + return ((ShortBuffer) buf).array(); + } else if (buf instanceof DoubleBuffer) { + return ((DoubleBuffer) buf).array(); + } else if (buf instanceof LongBuffer) { + return ((LongBuffer) buf).array(); + } + + throw new RuntimeException("Disallowed array backing store type in buffer " + + buf.getClass().getName()); + } + + + /** Helper routine to get the full byte offset from the beginning of + the array that is the storage for the indirect Buffer + object. The array offset also includes the position offset + within the buffer, in addition to any array offset. */ + + public static int getTotalByteOffset(Buffer buf) { + if(buf == null) { + return 0; + } + int pos = buf.position(); + if(buf instanceof ByteBuffer) { + return (((ByteBuffer)buf).arrayOffset() + pos); + } else if(buf instanceof FloatBuffer) { + return (BufferUtils.SIZEOF_FLOAT*(((FloatBuffer)buf).arrayOffset() + pos)); + } else if(buf instanceof IntBuffer) { + return (BufferUtils.SIZEOF_INT*(((IntBuffer)buf).arrayOffset() + pos)); + } else if(buf instanceof ShortBuffer) { + return (BufferUtils.SIZEOF_SHORT*(((ShortBuffer)buf).arrayOffset() + pos)); + } else if(buf instanceof DoubleBuffer) { + return (BufferUtils.SIZEOF_DOUBLE*(((DoubleBuffer)buf).arrayOffset() + pos)); + } else if(buf instanceof LongBuffer) { + return (BufferUtils.SIZEOF_LONG*(((LongBuffer)buf).arrayOffset() + pos)); + } + + throw new RuntimeException("Unknown buffer type " + buf.getClass().getName()); + } + } diff --git a/src/net/java/games/jogl/util/BufferUtils.java b/src/net/java/games/jogl/util/BufferUtils.java index 1572b749b..1962847e2 100644 --- a/src/net/java/games/jogl/util/BufferUtils.java +++ b/src/net/java/games/jogl/util/BufferUtils.java @@ -48,6 +48,8 @@ public class BufferUtils { public static final int SIZEOF_DOUBLE = 8; public static final int SIZEOF_FLOAT = 4; public static final int SIZEOF_INT = 4; + public static final int SIZEOF_LONG = 8; + public static final int SIZEOF_SHORT = 2; public static DoubleBuffer newDoubleBuffer(int numElements) { ByteBuffer bb = newByteBuffer(numElements * SIZEOF_DOUBLE); |