Moved all pointer arithmetic to Java code.

This commit is contained in:
Ioannis Tsakpinis 2011-07-16 16:05:37 +00:00
parent c7088cb44f
commit 0b0e185f47
61 changed files with 944 additions and 330 deletions

View file

@ -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.");
}
}

View file

@ -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);
}
}
}

View file

@ -99,7 +99,7 @@ public class PointerBuffer implements Comparable {
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.");
}

View file

@ -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 @@ import static org.lwjgl.opencl.KHRGLSharing.*;
*/
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 @@ final class APIUtil {
*
* @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 @@ final class APIUtil {
*
* @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 @@ final class APIUtil {
*
* @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 @@ final class APIUtil {
*
* @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 @@ final class APIUtil {
*
* @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 @@ final class APIUtil {
}
buffer.flip();
return buffer;
return MemoryUtil.getAddress0(buffer);
}
/**
@ -307,14 +305,14 @@ final class APIUtil {
*
* @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 @@ final class APIUtil {
*
* @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 @@ final class APIUtil {
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 @@ final class APIUtil {
}
}
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); }
};

View file

@ -118,7 +118,7 @@ final class InfoUtilFactory {
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 @@ final class InfoUtilFactory {
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 @@ final class InfoUtilFactory {
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;

View file

@ -33,6 +33,7 @@ package org.lwjgl.opengl;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.MemoryUtil;
import java.nio.*;
@ -185,10 +186,10 @@ final class APIUtil {
*
* @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 @@ final class APIUtil {
*
* @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 @@ final class APIUtil {
*
* @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 @@ final class APIUtil {
*
* @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 @@ final class APIUtil {
*
* @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 @@ final class APIUtil {
}
buffer.flip();
return buffer;
return MemoryUtil.getAddress0(buffer);
}
/**
@ -269,14 +270,22 @@ final class APIUtil {
*
* @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 {

View file

@ -33,6 +33,7 @@ package org.lwjgl.opengles;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.MemoryUtil;
import org.lwjgl.PointerBuffer;
import java.nio.ByteBuffer;
@ -207,10 +208,10 @@ final class APIUtil {
*
* @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 @@ final class APIUtil {
*
* @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 @@ final class APIUtil {
*
* @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 @@ final class APIUtil {
*
* @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 @@ final class APIUtil {
*
* @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 @@ final class APIUtil {
}
buffer.flip();
return buffer;
return MemoryUtil.getAddress0(buffer);
}
/**
@ -291,14 +292,22 @@ final class APIUtil {
*
* @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 {

View file

@ -118,6 +118,10 @@ public class MappedObjectTests3 {
set.view = 0;
assert (vec2.view == 0);
assert (vec3.view == 0);
set.next();
assert (vec2.view == 1);
assert (vec3.view == 1);
}
}

View file

@ -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 @@ import static org.lwjgl.opengl.GL30.*;
*/
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 @@ public final class SpriteShootout {
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 @@ public final class SpriteShootout {
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 @@ public final class SpriteShootout {
}
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,10 +560,7 @@ public final class SpriteShootout {
private class SpriteRendererMapped extends SpriteRendererBatched {
private ByteBuffer[] mapBuffer;
private FloatBuffer[] geomBuffer;
protected int animVBO;
private StreamVBO animVBO;
SpriteRendererMapped() {
System.out.println("Shootout Implementation: CPU animation & MapBufferRange");
@ -538,41 +569,29 @@ public final class SpriteShootout {
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 final class SpriteShootout {
}
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 @@ public final class SpriteShootout {
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]);

View file

@ -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;

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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 @@ import com.sun.mirror.util.*;
* $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 class JNITypeTranslator implements TypeVisitor {
}
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) {

View file

@ -194,8 +194,8 @@ public class JavaMethodsGenerator {
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 @@ public class JavaMethodsGenerator {
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 @@ public class JavaMethodsGenerator {
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 @@ public class JavaMethodsGenerator {
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() )

View file

@ -88,8 +88,6 @@ public class NativeMethodStubsGenerator {
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 @@ public class NativeMethodStubsGenerator {
} else {
JNITypeTranslator translator = new JNITypeTranslator();
result_type.accept(translator);
writer.print(translator.getSignature());
writer.print(translator.getReturnSignature());
}
writer.print(" JNICALL ");
@ -298,30 +296,17 @@ public class NativeMethodStubsGenerator {
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.getSimpleName() + Utils.BUFFER_OBJECT_PARAMETER_POSTFIX + "))");
writer.print("offsetToPointer(" + param.getSimpleName() + Utils.BUFFER_OBJECT_PARAMETER_POSTFIX + ")");
} else {
if (Buffer.class.isAssignableFrom(java_type) || java_type.equals(CharSequence.class) || java_type.equals(CharSequence[].class) || PointerBuffer.class.isAssignableFrom(java_type) ) {
boolean explicitly_byte_sized = java_type.equals(Buffer.class) ||
translator.getAnnotationType().equals(type_map.getVoidType()) ||
(param.getAnnotation(NativeType.class) != null && param.getAnnotation(NativeType.class).value().endsWith("void"));
if (explicitly_byte_sized)
writer.print("(((char *)");
if (method.getAnnotation(GenerateAutos.class) != null || (check_annotation != null && check_annotation.canBeNull())) {
writer.print("safeGetBufferAddress(env, " + param.getSimpleName());
} else {
writer.print("(*env)->GetDirectBufferAddress(env, " + param.getSimpleName());
}
writer.print("))");
writer.print(" + " + param.getSimpleName() + BUFFER_POSITION_POSTFIX);
if (explicitly_byte_sized)
writer.print("))");
writer.print(param.getSimpleName());
} else if (java_type.equals(String.class)) {
writer.print("GetStringNativeChars(env, " + param.getSimpleName() + "))");
writer.print("GetStringNativeChars(env, " + param.getSimpleName() + ")");
} else if ( array_annotation == null )
throw new RuntimeException("Illegal type " + java_type);
}