diff options
author | Kenneth Russel <[email protected]> | 2003-08-07 19:53:38 +0000 |
---|---|---|
committer | Kenneth Russel <[email protected]> | 2003-08-07 19:53:38 +0000 |
commit | db0bdc71eec40d7fcd22ddcea87178c8805d4312 (patch) | |
tree | d04e66f83bcf5eeeaa5283f17a86f9093d678e1c | |
parent | dd16a976876a779dc0ee6da9ebf5ada29f5781c7 (diff) |
Changed glMapBufferARB's implementation to return the same ByteBuffer
if the address and capacity of the underlying buffer object haven't
changed. This saves applications the cost of re-slicing the returned
buffer each frame and avoids allocation of one or more finalizable
objects per frame. Moved GlueGen's checking of whether a passed buffer
is direct up into Java from C to be able to handle buffers that wrap
the NULL pointer (needed for the "buffer offsets" used by
ARB_vertex_buffer_object). Ported the VertexArrayRange demo to
VertexBufferObject. Currently slower than VertexArrayRange but needs
to be updated to triangulate the geometry more efficiently (currently
the triangle strips are only 48 vertices long) and to move the indices
into fast RAM.
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@47 232f8b59-042b-4e1e-8c03-345bb8c30851
-rw-r--r-- | doc/TODO.txt | 3 | ||||
-rw-r--r-- | make/gl-common.cfg | 1 | ||||
-rw-r--r-- | make/gl-impl-CustomCCode.c | 9 | ||||
-rw-r--r-- | make/gl-impl-CustomJavaCode.java | 33 | ||||
-rw-r--r-- | src/native/jogl/InternalBufferUtils.c | 54 | ||||
-rw-r--r-- | src/net/java/games/gluegen/CMethodBindingEmitter.java | 14 | ||||
-rw-r--r-- | src/net/java/games/gluegen/CodeGenUtils.java | 1 | ||||
-rw-r--r-- | src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java | 10 | ||||
-rw-r--r-- | src/net/java/games/gluegen/MethodBinding.java | 4 | ||||
-rw-r--r-- | src/net/java/games/gluegen/runtime/BufferFactory.java | 25 | ||||
-rw-r--r-- | src/net/java/games/jogl/impl/InternalBufferUtils.java | 55 |
11 files changed, 182 insertions, 27 deletions
diff --git a/doc/TODO.txt b/doc/TODO.txt index 6cfd64b23..acfbc951a 100644 --- a/doc/TODO.txt +++ b/doc/TODO.txt @@ -11,6 +11,9 @@ - Fully expose ARB_vertex_buffer_object APIs. +- Fix addNotify()/removeNotify() handling so that adding and removing + a canvas from a window, etc. works properly. + - Test Cg binding on Linux. Find out if Cg is available on Mac OS X. - Finish implementation in GlueGen of <type>** arguments (currently diff --git a/make/gl-common.cfg b/make/gl-common.cfg index 9f2acf1c2..283ae1cc7 100644 --- a/make/gl-common.cfg +++ b/make/gl-common.cfg @@ -6,6 +6,7 @@ RuntimeExceptionType GLException # Imports needed by all glue code Import java.nio.* +Import java.util.* Import net.java.games.jogl.* Import net.java.games.jogl.impl.* diff --git a/make/gl-impl-CustomCCode.c b/make/gl-impl-CustomCCode.c index 1616353d9..0f02f2d48 100644 --- a/make/gl-impl-CustomCCode.c +++ b/make/gl-impl-CustomCCode.c @@ -1,15 +1,14 @@ /* Java->C glue code: * Java package: net.java.games.jogl.impl.windows.WindowsGLImpl - * Java method: java.nio.ByteBuffer dispatch_glMapBufferARB(int target, int access) + * Java method: long dispatch_glMapBufferARB(int target, int access) * C function: LPVOID glMapBufferARB(GLenum target, GLenum access); */ -JNIEXPORT jobject JNICALL -Java_net_java_games_jogl_impl_windows_WindowsGLImpl_dispatch_1glMapBufferARB(JNIEnv *env, jobject _unused, jint target, jint access, jint size, jlong glProcAddress) { +JNIEXPORT jlong JNICALL +Java_net_java_games_jogl_impl_windows_WindowsGLImpl_dispatch_1glMapBufferARB(JNIEnv *env, jobject _unused, jint target, jint access, jlong glProcAddress) { PFNGLMAPBUFFERARBPROC ptr_glMapBufferARB; LPVOID _res; ptr_glMapBufferARB = (PFNGLMAPBUFFERARBPROC) (intptr_t) glProcAddress; assert(ptr_glMapBufferARB != NULL); _res = (* ptr_glMapBufferARB) ((GLenum) target, (GLenum) access); - if (_res == NULL) return NULL; - return (*env)->NewDirectByteBuffer(env, _res, size); + return (jlong) (intptr_t) _res; } diff --git a/make/gl-impl-CustomJavaCode.java b/make/gl-impl-CustomJavaCode.java index 86fac5b5c..bd2be71f6 100644 --- a/make/gl-impl-CustomJavaCode.java +++ b/make/gl-impl-CustomJavaCode.java @@ -1,3 +1,17 @@ +// Attempt to return the same ByteBuffer object from glMapBufferARB if +// the vertex buffer object's base address and size haven't changed +private static class ARBVBOKey { + private long addr; + private int capacity; + + ARBVBOKey(long addr, int capacity) { + this.addr = addr; + this.capacity = capacity; + } +} + +private Map/*<ARBVBOKey, ByteBuffer>*/ arbVBOCache = new HashMap(); + /** Entry point to C language function: <br> <code> LPVOID glMapBufferARB(GLenum target, GLenum access); </code> */ public java.nio.ByteBuffer glMapBufferARB(int target, int access) { final long __addr_ = _context.getGLProcAddressTable()._addressof_glMapBufferARB; @@ -6,11 +20,20 @@ public java.nio.ByteBuffer glMapBufferARB(int target, int access) { } int[] sz = new int[1]; glGetBufferParameterivARB(target, GL_BUFFER_SIZE_ARB, sz); - ByteBuffer _res; - _res = dispatch_glMapBufferARB(target, access, sz[0], __addr_); - if (_res == null) return null; - return _res.order(ByteOrder.nativeOrder()); + long addr; + addr = dispatch_glMapBufferARB(target, access, __addr_); + if (addr == 0 || sz[0] == 0) { + return null; + } + ARBVBOKey key = new ARBVBOKey(addr, sz[0]); + ByteBuffer _res = (ByteBuffer) arbVBOCache.get(key); + if (_res == null) { + _res = InternalBufferUtils.newDirectByteBuffer(addr, sz[0]); + _res.order(ByteOrder.nativeOrder()); + arbVBOCache.put(key, _res); + } + return _res; } /** Encapsulates function pointer for OpenGL function <br>: <code> LPVOID glMapBufferARB(GLenum target, GLenum access); </code> */ -native private java.nio.ByteBuffer dispatch_glMapBufferARB(int target, int access, int size, long glProcAddress); +native private long dispatch_glMapBufferARB(int target, int access, long glProcAddress); diff --git a/src/native/jogl/InternalBufferUtils.c b/src/native/jogl/InternalBufferUtils.c new file mode 100644 index 000000000..395396ac8 --- /dev/null +++ b/src/native/jogl/InternalBufferUtils.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution 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 Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +#include <jni.h> + +#ifdef _MSC_VER + /* This typedef is only needed for VC6 */ + #if _MSC_VER <= 1200 + typedef int intptr_t; + #endif +#else + #include <inttypes.h> +#endif + +JNIEXPORT jobject JNICALL +Java_net_java_games_jogl_impl_InternalBufferUtils_newDirectByteBuffer(JNIEnv* env, jclass unused, jlong address, jint capacity) { + return (*env)->NewDirectByteBuffer(env, (void*) (intptr_t) address, capacity); +} diff --git a/src/net/java/games/gluegen/CMethodBindingEmitter.java b/src/net/java/games/gluegen/CMethodBindingEmitter.java index 763fe6695..27df36cea 100644 --- a/src/net/java/games/gluegen/CMethodBindingEmitter.java +++ b/src/net/java/games/gluegen/CMethodBindingEmitter.java @@ -1205,20 +1205,6 @@ public class CMethodBindingEmitter extends FunctionEmitter writer.print(incomingArgumentName); writer.println(");"); - writer.print(" if ("); - writer.print(cVariableName); - writer.println(" == NULL) {"); - writer.println(" (*env)->ThrowNew(env, (*env)->FindClass(env, \"java/lang/RuntimeException\"),"); - writer.print (" \"Argument \\\""); - writer.print(incomingArgumentName); - writer.println("\\\" was not a direct buffer\");"); - writer.print (" return"); - if (!binding.getJavaReturnType().isVoid()) { - writer.print(" 0"); - } - writer.println(";"); - writer.println(" }"); - if (EMIT_NULL_CHECKS) { writer.println(" }"); } diff --git a/src/net/java/games/gluegen/CodeGenUtils.java b/src/net/java/games/gluegen/CodeGenUtils.java index 313896d13..d982f2390 100644 --- a/src/net/java/games/gluegen/CodeGenUtils.java +++ b/src/net/java/games/gluegen/CodeGenUtils.java @@ -94,6 +94,7 @@ public class CodeGenUtils w.print(imports[i]); w.println(';'); } + w.println("import net.java.games.gluegen.runtime.*;"); w.println(); diff --git a/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java b/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java index 2ec2723bd..78a4a6ced 100644 --- a/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java +++ b/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java @@ -89,10 +89,10 @@ public class JavaMethodBindingImplEmitter extends JavaMethodBindingEmitter } protected void emitPreCallSetup(MethodBinding binding, PrintWriter writer) { - emitArrayLengthChecks(binding, writer); + emitArrayLengthAndNIOBufferChecks(binding, writer); } - protected void emitArrayLengthChecks(MethodBinding binding, PrintWriter writer) { + protected void emitArrayLengthAndNIOBufferChecks(MethodBinding binding, PrintWriter writer) { // Check lengths of any incoming arrays if necessary for (int i = 0; i < binding.getNumArguments(); i++) { Type type = binding.getCArgumentType(i); @@ -101,6 +101,12 @@ public class JavaMethodBindingImplEmitter extends JavaMethodBindingEmitter writer.println(" if (" + binding.getArgumentName(i) + ".length < " + arrayType.getLength() + ")"); writer.println(" throw new " + getRuntimeExceptionType() + "(\"Length of array \\\"" + binding.getArgumentName(i) + "\\\" was less than the required " + arrayType.getLength() + "\");"); + } else { + if (binding.getJavaArgumentType(i).isNIOBuffer()) { + writer.println(" if (!BufferFactory.isDirect(" + binding.getArgumentName(i) + "))"); + writer.println(" throw new " + getRuntimeExceptionType() + "(\"Argument \\\"" + + binding.getArgumentName(i) + "\\\" was not a direct buffer\");"); + } } } } diff --git a/src/net/java/games/gluegen/MethodBinding.java b/src/net/java/games/gluegen/MethodBinding.java index b8f0eefdf..af86f0b66 100644 --- a/src/net/java/games/gluegen/MethodBinding.java +++ b/src/net/java/games/gluegen/MethodBinding.java @@ -184,8 +184,10 @@ public class MethodBinding { JavaType javaArgType = getJavaArgumentType(i); Type cArgType = getCArgumentType(i); if (javaArgType.isCompoundTypeWrapper() || + javaArgType.isNIOBuffer() || cArgType.isArray()) { - // Needs unwrapping of accessors or checking of array lengths + // Needs unwrapping of accessors, checking of array + // lengths, or checking of direct buffer property needsBody = true; break; } diff --git a/src/net/java/games/gluegen/runtime/BufferFactory.java b/src/net/java/games/gluegen/runtime/BufferFactory.java index 2efb78ca6..67ffea1d8 100644 --- a/src/net/java/games/gluegen/runtime/BufferFactory.java +++ b/src/net/java/games/gluegen/runtime/BufferFactory.java @@ -47,4 +47,29 @@ public class BufferFactory { buf.order(ByteOrder.nativeOrder()); return buf; } + + /** Helper routine to tell whether a buffer is direct or not. Null + pointers are considered direct. isDirect() should really be + public in Buffer and not replicated in all subclasses. */ + public static boolean isDirect(Buffer buf) { + if (buf == null) { + return true; + } + if (buf instanceof ByteBuffer) { + return ((ByteBuffer) buf).isDirect(); + } else if (buf instanceof FloatBuffer) { + return ((FloatBuffer) buf).isDirect(); + } else if (buf instanceof DoubleBuffer) { + return ((DoubleBuffer) buf).isDirect(); + } else if (buf instanceof CharBuffer) { + return ((CharBuffer) buf).isDirect(); + } else if (buf instanceof ShortBuffer) { + return ((ShortBuffer) buf).isDirect(); + } else if (buf instanceof IntBuffer) { + return ((IntBuffer) buf).isDirect(); + } else if (buf instanceof LongBuffer) { + return ((LongBuffer) buf).isDirect(); + } + throw new RuntimeException("Unknown buffer type " + buf.getClass().getName()); + } } diff --git a/src/net/java/games/jogl/impl/InternalBufferUtils.java b/src/net/java/games/jogl/impl/InternalBufferUtils.java new file mode 100644 index 000000000..707ebbe93 --- /dev/null +++ b/src/net/java/games/jogl/impl/InternalBufferUtils.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution 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 Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package net.java.games.jogl.impl; + +import java.nio.*; + +/** Utility routines available only to the JOGL implementation. */ + +public class InternalBufferUtils { + /** Allocates a new direct byte buffer at the given address with the + given capacity. This is exposed only because of glMapBufferARB + and its semantics; it is undesirable to allocate a new buffer + every frame because (a) ByteBuffers are finalizable and (b) the + application would typically need to re-slice the buffer every + frame. Instead we cache these ByteBuffer objects up in Java and + look them up in a HashMap by base address and capacity. */ + public static native ByteBuffer newDirectByteBuffer(long address, int capacity); +} |