From: <sp...@us...> - 2011-07-16 16:05:47
|
Revision: 3589 http://java-game-lib.svn.sourceforge.net/java-game-lib/?rev=3589&view=rev Author: spasi Date: 2011-07-16 16:05:37 +0000 (Sat, 16 Jul 2011) Log Message: ----------- Moved all pointer arithmetic to Java code. Modified Paths: -------------- trunk/LWJGL/src/java/org/lwjgl/PointerBuffer.java trunk/LWJGL/src/java/org/lwjgl/opencl/APIUtil.java trunk/LWJGL/src/java/org/lwjgl/opencl/InfoUtilFactory.java trunk/LWJGL/src/java/org/lwjgl/opengl/APIUtil.java trunk/LWJGL/src/java/org/lwjgl/opengles/APIUtil.java trunk/LWJGL/src/java/org/lwjgl/test/mapped/MappedObjectTests3.java trunk/LWJGL/src/java/org/lwjgl/test/opengl/sprites/SpriteShootout.java trunk/LWJGL/src/java/org/lwjgl/test/opengl/sprites/SpriteShootout2P.java trunk/LWJGL/src/java/org/lwjgl/test/opengl/sprites/SpriteShootoutCL.java trunk/LWJGL/src/java/org/lwjgl/util/generator/JNITypeTranslator.java trunk/LWJGL/src/java/org/lwjgl/util/generator/JavaMethodsGenerator.java trunk/LWJGL/src/java/org/lwjgl/util/generator/NativeMethodStubsGenerator.java trunk/LWJGL/src/templates/org/lwjgl/opencl/CL10.java trunk/LWJGL/src/templates/org/lwjgl/opencl/CL10GL.java trunk/LWJGL/src/templates/org/lwjgl/opencl/EXT_migrate_memobject.java trunk/LWJGL/src/templates/org/lwjgl/opengl/AMD_name_gen_delete.java trunk/LWJGL/src/templates/org/lwjgl/opengl/AMD_performance_monitor.java trunk/LWJGL/src/templates/org/lwjgl/opengl/APPLE_fence.java trunk/LWJGL/src/templates/org/lwjgl/opengl/APPLE_vertex_array_object.java trunk/LWJGL/src/templates/org/lwjgl/opengl/ARB_buffer_object.java trunk/LWJGL/src/templates/org/lwjgl/opengl/ARB_draw_buffers.java trunk/LWJGL/src/templates/org/lwjgl/opengl/ARB_framebuffer_object.java trunk/LWJGL/src/templates/org/lwjgl/opengl/ARB_occlusion_query.java trunk/LWJGL/src/templates/org/lwjgl/opengl/ARB_program.java trunk/LWJGL/src/templates/org/lwjgl/opengl/ARB_sampler_objects.java trunk/LWJGL/src/templates/org/lwjgl/opengl/ARB_separate_shader_objects.java trunk/LWJGL/src/templates/org/lwjgl/opengl/ARB_shader_objects.java trunk/LWJGL/src/templates/org/lwjgl/opengl/ARB_shading_language_include.java trunk/LWJGL/src/templates/org/lwjgl/opengl/ARB_transform_feedback2.java trunk/LWJGL/src/templates/org/lwjgl/opengl/ARB_vertex_array_object.java trunk/LWJGL/src/templates/org/lwjgl/opengl/ARB_vertex_shader.java trunk/LWJGL/src/templates/org/lwjgl/opengl/ATI_draw_buffers.java trunk/LWJGL/src/templates/org/lwjgl/opengl/EXT_direct_state_access.java trunk/LWJGL/src/templates/org/lwjgl/opengl/EXT_framebuffer_object.java trunk/LWJGL/src/templates/org/lwjgl/opengl/EXT_texture_integer.java trunk/LWJGL/src/templates/org/lwjgl/opengl/EXT_transform_feedback.java trunk/LWJGL/src/templates/org/lwjgl/opengl/GL11.java trunk/LWJGL/src/templates/org/lwjgl/opengl/GL15.java trunk/LWJGL/src/templates/org/lwjgl/opengl/GL20.java trunk/LWJGL/src/templates/org/lwjgl/opengl/GL30.java trunk/LWJGL/src/templates/org/lwjgl/opengl/GL31.java trunk/LWJGL/src/templates/org/lwjgl/opengl/GL32.java trunk/LWJGL/src/templates/org/lwjgl/opengl/GL33.java trunk/LWJGL/src/templates/org/lwjgl/opengl/GL40.java trunk/LWJGL/src/templates/org/lwjgl/opengl/GL41.java trunk/LWJGL/src/templates/org/lwjgl/opengl/NV_fence.java trunk/LWJGL/src/templates/org/lwjgl/opengl/NV_occlusion_query.java trunk/LWJGL/src/templates/org/lwjgl/opengl/NV_program.java trunk/LWJGL/src/templates/org/lwjgl/opengl/NV_transform_feedback.java trunk/LWJGL/src/templates/org/lwjgl/opengl/NV_transform_feedback2.java trunk/LWJGL/src/templates/org/lwjgl/opengles/AMD_performance_monitor.java trunk/LWJGL/src/templates/org/lwjgl/opengles/ARB_draw_buffers.java trunk/LWJGL/src/templates/org/lwjgl/opengles/GLES20.java trunk/LWJGL/src/templates/org/lwjgl/opengles/NV_draw_buffers.java trunk/LWJGL/src/templates/org/lwjgl/opengles/NV_fence.java trunk/LWJGL/src/templates/org/lwjgl/opengles/OES_framebuffer_object.java trunk/LWJGL/src/templates/org/lwjgl/opengles/OES_vertex_array_object.java trunk/LWJGL/src/templates/org/lwjgl/opengles/QCOM_driver_control.java Added Paths: ----------- trunk/LWJGL/src/java/org/lwjgl/MemoryUtil.java trunk/LWJGL/src/java/org/lwjgl/MemoryUtilSun.java trunk/LWJGL/src/java/org/lwjgl/test/opengl/sprites/StreamVBO.java Added: trunk/LWJGL/src/java/org/lwjgl/MemoryUtil.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/MemoryUtil.java (rev 0) +++ trunk/LWJGL/src/java/org/lwjgl/MemoryUtil.java 2011-07-16 16:05:37 UTC (rev 3589) @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2002-2011 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * 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; + +import java.lang.reflect.Field; +import java.nio.*; + +/** + * [INTERNAL USE ONLY] + * <p/> + * This class provides utility methods for passing buffer addresses to JNI API calls. + * + * @author Spasi + */ +public final class MemoryUtil { + + private static final Accessor memUtil; + + static { + Accessor util; + try { + // Depends on java.nio.Buffer#address and sun.misc.Unsafe + //util = loadAccessor("org.lwjgl.MemoryUtilSun$AccessorUnsafe"); + util = new AccessorJNI(); + } catch (Exception e0) { + try { + // Depends on java.nio.Buffer#address and sun.reflect.FieldAccessor + util = loadAccessor("org.lwjgl.MemoryUtilSun$AccessorReflectFast"); + } catch (Exception e1) { + try { + // Depends on java.nio.Buffer#address + util = new AccessorReflect(); + } catch (Exception e2) { + LWJGLUtil.log("Unsupported JVM detected, this will likely result in low performance. Please inform LWJGL developers."); + util = new AccessorJNI(); + } + } + } + + LWJGLUtil.log("MemoryUtil Accessor: " + util.getClass().getSimpleName()); + memUtil = util; + + /* + BENCHMARK RESULTS - Oracle Server VM: + + Unsafe: 4ns + ReflectFast: 8ns + Reflect: 10ns + JNI: 82ns + + BENCHMARK RESULTS - Oracle Client VM: + + Unsafe: 5ns + ReflectFast: 81ns + Reflect: 85ns + JNI: 87ns + + On non-Oracle VMs, Unsafe should be the fastest implementation as well. In the absence + of Unsafe, performance will depend on how reflection and JNI are implemented. For now + we'll go with what we see on the Oracle VM (that is, we'll prefer reflection over JNI). + */ + } + + private MemoryUtil() { + } + + public static String wrap(final String test) { + return "MemoryUtil.getAddress(" + test + ")"; + } + + /** + * Returns the memory address of the specified buffer. [INTERNAL USE ONLY] + * + * @param buffer the buffer + * + * @return the memory address + */ + public static long getAddress0(Buffer buffer) { return memUtil.getAddress(buffer); } + + public static long getAddress0Safe(Buffer buffer) { return buffer == null ? 0L : memUtil.getAddress(buffer); } + + public static long getAddress0(PointerBuffer buffer) { return memUtil.getAddress(buffer.getBuffer()); } + + public static long getAddress0Safe(PointerBuffer buffer) { return buffer == null ? 0L : memUtil.getAddress(buffer.getBuffer()); } + + // --- [ API utilities ] --- + + public static long getAddress(ByteBuffer buffer) { return getAddress(buffer, buffer.position()); } + + public static long getAddress(ByteBuffer buffer, int position) { return getAddress0(buffer) + position; } + + public static long getAddress(ShortBuffer buffer) { return getAddress(buffer, buffer.position()); } + + public static long getAddress(ShortBuffer buffer, int position) { return getAddress0(buffer) + (position << 1); } + + public static long getAddress(CharBuffer buffer) { return getAddress(buffer, buffer.position()); } + + public static long getAddress(CharBuffer buffer, int position) { return getAddress0(buffer) + (position << 1); } + + public static long getAddress(IntBuffer buffer) { return getAddress(buffer, buffer.position()); } + + public static long getAddress(IntBuffer buffer, int position) { return getAddress0(buffer) + (position << 2); } + + public static long getAddress(FloatBuffer buffer) { return getAddress(buffer, buffer.position()); } + + public static long getAddress(FloatBuffer buffer, int position) { return getAddress0(buffer) + (position << 2); } + + public static long getAddress(LongBuffer buffer) { return getAddress(buffer, buffer.position()); } + + public static long getAddress(LongBuffer buffer, int position) { return getAddress0(buffer) + (position << 3); } + + public static long getAddress(DoubleBuffer buffer) { return getAddress(buffer, buffer.position()); } + + public static long getAddress(DoubleBuffer buffer, int position) { return getAddress0(buffer) + (position << 3); } + + public static long getAddress(PointerBuffer buffer) { return getAddress(buffer, buffer.position()); } + + public static long getAddress(PointerBuffer buffer, int position) { return getAddress0(buffer) + (position * PointerBuffer.getPointerSize()); } + + // --- [ API utilities - Safe ] --- + + public static long getAddressSafe(ByteBuffer buffer) { return buffer == null ? 0L : getAddress(buffer); } + + public static long getAddressSafe(ByteBuffer buffer, int position) { return buffer == null ? 0L : getAddress(buffer, position); } + + public static long getAddressSafe(ShortBuffer buffer) { return buffer == null ? 0L : getAddress(buffer); } + + public static long getAddressSafe(ShortBuffer buffer, int position) { return buffer == null ? 0L : getAddress(buffer, position); } + + public static long getAddressSafe(CharBuffer buffer) { return buffer == null ? 0L : getAddress(buffer); } + + public static long getAddressSafe(CharBuffer buffer, int position) { return buffer == null ? 0L : getAddress(buffer, position); } + + public static long getAddressSafe(IntBuffer buffer) { return buffer == null ? 0L : getAddress(buffer); } + + public static long getAddressSafe(IntBuffer buffer, int position) { return buffer == null ? 0L : getAddress(buffer, position); } + + public static long getAddressSafe(FloatBuffer buffer) { return buffer == null ? 0L : getAddress(buffer); } + + public static long getAddressSafe(FloatBuffer buffer, int position) { return buffer == null ? 0L : getAddress(buffer, position); } + + public static long getAddressSafe(LongBuffer buffer) { return buffer == null ? 0L : getAddress(buffer); } + + public static long getAddressSafe(LongBuffer buffer, int position) { return buffer == null ? 0L : getAddress(buffer, position); } + + public static long getAddressSafe(DoubleBuffer buffer) { return buffer == null ? 0L : getAddress(buffer); } + + public static long getAddressSafe(DoubleBuffer buffer, int position) { return buffer == null ? 0L : getAddress(buffer, position); } + + public static long getAddressSafe(PointerBuffer buffer) { return buffer == null ? 0L : getAddress(buffer); } + + public static long getAddressSafe(PointerBuffer buffer, int position) { return buffer == null ? 0L : getAddress(buffer, position); } + + interface Accessor { + + long getAddress(Buffer buffer); + + } + + private static Accessor loadAccessor(final String className) throws Exception { + return (Accessor)Class.forName(className).newInstance(); + } + + /** Default implementation. */ + private static class AccessorJNI implements Accessor { + + public long getAddress(final Buffer buffer) { + return BufferUtils.getBufferAddress(buffer); + } + + } + + /** Implementation using reflection on ByteBuffer. */ + private static class AccessorReflect implements Accessor { + + private final Field address; + + AccessorReflect() { + try { + address = getAddressField(); + } catch (NoSuchFieldException e) { + throw new UnsupportedOperationException(e); + } + address.setAccessible(true); + } + + public long getAddress(final Buffer buffer) { + try { + return address.getLong(buffer); + } catch (IllegalAccessException e) { + // cannot happen + return 0L; + } + } + + } + + static Field getAddressField() throws NoSuchFieldException { + return getDeclaredFieldRecursive(ByteBuffer.class, "address"); + } + + private static Field getDeclaredFieldRecursive(Class<?> type, final String fieldName) throws NoSuchFieldException { + while ( type != null ) { + try { + return type.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + type = type.getSuperclass(); + } + } + + throw new NoSuchFieldException(fieldName + " does not exist in " + type.getSimpleName() + " or any of its superclasses."); + } + +} \ No newline at end of file Added: trunk/LWJGL/src/java/org/lwjgl/MemoryUtilSun.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/MemoryUtilSun.java (rev 0) +++ trunk/LWJGL/src/java/org/lwjgl/MemoryUtilSun.java 2011-07-16 16:05:37 UTC (rev 3589) @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2002-2011 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * 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; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.nio.Buffer; + +import sun.misc.Unsafe; +import sun.reflect.FieldAccessor; + +/** + * MemoryUtil.Accessor implementations that depend on sun.misc. + * We use reflection to grab these, so that we can compile on JDKs + * that do not support sun.misc. + * + * @author Spasi + */ +final class MemoryUtilSun { + + private MemoryUtilSun() { + } + + /** Implementation using sun.misc.Unsafe. */ + private static class AccessorUnsafe implements MemoryUtil.Accessor { + + private final Unsafe unsafe; + private final long address; + + AccessorUnsafe() { + try { + unsafe = getUnsafeInstance(); + address = unsafe.objectFieldOffset(MemoryUtil.getAddressField()); + } catch (Exception e) { + throw new UnsupportedOperationException(e); + } + } + + public long getAddress(final Buffer buffer) { + return unsafe.getLong(buffer, address); + } + + private static Unsafe getUnsafeInstance() { + final Field[] fields = Unsafe.class.getDeclaredFields(); + + /* + Different runtimes use different names for the Unsafe singleton, + so we cannot use .getDeclaredField and we scan instead. For example: + + Oracle: theUnsafe + PERC : m_unsafe_instance + Android: THE_ONE + */ + for ( Field field : fields ) { + if ( !field.getType().equals(Unsafe.class) ) + continue; + + final int modifiers = field.getModifiers(); + if ( !(Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) ) + continue; + + field.setAccessible(true); + try { + return (Unsafe)field.get(null); + } catch (IllegalAccessException e) { + // ignore + } + break; + } + + throw new UnsupportedOperationException(); + } + + } + + /** Implementation using reflection on ByteBuffer, FieldAccessor is used directly. */ + private static class AccessorReflectFast implements MemoryUtil.Accessor { + + private final FieldAccessor addressAccessor; + + AccessorReflectFast() { + Field address; + try { + address = MemoryUtil.getAddressField(); + } catch (NoSuchFieldException e) { + throw new UnsupportedOperationException(e); + } + address.setAccessible(true); + + try { + Method m = Field.class.getDeclaredMethod("acquireFieldAccessor", boolean.class); + m.setAccessible(true); + addressAccessor = (FieldAccessor)m.invoke(address, true); + } catch (Exception e) { + throw new UnsupportedOperationException(e); + } + } + + public long getAddress(final Buffer buffer) { + return addressAccessor.getLong(buffer); + } + + } + +} \ No newline at end of file Modified: trunk/LWJGL/src/java/org/lwjgl/PointerBuffer.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/PointerBuffer.java 2011-07-14 23:11:41 UTC (rev 3588) +++ trunk/LWJGL/src/java/org/lwjgl/PointerBuffer.java 2011-07-16 16:05:37 UTC (rev 3589) @@ -99,7 +99,7 @@ throw new IllegalArgumentException("The source buffer is not direct."); final int alignment = is64Bit ? 8 : 4; - if ( (BufferUtils.getBufferAddress(source) + source.position()) % alignment != 0 || source.remaining() % alignment != 0 ) + if ( (MemoryUtil.getAddress0(source) + source.position()) % alignment != 0 || source.remaining() % alignment != 0 ) throw new IllegalArgumentException("The source buffer is not aligned to " + alignment + " bytes."); } Modified: trunk/LWJGL/src/java/org/lwjgl/opencl/APIUtil.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/opencl/APIUtil.java 2011-07-14 23:11:41 UTC (rev 3588) +++ trunk/LWJGL/src/java/org/lwjgl/opencl/APIUtil.java 2011-07-16 16:05:37 UTC (rev 3589) @@ -31,9 +31,7 @@ */ package org.lwjgl.opencl; -import org.lwjgl.BufferUtils; -import org.lwjgl.LWJGLUtil; -import org.lwjgl.PointerBuffer; +import org.lwjgl.*; import org.lwjgl.opencl.FastLongMap.Entry; import java.nio.*; @@ -53,7 +51,7 @@ */ final class APIUtil { - private static final int INITIAL_BUFFER_SIZE = 256; + private static final int INITIAL_BUFFER_SIZE = 256; private static final int INITIAL_LENGTHS_SIZE = 4; private static final int BUFFERS_SIZE = 32; @@ -223,10 +221,10 @@ * * @return the String as a ByteBuffer */ - static ByteBuffer getBuffer(final CharSequence string) { + static long getBuffer(final CharSequence string) { final ByteBuffer buffer = encode(getBufferByte(string.length()), string); buffer.flip(); - return buffer; + return MemoryUtil.getAddress0(buffer); } /** @@ -236,10 +234,10 @@ * * @return the String as a ByteBuffer */ - static ByteBuffer getBuffer(final CharSequence string, final int offset) { + static long getBuffer(final CharSequence string, final int offset) { final ByteBuffer buffer = encode(getBufferByteOffset(offset + string.length()), string); buffer.flip(); - return buffer; + return MemoryUtil.getAddress(buffer); } /** @@ -249,11 +247,11 @@ * * @return the String as a ByteBuffer */ - static ByteBuffer getBufferNT(final CharSequence string) { + static long getBufferNT(final CharSequence string) { final ByteBuffer buffer = encode(getBufferByte(string.length() + 1), string); buffer.put((byte)0); buffer.flip(); - return buffer; + return MemoryUtil.getAddress0(buffer); } static int getTotalLength(final CharSequence[] strings) { @@ -271,14 +269,14 @@ * * @return the Strings as a ByteBuffer */ - static ByteBuffer getBuffer(final CharSequence[] strings) { + static long getBuffer(final CharSequence[] strings) { final ByteBuffer buffer = getBufferByte(getTotalLength(strings)); for ( CharSequence string : strings ) encode(buffer, string); buffer.flip(); - return buffer; + return MemoryUtil.getAddress0(buffer); } /** @@ -288,7 +286,7 @@ * * @return the Strings as a ByteBuffer */ - static ByteBuffer getBufferNT(final CharSequence[] strings) { + static long getBufferNT(final CharSequence[] strings) { final ByteBuffer buffer = getBufferByte(getTotalLength(strings) + strings.length); for ( CharSequence string : strings ) { @@ -297,7 +295,7 @@ } buffer.flip(); - return buffer; + return MemoryUtil.getAddress0(buffer); } /** @@ -307,14 +305,14 @@ * * @return the String lengths in a PointerBuffer */ - static PointerBuffer getLengths(final CharSequence[] strings) { + static long getLengths(final CharSequence[] strings) { PointerBuffer buffer = getLengths(strings.length); for ( CharSequence string : strings ) buffer.put(string.length()); buffer.flip(); - return buffer; + return MemoryUtil.getAddress0(buffer); } /** @@ -324,14 +322,14 @@ * * @return the buffer lengths in a PointerBuffer */ - static PointerBuffer getLengths(final ByteBuffer[] buffers) { + static long getLengths(final ByteBuffer[] buffers) { PointerBuffer lengths = getLengths(buffers.length); for ( ByteBuffer buffer : buffers ) lengths.put(buffer.remaining()); lengths.flip(); - return lengths; + return MemoryUtil.getAddress0(lengths); } static int getSize(final PointerBuffer lengths) { @@ -342,14 +340,22 @@ return (int)size; } + static long getPointer(final PointerWrapper pointer) { + return MemoryUtil.getAddress0(getBufferPointer().put(0, pointer)); + } + + static long getPointerSafe(final PointerWrapper pointer) { + return MemoryUtil.getAddress0(getBufferPointer().put(0, pointer == null ? 0L : pointer.getPointer())); + } + private static class Buffers { final ShortBuffer shorts; - final IntBuffer ints; - final IntBuffer intsDebug; - final LongBuffer longs; + final IntBuffer ints; + final IntBuffer intsDebug; + final LongBuffer longs; - final FloatBuffer floats; + final FloatBuffer floats; final DoubleBuffer doubles; final PointerBuffer pointers; @@ -513,25 +519,25 @@ } } - private static final ObjectDestructor<CLDevice> DESTRUCTOR_CLSubDevice = new ObjectDestructor<CLDevice>() { + private static final ObjectDestructor<CLDevice> DESTRUCTOR_CLSubDevice = new ObjectDestructor<CLDevice>() { public void release(final CLDevice object) { clReleaseDeviceEXT(object); } }; - private static final ObjectDestructor<CLMem> DESTRUCTOR_CLMem = new ObjectDestructor<CLMem>() { + private static final ObjectDestructor<CLMem> DESTRUCTOR_CLMem = new ObjectDestructor<CLMem>() { public void release(final CLMem object) { clReleaseMemObject(object); } }; private static final ObjectDestructor<CLCommandQueue> DESTRUCTOR_CLCommandQueue = new ObjectDestructor<CLCommandQueue>() { public void release(final CLCommandQueue object) { clReleaseCommandQueue(object); } }; - private static final ObjectDestructor<CLSampler> DESTRUCTOR_CLSampler = new ObjectDestructor<CLSampler>() { + private static final ObjectDestructor<CLSampler> DESTRUCTOR_CLSampler = new ObjectDestructor<CLSampler>() { public void release(final CLSampler object) { clReleaseSampler(object); } }; - private static final ObjectDestructor<CLProgram> DESTRUCTOR_CLProgram = new ObjectDestructor<CLProgram>() { + private static final ObjectDestructor<CLProgram> DESTRUCTOR_CLProgram = new ObjectDestructor<CLProgram>() { public void release(final CLProgram object) { clReleaseProgram(object); } }; - private static final ObjectDestructor<CLKernel> DESTRUCTOR_CLKernel = new ObjectDestructor<CLKernel>() { + private static final ObjectDestructor<CLKernel> DESTRUCTOR_CLKernel = new ObjectDestructor<CLKernel>() { public void release(final CLKernel object) { clReleaseKernel(object); } }; - private static final ObjectDestructor<CLEvent> DESTRUCTOR_CLEvent = new ObjectDestructor<CLEvent>() { + private static final ObjectDestructor<CLEvent> DESTRUCTOR_CLEvent = new ObjectDestructor<CLEvent>() { public void release(final CLEvent object) { clReleaseEvent(object); } }; Modified: trunk/LWJGL/src/java/org/lwjgl/opencl/InfoUtilFactory.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/opencl/InfoUtilFactory.java 2011-07-14 23:11:41 UTC (rev 3588) +++ trunk/LWJGL/src/java/org/lwjgl/opencl/InfoUtilFactory.java 2011-07-16 16:05:37 UTC (rev 3589) @@ -118,7 +118,7 @@ final long user_data = pfn_notify == null || pfn_notify.isCustom() ? 0 : CallbackUtil.createGlobalRef(pfn_notify); CLContext __result = null; try { - __result = new CLContext(nclCreateContext(properties.getBuffer(), 0, devices.size(), properties.getBuffer(), propertyCount, pfn_notify == null ? 0 : pfn_notify.getPointer(), user_data, errcode_ret, errcode_ret != null ? errcode_ret.position() : 0, function_pointer), platform); + __result = new CLContext(nclCreateContext(MemoryUtil.getAddress0(properties.getBuffer()), devices.size(), MemoryUtil.getAddress(properties, propertyCount), pfn_notify == null ? 0 : pfn_notify.getPointer(), user_data, MemoryUtil.getAddressSafe(errcode_ret), function_pointer), platform); if ( LWJGLUtil.DEBUG ) Util.checkCLError(errcode_ret.get(0)); return __result; @@ -304,9 +304,9 @@ else if ( LWJGLUtil.DEBUG ) errcode_ret = APIUtil.getBufferInt(); - CLMem __result = new CLMem(nclCreateImage2D(context.getPointer(), flags, formatBuffer, 0, image_width, image_height, image_row_pitch, host_ptr, - host_ptr != null ? BufferChecks.checkBuffer(host_ptr, CLChecks.calculateImage2DSize(formatBuffer, image_width, image_height, image_row_pitch)) : 0, - errcode_ret, errcode_ret != null ? errcode_ret.position() : 0, function_pointer), context); + CLMem __result = new CLMem(nclCreateImage2D(context.getPointer(), flags, MemoryUtil.getAddress(formatBuffer, 0), image_width, image_height, image_row_pitch, MemoryUtil.getAddress0Safe(host_ptr) + + (host_ptr != null ? BufferChecks.checkBuffer(host_ptr, CLChecks.calculateImage2DSize(formatBuffer, image_width, image_height, image_row_pitch)) : 0), + MemoryUtil.getAddressSafe(errcode_ret), function_pointer), context); if ( LWJGLUtil.DEBUG ) Util.checkCLError(errcode_ret.get(0)); return __result; @@ -324,9 +324,9 @@ else if ( LWJGLUtil.DEBUG ) errcode_ret = APIUtil.getBufferInt(); - CLMem __result = new CLMem(nclCreateImage3D(context.getPointer(), flags, formatBuffer, 0, image_width, image_height, image_depth, image_row_pitch, image_slice_pitch, host_ptr, - host_ptr != null ? BufferChecks.checkBuffer(host_ptr, CLChecks.calculateImage3DSize(formatBuffer, image_width, image_height, image_depth, image_row_pitch, image_slice_pitch)) : 0, - errcode_ret, errcode_ret != null ? errcode_ret.position() : 0, function_pointer), context); + CLMem __result = new CLMem(nclCreateImage3D(context.getPointer(), flags, MemoryUtil.getAddress(formatBuffer, 0), image_width, image_height, image_depth, image_row_pitch, image_slice_pitch, MemoryUtil.getAddress0Safe(host_ptr) + + (host_ptr != null ? BufferChecks.checkBuffer(host_ptr, CLChecks.calculateImage3DSize(formatBuffer, image_width, image_height, image_depth, image_row_pitch, image_slice_pitch)) : 0), + MemoryUtil.getAddressSafe(errcode_ret), function_pointer), context); if ( LWJGLUtil.DEBUG ) Util.checkCLError(errcode_ret.get(0)); return __result; Modified: trunk/LWJGL/src/java/org/lwjgl/opengl/APIUtil.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/opengl/APIUtil.java 2011-07-14 23:11:41 UTC (rev 3588) +++ trunk/LWJGL/src/java/org/lwjgl/opengl/APIUtil.java 2011-07-16 16:05:37 UTC (rev 3589) @@ -33,6 +33,7 @@ import org.lwjgl.BufferUtils; import org.lwjgl.LWJGLUtil; +import org.lwjgl.MemoryUtil; import java.nio.*; @@ -185,10 +186,10 @@ * * @return the String as a ByteBuffer */ - static ByteBuffer getBuffer(final CharSequence string) { + static long getBuffer(final CharSequence string) { final ByteBuffer buffer = encode(getBufferByte(string.length()), string); buffer.flip(); - return buffer; + return MemoryUtil.getAddress0(buffer); } /** @@ -198,10 +199,10 @@ * * @return the String as a ByteBuffer */ - static ByteBuffer getBuffer(final CharSequence string, final int offset) { + static long getBuffer(final CharSequence string, final int offset) { final ByteBuffer buffer = encode(getBufferByteOffset(offset + string.length()), string); buffer.flip(); - return buffer; + return MemoryUtil.getAddress(buffer); } /** @@ -211,11 +212,11 @@ * * @return the String as a ByteBuffer */ - static ByteBuffer getBufferNT(final CharSequence string) { + static long getBufferNT(final CharSequence string) { final ByteBuffer buffer = encode(getBufferByte(string.length() + 1), string); buffer.put((byte)0); buffer.flip(); - return buffer; + return MemoryUtil.getAddress0(buffer); } static int getTotalLength(final CharSequence[] strings) { @@ -233,14 +234,14 @@ * * @return the Strings as a ByteBuffer */ - static ByteBuffer getBuffer(final CharSequence[] strings) { + static long getBuffer(final CharSequence[] strings) { final ByteBuffer buffer = getBufferByte(getTotalLength(strings)); for ( CharSequence string : strings ) encode(buffer, string); buffer.flip(); - return buffer; + return MemoryUtil.getAddress0(buffer); } /** @@ -250,7 +251,7 @@ * * @return the Strings as a ByteBuffer */ - static ByteBuffer getBufferNT(final CharSequence[] strings) { + static long getBufferNT(final CharSequence[] strings) { final ByteBuffer buffer = getBufferByte(getTotalLength(strings) + strings.length); for ( CharSequence string : strings ) { @@ -259,7 +260,7 @@ } buffer.flip(); - return buffer; + return MemoryUtil.getAddress0(buffer); } /** @@ -269,16 +270,24 @@ * * @return the String lengths in an IntBuffer */ - static IntBuffer getLengths(final CharSequence[] strings) { + static long getLengths(final CharSequence[] strings) { IntBuffer buffer = getLengths(strings.length); for ( CharSequence string : strings ) buffer.put(string.length()); buffer.flip(); - return buffer; + return MemoryUtil.getAddress0(buffer); } + static long getInt(final int value) { + return MemoryUtil.getAddress0(getBufferInt().put(0, value)); + } + + static long getBufferByte0() { + return MemoryUtil.getAddress0(getBufferByte(0)); + } + private static class Buffers { final ShortBuffer shorts; Modified: trunk/LWJGL/src/java/org/lwjgl/opengles/APIUtil.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/opengles/APIUtil.java 2011-07-14 23:11:41 UTC (rev 3588) +++ trunk/LWJGL/src/java/org/lwjgl/opengles/APIUtil.java 2011-07-16 16:05:37 UTC (rev 3589) @@ -33,6 +33,7 @@ import org.lwjgl.BufferUtils; import org.lwjgl.LWJGLUtil; +import org.lwjgl.MemoryUtil; import org.lwjgl.PointerBuffer; import java.nio.ByteBuffer; @@ -207,10 +208,10 @@ * * @return the String as a ByteBuffer */ - static ByteBuffer getBuffer(final CharSequence string) { + static long getBuffer(final CharSequence string) { final ByteBuffer buffer = encode(getBufferByte(string.length()), string); buffer.flip(); - return buffer; + return MemoryUtil.getAddress0(buffer); } /** @@ -220,10 +221,10 @@ * * @return the String as a ByteBuffer */ - static ByteBuffer getBuffer(final CharSequence string, final int offset) { + static long getBuffer(final CharSequence string, final int offset) { final ByteBuffer buffer = encode(getBufferByteOffset(offset + string.length()), string); buffer.flip(); - return buffer; + return MemoryUtil.getAddress(buffer); } /** @@ -233,11 +234,11 @@ * * @return the String as a ByteBuffer */ - static ByteBuffer getBufferNT(final CharSequence string) { + static long getBufferNT(final CharSequence string) { final ByteBuffer buffer = encode(getBufferByte(string.length() + 1), string); buffer.put((byte)0); buffer.flip(); - return buffer; + return MemoryUtil.getAddress0(buffer); } static int getTotalLength(final CharSequence[] strings) { @@ -255,14 +256,14 @@ * * @return the Strings as a ByteBuffer */ - static ByteBuffer getBuffer(final CharSequence[] strings) { + static long getBuffer(final CharSequence[] strings) { final ByteBuffer buffer = getBufferByte(getTotalLength(strings)); for ( CharSequence string : strings ) encode(buffer, string); buffer.flip(); - return buffer; + return MemoryUtil.getAddress0(buffer); } /** @@ -272,7 +273,7 @@ * * @return the Strings as a ByteBuffer */ - static ByteBuffer getBufferNT(final CharSequence[] strings) { + static long getBufferNT(final CharSequence[] strings) { final ByteBuffer buffer = getBufferByte(getTotalLength(strings) + strings.length); for ( CharSequence string : strings ) { @@ -281,7 +282,7 @@ } buffer.flip(); - return buffer; + return MemoryUtil.getAddress0(buffer); } /** @@ -291,16 +292,24 @@ * * @return the String lengths in an IntBuffer */ - static IntBuffer getLengths(final CharSequence[] strings) { + static long getLengths(final CharSequence[] strings) { IntBuffer buffer = getLengths(strings.length); for ( CharSequence string : strings ) buffer.put(string.length()); buffer.flip(); - return buffer; + return MemoryUtil.getAddress0(buffer); } + static long getInt(final int value) { + return MemoryUtil.getAddress(getBufferInt().put(0, value), 0); + } + + static long getBufferByte0() { + return MemoryUtil.getAddress0(getBufferByte(0)); + } + private static class Buffers { final ShortBuffer shorts; Modified: trunk/LWJGL/src/java/org/lwjgl/test/mapped/MappedObjectTests3.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/test/mapped/MappedObjectTests3.java 2011-07-14 23:11:41 UTC (rev 3588) +++ trunk/LWJGL/src/java/org/lwjgl/test/mapped/MappedObjectTests3.java 2011-07-16 16:05:37 UTC (rev 3589) @@ -118,6 +118,10 @@ set.view = 0; assert (vec2.view == 0); assert (vec3.view == 0); + + set.next(); + assert (vec2.view == 1); + assert (vec3.view == 1); } } \ No newline at end of file Modified: trunk/LWJGL/src/java/org/lwjgl/test/opengl/sprites/SpriteShootout.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/test/opengl/sprites/SpriteShootout.java 2011-07-14 23:11:41 UTC (rev 3588) +++ trunk/LWJGL/src/java/org/lwjgl/test/opengl/sprites/SpriteShootout.java 2011-07-16 16:05:37 UTC (rev 3589) @@ -1,3 +1,34 @@ +/* + * Copyright (c) 2002-2011 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * 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.test.opengl.sprites; import org.lwjgl.BufferUtils; @@ -33,8 +64,8 @@ */ public final class SpriteShootout { - private static final int SCREEN_WIDTH = 800; - private static final int SCREEN_HEIGHT = 600; + static final int SCREEN_WIDTH = 800; + static final int SCREEN_HEIGHT = 600; private static final int ANIMATION_TICKS = 60; @@ -45,8 +76,8 @@ private boolean smooth; private boolean vsync; - private int ballSize = 42; - private int ballCount = 100 * 1000; + int ballSize = 42; + int ballCount = 100 * 1000; private SpriteRenderer renderer; @@ -401,43 +432,45 @@ transform = newTransform; } - protected void animate(final FloatBuffer geom, final int ballIndex, final int batchSize, final int delta) { - final float[] transform = this.transform; - + protected void animate( + final float[] sprites, + final FloatBuffer spritesRender, + final int ballSize, final int ballIndex, final int batchSize, final int delta + ) { final float ballRadius = ballSize * 0.5f; final float boundW = SCREEN_WIDTH - ballRadius; final float boundH = SCREEN_HEIGHT - ballRadius; for ( int b = ballIndex * 4, len = (ballIndex + batchSize) * 4; b < len; b += 4 ) { - float x = transform[b + 0]; - float dx = transform[b + 2]; + float x = sprites[b + 0]; + float dx = sprites[b + 2]; x += dx * delta; if ( x < ballRadius ) { x = ballRadius; - transform[b + 2] = -dx; + sprites[b + 2] = -dx; } else if ( x > boundW ) { x = boundW; - transform[b + 2] = -dx; + sprites[b + 2] = -dx; } - transform[b + 0] = x; + sprites[b + 0] = x; - float y = transform[b + 1]; - float dy = transform[b + 3]; + float y = sprites[b + 1]; + float dy = sprites[b + 3]; y += dy * delta; if ( y < ballRadius ) { y = ballRadius; - transform[b + 3] = -dy; + sprites[b + 3] = -dy; } else if ( y > boundH ) { y = boundH; - transform[b + 3] = -dy; + sprites[b + 3] = -dy; } - transform[b + 1] = y; + sprites[b + 1] = y; - geom.put(x).put(y); + spritesRender.put(x).put(y); } - geom.clear(); + spritesRender.clear(); } protected abstract void render(boolean render, boolean animate, int delta); @@ -517,8 +550,9 @@ } private void animate(final int ballIndex, final int batchSize, final int delta) { - animate(geom, ballIndex, batchSize, delta); + animate(transform, geom, ballSize, ballIndex, batchSize, delta); + // Orphan current buffer and allocate a new one glBufferData(GL_ARRAY_BUFFER, geom.capacity() * 4, GL_STREAM_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0, geom); } @@ -526,11 +560,8 @@ private class SpriteRendererMapped extends SpriteRendererBatched { - private ByteBuffer[] mapBuffer; - private FloatBuffer[] geomBuffer; + private StreamVBO animVBO; - protected int animVBO; - SpriteRendererMapped() { System.out.println("Shootout Implementation: CPU animation & MapBufferRange"); } @@ -538,41 +569,29 @@ public void updateBalls(final int count) { super.updateBalls(count); - final int batchCount = count / BALLS_PER_BATCH + (count % BALLS_PER_BATCH == 0 ? 0 : 1); - mapBuffer = new ByteBuffer[batchCount]; - geomBuffer = new FloatBuffer[batchCount]; + if ( animVBO != null ) + animVBO.destroy(); - animVBO = glGenBuffers(); - glBindBuffer(GL_ARRAY_BUFFER, animVBO); - glBufferData(GL_ARRAY_BUFFER, ballCount * (2 * 4), GL_DYNAMIC_DRAW); - glVertexPointer(2, GL_FLOAT, 0, 0); + animVBO = new StreamVBO(GL_ARRAY_BUFFER, ballCount * (2 * 4)); } public void render(final boolean render, final boolean animate, final int delta) { int batchSize = Math.min(ballCount, BALLS_PER_BATCH); int ballIndex = 0; - int batchIndex = 0; while ( ballIndex < ballCount ) { if ( animate ) { - final ByteBuffer buffer = glMapBufferRange(GL_ARRAY_BUFFER, - ballIndex * (2 * 4), - batchSize * (2 * 4), - GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT, - mapBuffer[batchIndex]); - if ( buffer != mapBuffer[batchIndex] ) { - mapBuffer[batchIndex] = buffer; - geomBuffer[batchIndex] = mapBuffer[batchIndex].asFloatBuffer(); - } + final ByteBuffer buffer = animVBO.map(batchSize * (2 * 4)); - animate(geomBuffer[batchIndex], ballIndex, batchSize, delta); + animate(transform, buffer.asFloatBuffer(), ballSize, ballIndex, batchSize, delta); - glUnmapBuffer(GL_ARRAY_BUFFER); + animVBO.unmap(); } - if ( render ) - glDrawArrays(GL_POINTS, ballIndex, batchSize); + if ( render ) { + glVertexPointer(2, GL_FLOAT, 0, ballIndex * (2 * 4)); + glDrawArrays(GL_POINTS, 0, batchSize); + } - batchIndex++; ballIndex += batchSize; batchSize = Math.min(ballCount - ballIndex, BALLS_PER_BATCH); } @@ -653,6 +672,13 @@ } public void updateBalls(final int count) { + if ( tfVBO[0] != 0 ) { + // Fetch current animation state + final FloatBuffer state = BufferUtils.createFloatBuffer(transform.length); + glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, state); + state.get(transform); + } + super.updateBalls(count); if ( tfVBO[0] != 0 ) { @@ -660,14 +686,14 @@ glDeleteBuffers(tfVBO[i]); } - final FloatBuffer transform = BufferUtils.createFloatBuffer(count * 4); - transform.put(this.transform); - transform.flip(); + final FloatBuffer state = BufferUtils.createFloatBuffer(count * 4); + state.put(transform); + state.flip(); for ( int i = 0; i < tfVBO.length; i++ ) { tfVBO[i] = glGenBuffers(); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tfVBO[i]); - glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, transform, GL_STATIC_DRAW); + glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, state, GL_STATIC_DRAW); } glBindBuffer(GL_ARRAY_BUFFER, tfVBO[0]); Modified: trunk/LWJGL/src/java/org/lwjgl/test/opengl/sprites/SpriteShootout2P.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/test/opengl/sprites/SpriteShootout2P.java 2011-07-14 23:11:41 UTC (rev 3588) +++ trunk/LWJGL/src/java/org/lwjgl/test/opengl/sprites/SpriteShootout2P.java 2011-07-16 16:05:37 UTC (rev 3589) @@ -1,3 +1,34 @@ +/* + * Copyright (c) 2002-2011 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * 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.test.opengl.sprites; import org.lwjgl.BufferUtils; Modified: trunk/LWJGL/src/java/org/lwjgl/test/opengl/sprites/SpriteShootoutCL.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/test/opengl/sprites/SpriteShootoutCL.java 2011-07-14 23:11:41 UTC (rev 3588) +++ trunk/LWJGL/src/java/org/lwjgl/test/opengl/sprites/SpriteShootoutCL.java 2011-07-16 16:05:37 UTC (rev 3589) @@ -1,3 +1,34 @@ +/* + * Copyright (c) 2002-2011 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * 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.test.opengl.sprites; import org.lwjgl.BufferUtils; Added: trunk/LWJGL/src/java/org/lwjgl/test/opengl/sprites/StreamVBO.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/test/opengl/sprites/StreamVBO.java (rev 0) +++ trunk/LWJGL/src/java/org/lwjgl/test/opengl/sprites/StreamVBO.java 2011-07-16 16:05:37 UTC (rev 3589) @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2002-2011 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * 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.test.opengl.sprites; + +import org.lwjgl.LWJGLUtil; + +import java.nio.ByteBuffer; + +import static java.lang.Math.*; +import static org.lwjgl.opengl.GL15.*; +import static org.lwjgl.opengl.GL30.*; + +/** + * This class implements VBO orphaning, useful for streaming + * dynamically generated geometry to the GPU. OpenGL 3.0 or + * higher is required. See + * {@url http://www.opengl.org/wiki/Buffer_Object_Streaming} + * under "Buffer update" for details. + * + * @author Spasi + */ +public class StreamVBO { + + private final int target; + private final long size; + private final int padding; + + private int ID; + + private long cursor; + + public StreamVBO(final int target, final int size) { + this(target, size, 64); + } + + public StreamVBO(final int target, final int size, final int padding) { + this.target = target; + this.padding = padding; + this.size = max(pad(size), padding); + + ID = glGenBuffers(); + + glBindBuffer(target, ID); + glBufferData(target, this.size, GL_STREAM_DRAW); + } + + public int getTarget() { + return target; + } + + public int getID() { + return ID; + } + + public long getSize() { + return size; + } + + public int getPadding() { + return padding; + } + + public void bind() { + glBindBuffer(target, ID); + } + + public void init(final int offset, final ByteBuffer data) { + glBufferSubData(target, offset, data); + } + + public void unmap() { + glUnmapBuffer(target); + } + + public void destroy() { + glBindBuffer(target, 0); + glDeleteBuffers(ID); + } + + public void reset() { + // Orphan current buffer and allocate a new one + glBufferData(target, size, GL_STREAM_DRAW); + // Flush + cursor = 0; + } + + public ByteBuffer map(final int bytes) { + return map(bytes, null); + } + + public ByteBuffer map(final int bytes, final ByteBuffer old_buffer) { + return doMap(pad(bytes), old_buffer); + } + + private int pad(int size) { + final int mod = size % padding; + if ( mod == 0 ) + return size; + + return size + padding - mod; + } + + private ByteBuffer doMap(final int bytes, final ByteBuffer old_buffer) { + if ( LWJGLUtil.CHECKS && size < bytes ) + throw new IllegalArgumentException(Integer.toString(bytes)); + + if ( size < cursor + bytes ) + reset(); + + final ByteBuffer map = glMapBufferRange(target, cursor, bytes, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT, old_buffer); + cursor += bytes; + return map; + } + +} \ No newline at end of file Modified: trunk/LWJGL/src/java/org/lwjgl/util/generator/JNITypeTranslator.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/util/generator/JNITypeTranslator.java 2011-07-14 23:11:41 UTC (rev 3588) +++ trunk/LWJGL/src/java/org/lwjgl/util/generator/JNITypeTranslator.java 2011-07-16 16:05:37 UTC (rev 3589) @@ -32,6 +32,10 @@ package org.lwjgl.util.generator; +import org.lwjgl.PointerBuffer; + +import java.nio.Buffer; + import com.sun.mirror.type.*; import com.sun.mirror.util.*; @@ -45,12 +49,19 @@ * $Id$ */ public class JNITypeTranslator implements TypeVisitor { + private final StringBuilder signature = new StringBuilder(); + private boolean objectReturn; + public String getSignature() { return signature.toString(); } + public String getReturnSignature() { + return objectReturn ? "jobject" : signature.toString(); + } + public void visitAnnotationType(AnnotationType t) { throw new RuntimeException(t + " is not allowed"); } @@ -68,7 +79,12 @@ } public void visitClassType(ClassType t) { - signature.append("jobject"); + final Class<?> type = Utils.getJavaType(t); + if ( Buffer.class.isAssignableFrom(type) || PointerBuffer.class.isAssignableFrom(type) ) { + signature.append("jlong"); + objectReturn = true; + } else + signature.append("jobject"); } public void visitDeclaredType(DeclaredType t) { Modified: trunk/LWJGL/src/java/org/lwjgl/util/generator/JavaMethodsGenerator.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/util/generator/JavaMethodsGenerator.java 2011-07-14 23:11:41 UTC (rev 3588) +++ trunk/LWJGL/src/java/org/lwjgl/util/generator/JavaMethodsGenerator.java 2011-07-16 16:05:37 UTC (rev 3589) @@ -194,8 +194,8 @@ writer.print("long "); else { Class type = type_info.getType(); - if ( native_stub && (type == CharSequence.class || type == CharSequence[].class || type == PointerBuffer.class) ) - writer.print("ByteBuffer "); + if ( native_stub && (type == CharSequence.class || type == CharSequence[].class || type == PointerBuffer.class || Buffer.class.isAssignableFrom(type) ) ) + writer.print("long "); else if ( printTypes ) writer.print(type_info.getType().getSimpleName() + " "); } @@ -203,8 +203,6 @@ if ( auto_size_annotation != null ) writer.print(auto_size_annotation.value() + "_"); writer.print(param.getSimpleName()); - if ( native_stub && buffer_type != null ) - writer.print(", int " + param.getSimpleName() + NativeMethodStubsGenerator.BUFFER_POSITION_POSTFIX); } return false; } @@ -490,7 +488,7 @@ Check check_annotation = param.getAnnotation(Check.class); boolean hide_buffer = mode == Mode.AUTOS && getAutoTypeParameter(method, param) != null; if (hide_buffer) { - writer.print("null"); + writer.print("0L"); } else { if ( type == CharSequence.class || type == CharSequence[].class ) { final String offset = Utils.getStringOffset(method, param); @@ -502,48 +500,25 @@ if ( offset != null ) writer.print(", " + offset); writer.print(")"); - hide_buffer = true; } else { final AutoSize auto_size_annotation = param.getAnnotation(AutoSize.class); if ( auto_size_annotation != null ) writer.print(auto_size_annotation.value() + "_"); - writer.print(param.getSimpleName()); - if ( PointerBuffer.class.isAssignableFrom(type) ) { + + final Class buffer_type = Utils.getNIOBufferType(param.getType()); + if ( buffer_type == null ) + writer.print(param.getSimpleName()); + else { + writer.print("MemoryUtil.getAddress"); if ( check_annotation != null && check_annotation.canBeNull() ) - writer.print(" != null ? " + param.getSimpleName()); - writer.print(".getBuffer()"); - if ( check_annotation != null && check_annotation.canBeNull() ) - writer.print(" : null"); + writer.print("Safe"); + writer.print("("); + writer.print(param.getSimpleName()); + writer.print(")"); } } } - Class buffer_type = Utils.getNIOBufferType(param.getType()); - if (buffer_type != null) { - writer.print(", "); - if (!hide_buffer) { - int shifting; - if (Utils.getNIOBufferType(param.getType()).equals(Buffer.class)) { - shifting = getBufferElementSizeExponent(type == Buffer.class ? ByteBuffer.class : type); // TODO: This will always throw an exception - //shifting = 0; - } else - shifting = 0; - writer.print(param.getSimpleName()); - if (check_annotation != null && check_annotation.canBeNull()) - writer.print(" != null ? " + param.getSimpleName()); - if ( type == PointerBuffer.class && param.getAnnotation(NativeType.class).value().endsWith("void") ) - writer.print(".positionByte()"); - else - writer.print(".position()"); - if (shifting > 0) - writer.print(" << " + shifting); - if (check_annotation != null && check_annotation.canBeNull()) - writer.print(" : 0"); - } else if ( type == CharSequence.class || type == CharSequence[].class ) { - final String offset = Utils.getStringOffset(method, param); - writer.print(offset == null ? "0" : offset); - } else - writer.print("0"); - } else if ( type != long.class ) { + if ( type != long.class ) { PointerWrapper pointer_annotation = param.getAnnotation(PointerWrapper.class); if ( pointer_annotation != null ) { if ( pointer_annotation.canBeNull() ) Modified: trunk/LWJGL/src/java/org/lwjgl/util/generator/NativeMethodStubsGenerator.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/util/generator/NativeMethodStubsGenerator.java 2011-07-14 23:11:41 UTC (rev 3588) +++ trunk/LWJGL/src/java/org/lwjgl/util/generator/NativeMethodStubsGenerator.java 2011-07-16 16:05:37 UTC (rev 3589) @@ -88,8 +88,6 @@ JNITypeTranslator translator = new JNITypeTranslator(); param.getType().accept(translator); writer.print(translator.getSignature() + " " + param.getSimpleName()); - if (Utils.getNIOBufferType(param.getType()) != null) - writer.print(", jint " + param.getSimpleName() + BUFFER_POSITION_POSTFIX); } } @@ -108,7 +106,7 @@ } else { JNITypeTranslator translator = new JNITypeTranslator(); result_type.accept(translator); - writer.print(translator.getSignature()); + writer.print(translator.getReturnSignature()); } writer.print(" JNICALL "); @@ -298,30 +296,17 @@ if ( !java_type.isArray() || CharSequence.class.isAssignableFrom(java_type.getComponentType()) ) { writer.print("\t" + native_type + param.getSimpleName()); - writer.print(BUFFER_ADDRESS_POSTFIX + " = (("); + writer.print(BUFFER_ADDRESS_POSTFIX + " = ("); writer.print(native_type); writer.print(")"); if (mode == Mode.BUFFEROBJECT && param.getAnnotation(BufferObject.class) != null) { - writer.print("offsetToPointer(" + param.getSimpleNa... [truncated message content] |