Replaced HashMap<Long, T> with FastLongMap in the OpenCL package.
Replaced CharsetEncoder with simple ASCII encoding in APIUtil. Attempt to fix CL native kernels on x64.
This commit is contained in:
parent
8d37d1bdee
commit
9405dde18a
|
@ -34,10 +34,9 @@ package org.lwjgl.opencl;
|
|||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.LWJGLUtil;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.opencl.FastLongMap.Entry;
|
||||
|
||||
import java.nio.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
@ -75,16 +74,10 @@ final class APIUtil {
|
|||
protected PointerBuffer initialValue() { return BufferUtils.createPointerBuffer(INITIAL_LENGTHS_SIZE); }
|
||||
};
|
||||
|
||||
private static final ThreadLocal<InfiniteCharSequence> infiniteSeqTL = new ThreadLocal<InfiniteCharSequence>() {
|
||||
protected InfiniteCharSequence initialValue() { return new InfiniteCharSequence(); }
|
||||
};
|
||||
|
||||
private static final ThreadLocal<Buffers> buffersTL = new ThreadLocal<Buffers>() {
|
||||
protected Buffers initialValue() { return new Buffers(); }
|
||||
};
|
||||
|
||||
private static final CharsetEncoder encoder = Charset.forName("US-ASCII").newEncoder();
|
||||
|
||||
private APIUtil() {
|
||||
}
|
||||
|
||||
|
@ -188,15 +181,22 @@ final class APIUtil {
|
|||
return lengths;
|
||||
}
|
||||
|
||||
private static InfiniteCharSequence getInfiniteSeq() {
|
||||
return infiniteSeqTL.get();
|
||||
}
|
||||
/**
|
||||
* Simple ASCII encoding.
|
||||
*
|
||||
* @param buffer The target buffer
|
||||
* @param string The source string
|
||||
*/
|
||||
private static ByteBuffer encode(final ByteBuffer buffer, final CharSequence string) {
|
||||
for ( int i = 0; i < string.length(); i++ ) {
|
||||
final char c = string.charAt(i);
|
||||
if ( LWJGLUtil.DEBUG && 0x80 <= c ) // Silently ignore and map to 0x1A.
|
||||
buffer.put((byte)0x1A);
|
||||
else
|
||||
buffer.put((byte)c);
|
||||
}
|
||||
|
||||
private static void encode(final ByteBuffer buffer, final CharSequence string) {
|
||||
final InfiniteCharSequence infiniteSeq = getInfiniteSeq();
|
||||
infiniteSeq.setString(string);
|
||||
encoder.encode(infiniteSeq.buffer, buffer, true);
|
||||
infiniteSeq.clear();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -224,10 +224,7 @@ final class APIUtil {
|
|||
* @return the String as a ByteBuffer
|
||||
*/
|
||||
static ByteBuffer getBuffer(final CharSequence string) {
|
||||
final ByteBuffer buffer = getBufferByte(string.length());
|
||||
|
||||
encode(buffer, string);
|
||||
|
||||
final ByteBuffer buffer = encode(getBufferByte(string.length()), string);
|
||||
buffer.flip();
|
||||
return buffer;
|
||||
}
|
||||
|
@ -240,10 +237,7 @@ final class APIUtil {
|
|||
* @return the String as a ByteBuffer
|
||||
*/
|
||||
static ByteBuffer getBuffer(final CharSequence string, final int offset) {
|
||||
final ByteBuffer buffer = getBufferByteOffset(offset + string.length());
|
||||
|
||||
encode(buffer, string);
|
||||
|
||||
final ByteBuffer buffer = encode(getBufferByteOffset(offset + string.length()), string);
|
||||
buffer.flip();
|
||||
return buffer;
|
||||
}
|
||||
|
@ -256,10 +250,7 @@ final class APIUtil {
|
|||
* @return the String as a ByteBuffer
|
||||
*/
|
||||
static ByteBuffer getBufferNT(final CharSequence string) {
|
||||
final ByteBuffer buffer = getBufferByte(string.length() + 1);
|
||||
|
||||
encode(buffer, string);
|
||||
|
||||
final ByteBuffer buffer = encode(getBufferByte(string.length() + 1), string);
|
||||
buffer.put((byte)0);
|
||||
buffer.flip();
|
||||
return buffer;
|
||||
|
@ -283,12 +274,8 @@ final class APIUtil {
|
|||
static ByteBuffer getBuffer(final CharSequence[] strings) {
|
||||
final ByteBuffer buffer = getBufferByte(getTotalLength(strings));
|
||||
|
||||
final InfiniteCharSequence infiniteSeq = getInfiniteSeq();
|
||||
for ( CharSequence string : strings ) {
|
||||
infiniteSeq.setString(string);
|
||||
encoder.encode(infiniteSeq.buffer, buffer, true);
|
||||
}
|
||||
infiniteSeq.clear();
|
||||
for ( CharSequence string : strings )
|
||||
encode(buffer, string);
|
||||
|
||||
buffer.flip();
|
||||
return buffer;
|
||||
|
@ -304,13 +291,10 @@ final class APIUtil {
|
|||
static ByteBuffer getBufferNT(final CharSequence[] strings) {
|
||||
final ByteBuffer buffer = getBufferByte(getTotalLength(strings) + strings.length);
|
||||
|
||||
final InfiniteCharSequence infiniteSeq = getInfiniteSeq();
|
||||
for ( CharSequence string : strings ) {
|
||||
infiniteSeq.setString(string);
|
||||
encoder.encode(infiniteSeq.buffer, buffer, true);
|
||||
encode(buffer, string);
|
||||
buffer.put((byte)0);
|
||||
}
|
||||
infiniteSeq.clear();
|
||||
|
||||
buffer.flip();
|
||||
return buffer;
|
||||
|
@ -358,43 +342,6 @@ final class APIUtil {
|
|||
return (int)size;
|
||||
}
|
||||
|
||||
/**
|
||||
* A mutable CharSequence with very large initial length. We can wrap this in a re-usable CharBuffer for decoding.
|
||||
* We cannot subclass CharBuffer because of {@link java.nio.CharBuffer#toString(int,int)}.
|
||||
*/
|
||||
private static class InfiniteCharSequence implements CharSequence {
|
||||
|
||||
final CharBuffer buffer;
|
||||
|
||||
CharSequence string;
|
||||
|
||||
InfiniteCharSequence() {
|
||||
buffer = CharBuffer.wrap(this);
|
||||
}
|
||||
|
||||
void setString(final CharSequence string) {
|
||||
this.string = string;
|
||||
this.buffer.position(0);
|
||||
this.buffer.limit(string.length());
|
||||
}
|
||||
|
||||
void clear() {
|
||||
this.string = null;
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
public char charAt(final int index) {
|
||||
return string.charAt(index);
|
||||
}
|
||||
|
||||
public CharSequence subSequence(final int start, final int end) {
|
||||
return string.subSequence(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Buffers {
|
||||
|
||||
final ShortBuffer shorts;
|
||||
|
@ -559,7 +506,8 @@ final class APIUtil {
|
|||
if ( registry.isEmpty() )
|
||||
return;
|
||||
|
||||
for ( final T object : registry.getAll() ) {
|
||||
for ( Entry<T> entry : registry.getAll() ) {
|
||||
final T object = entry.value;
|
||||
while ( object.isValid() )
|
||||
destructor.release(object);
|
||||
}
|
||||
|
|
|
@ -37,9 +37,7 @@ import org.lwjgl.opencl.api.Filter;
|
|||
import org.lwjgl.opengl.Drawable;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This class is a wrapper around a cl_context pointer.
|
||||
|
@ -57,10 +55,10 @@ public final class CLContext extends CLObjectChild<CLPlatform> {
|
|||
private final CLObjectRegistry<CLEvent> clEvents;
|
||||
|
||||
/** Global registry for build callbacks. */
|
||||
static final Map<Long, CLProgram> clProgramsGlobal = new HashMap<Long, CLProgram>();
|
||||
static final FastLongMap<CLProgram> clProgramsGlobal = new FastLongMap<CLProgram>();
|
||||
|
||||
/** Global registry for event callbacks. */
|
||||
static final Map<Long, CLEvent> clEventsGlobal = new HashMap<Long, CLEvent>();
|
||||
static final FastLongMap<CLEvent> clEventsGlobal = new FastLongMap<CLEvent>();
|
||||
|
||||
CLContext(final long pointer, final CLPlatform platform) {
|
||||
super(pointer, platform);
|
||||
|
|
|
@ -2,11 +2,6 @@ package org.lwjgl.opencl;
|
|||
|
||||
import org.lwjgl.LWJGLUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A CLObjectChild container.
|
||||
*
|
||||
|
@ -14,7 +9,7 @@ import java.util.Map;
|
|||
*/
|
||||
class CLObjectRegistry<T extends CLObjectChild> {
|
||||
|
||||
private Map<Long, T> registry;
|
||||
private FastLongMap<T> registry;
|
||||
|
||||
CLObjectRegistry() {
|
||||
}
|
||||
|
@ -31,12 +26,12 @@ class CLObjectRegistry<T extends CLObjectChild> {
|
|||
return registry != null && registry.containsKey(id);
|
||||
}
|
||||
|
||||
final List<T> getAll() {
|
||||
return registry == null ? null : new ArrayList<T>(registry.values());
|
||||
final Iterable<FastLongMap.Entry<T>> getAll() {
|
||||
return registry;
|
||||
}
|
||||
|
||||
void registerObject(final T object) {
|
||||
final Map<Long, T> map = getMap();
|
||||
final FastLongMap<T> map = getMap();
|
||||
final Long key = object.getPointer();
|
||||
|
||||
if ( LWJGLUtil.DEBUG && map.containsKey(key) )
|
||||
|
@ -49,9 +44,9 @@ class CLObjectRegistry<T extends CLObjectChild> {
|
|||
getMap().remove(object.getPointerUnsafe());
|
||||
}
|
||||
|
||||
private Map<Long, T> getMap() {
|
||||
private FastLongMap<T> getMap() {
|
||||
if ( registry == null )
|
||||
registry = new HashMap<Long, T>();
|
||||
registry = new FastLongMap<T>();
|
||||
|
||||
return registry;
|
||||
}
|
||||
|
|
|
@ -31,8 +31,6 @@
|
|||
*/
|
||||
package org.lwjgl.opencl;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A CLObject registry that also registers/unregisters objects to/from a global registry.
|
||||
*
|
||||
|
@ -40,9 +38,9 @@ import java.util.Map;
|
|||
*/
|
||||
final class CLObjectRegistryGlobal<T extends CLObjectChild> extends CLObjectRegistry<T> {
|
||||
|
||||
private final Map<Long, T> globalRegistry;
|
||||
private final FastLongMap<T> globalRegistry;
|
||||
|
||||
CLObjectRegistryGlobal(final Map<Long, T> globalRegistry) {
|
||||
CLObjectRegistryGlobal(final FastLongMap<T> globalRegistry) {
|
||||
this.globalRegistry = globalRegistry;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,9 +36,7 @@ import org.lwjgl.opencl.api.Filter;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.lang.Math.*;
|
||||
|
||||
|
@ -51,12 +49,12 @@ public final class CLPlatform extends CLObject {
|
|||
|
||||
private static final CLPlatformUtil util = (CLPlatformUtil)getInfoUtilInstance(CLPlatform.class, "CL_PLATFORM_UTIL");
|
||||
|
||||
private static final Map<Long, CLPlatform> clPlatforms = new HashMap<Long, CLPlatform>();
|
||||
private static final FastLongMap<CLPlatform> clPlatforms = new FastLongMap<CLPlatform>();
|
||||
|
||||
private final CLObjectRegistry<CLDevice> clDevices;
|
||||
|
||||
/** Global registry for build callbacks. */
|
||||
static final Map<Long, CLDevice> clDevicesGlobal = new HashMap<Long, CLDevice>();
|
||||
static final FastLongMap<CLDevice> clDevicesGlobal = new FastLongMap<CLDevice>();
|
||||
|
||||
private Object caps;
|
||||
|
||||
|
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
* Copyright 2002-2004 The Apache Software Foundation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
|
||||
* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
package org.lwjgl.opencl;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* A hash map using primitive longs as keys rather than objects.
|
||||
*
|
||||
* @author Justin Couch
|
||||
* @author Alex Chaffee (alex@apache.org)
|
||||
* @author Stephen Colebourne
|
||||
* @author Nathan Sweet
|
||||
*/
|
||||
final class FastLongMap<V> implements Iterable<FastLongMap.Entry<V>> {
|
||||
|
||||
private Entry[] table;
|
||||
private int size, mask, capacity, threshold;
|
||||
|
||||
/** Same as: FastLongMap(16, 0.75f); */
|
||||
FastLongMap() {
|
||||
this(16, 0.75f);
|
||||
}
|
||||
|
||||
/** Same as: FastLongMap(initialCapacity, 0.75f); */
|
||||
FastLongMap(int initialCapacity) {
|
||||
this(initialCapacity, 0.75f);
|
||||
}
|
||||
|
||||
FastLongMap(int initialCapacity, float loadFactor) {
|
||||
if ( initialCapacity > 1 << 30 ) throw new IllegalArgumentException("initialCapacity is too large.");
|
||||
if ( initialCapacity < 0 ) throw new IllegalArgumentException("initialCapacity must be greater than zero.");
|
||||
if ( loadFactor <= 0 ) throw new IllegalArgumentException("initialCapacity must be greater than zero.");
|
||||
capacity = 1;
|
||||
while ( capacity < initialCapacity )
|
||||
capacity <<= 1;
|
||||
this.threshold = (int)(capacity * loadFactor);
|
||||
this.table = new Entry[capacity];
|
||||
this.mask = capacity - 1;
|
||||
}
|
||||
|
||||
private int index(final long key) {
|
||||
return index(key, mask);
|
||||
}
|
||||
|
||||
private static int index(final long key, final int mask) {
|
||||
final int hash = (int)(key ^ (key >>> 32));
|
||||
return hash & mask;
|
||||
}
|
||||
|
||||
public V put(long key, V value) {
|
||||
final Entry<V>[] table = this.table;
|
||||
int index = index(key);
|
||||
|
||||
// Check if key already exists.
|
||||
for ( Entry<V> e = table[index]; e != null; e = e.next ) {
|
||||
if ( e.key != key ) continue;
|
||||
V oldValue = e.value;
|
||||
e.value = value;
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
table[index] = new Entry<V>(key, value, table[index]);
|
||||
|
||||
if ( size++ >= threshold )
|
||||
rehash(table);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void rehash(final Entry<V>[] table) {
|
||||
final int newCapacity = 2 * capacity;
|
||||
final int newMask = newCapacity - 1;
|
||||
|
||||
final Entry<V>[] newTable = new Entry[newCapacity];
|
||||
|
||||
for ( int i = 0, index; i < table.length; i++ ) {
|
||||
Entry<V> e = table[i];
|
||||
if ( e == null ) continue;
|
||||
do {
|
||||
final Entry<V> next = e.next;
|
||||
index = index(e.key, newMask);
|
||||
e.next = newTable[index];
|
||||
newTable[index] = e;
|
||||
e = next;
|
||||
} while ( e != null );
|
||||
}
|
||||
|
||||
this.table = newTable;
|
||||
capacity = newCapacity;
|
||||
mask = newMask;
|
||||
threshold *= 2;
|
||||
}
|
||||
|
||||
public V get(long key) {
|
||||
final int index = index(key);
|
||||
for ( Entry<V> e = table[index]; e != null; e = e.next )
|
||||
if ( e.key == key ) return e.value;
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean containsValue(Object value) {
|
||||
final Entry<V>[] table = this.table;
|
||||
for ( int i = table.length - 1; i >= 0; i-- )
|
||||
for ( Entry<V> e = table[i]; e != null; e = e.next )
|
||||
if ( e.value.equals(value) ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean containsKey(long key) {
|
||||
final int index = index(key);
|
||||
for ( Entry<V> e = table[index]; e != null; e = e.next )
|
||||
if ( e.key == key ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public V remove(long key) {
|
||||
final int index = index(key);
|
||||
|
||||
Entry<V> prev = table[index];
|
||||
Entry<V> e = prev;
|
||||
while ( e != null ) {
|
||||
Entry<V> next = e.next;
|
||||
if ( e.key == key ) {
|
||||
size--;
|
||||
if ( prev == e )
|
||||
table[index] = next;
|
||||
else
|
||||
prev.next = next;
|
||||
return e.value;
|
||||
}
|
||||
prev = e;
|
||||
e = next;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
final Entry<V>[] table = this.table;
|
||||
for ( int index = table.length - 1; index >= 0; index-- )
|
||||
table[index] = null;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
public EntryIterator iterator() {
|
||||
return new EntryIterator();
|
||||
}
|
||||
|
||||
public class EntryIterator implements Iterator<Entry<V>> {
|
||||
|
||||
private int nextIndex;
|
||||
private Entry<V> current;
|
||||
|
||||
EntryIterator() {
|
||||
reset();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
current = null;
|
||||
// Find first bucket.
|
||||
final Entry<V>[] table = FastLongMap.this.table;
|
||||
int i;
|
||||
for ( i = table.length - 1; i >= 0; i-- )
|
||||
if ( table[i] != null ) break;
|
||||
nextIndex = i;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
if ( nextIndex >= 0 ) return true;
|
||||
Entry e = current;
|
||||
return e != null && e.next != null;
|
||||
}
|
||||
|
||||
public Entry<V> next() {
|
||||
// Next entry in current bucket.
|
||||
Entry<V> e = current;
|
||||
if ( e != null ) {
|
||||
e = e.next;
|
||||
if ( e != null ) {
|
||||
current = e;
|
||||
return e;
|
||||
}
|
||||
}
|
||||
// Use the bucket at nextIndex and find the next nextIndex.
|
||||
final Entry<V>[] table = FastLongMap.this.table;
|
||||
int i = nextIndex;
|
||||
e = current = table[i];
|
||||
while ( --i >= 0 )
|
||||
if ( table[i] != null ) break;
|
||||
nextIndex = i;
|
||||
return e;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
FastLongMap.this.remove(current.key);
|
||||
}
|
||||
}
|
||||
|
||||
static final class Entry<T> {
|
||||
|
||||
final long key;
|
||||
T value;
|
||||
Entry<T> next;
|
||||
|
||||
Entry(long key, T value, Entry<T> next) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public long getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -32,10 +32,9 @@
|
|||
package org.lwjgl.opengl;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.LWJGLUtil;
|
||||
|
||||
import java.nio.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
|
||||
/** @author spasi */
|
||||
final class APIUtil {
|
||||
|
@ -57,16 +56,10 @@ final class APIUtil {
|
|||
protected IntBuffer initialValue() { return BufferUtils.createIntBuffer(INITIAL_LENGTHS_SIZE); }
|
||||
};
|
||||
|
||||
private static final ThreadLocal<InfiniteCharSequence> infiniteSeqTL = new ThreadLocal<InfiniteCharSequence>() {
|
||||
protected InfiniteCharSequence initialValue() { return new InfiniteCharSequence(); }
|
||||
};
|
||||
|
||||
private static final ThreadLocal<Buffers> buffersTL = new ThreadLocal<Buffers>() {
|
||||
protected Buffers initialValue() { return new Buffers(); }
|
||||
};
|
||||
|
||||
private static CharsetEncoder encoder = Charset.forName("US-ASCII").newEncoder();
|
||||
|
||||
private APIUtil() {
|
||||
}
|
||||
|
||||
|
@ -150,15 +143,22 @@ final class APIUtil {
|
|||
return lengths;
|
||||
}
|
||||
|
||||
private static InfiniteCharSequence getInfiniteSeq() {
|
||||
return infiniteSeqTL.get();
|
||||
}
|
||||
/**
|
||||
* Simple ASCII encoding.
|
||||
*
|
||||
* @param buffer The target buffer
|
||||
* @param string The source string
|
||||
*/
|
||||
private static ByteBuffer encode(final ByteBuffer buffer, final CharSequence string) {
|
||||
for ( int i = 0; i < string.length(); i++ ) {
|
||||
final char c = string.charAt(i);
|
||||
if ( LWJGLUtil.DEBUG && 0x80 <= c ) // Silently ignore and map to 0x1A.
|
||||
buffer.put((byte)0x1A);
|
||||
else
|
||||
buffer.put((byte)c);
|
||||
}
|
||||
|
||||
private static void encode(final ByteBuffer buffer, final CharSequence string) {
|
||||
final InfiniteCharSequence infiniteSeq = getInfiniteSeq();
|
||||
infiniteSeq.setString(string);
|
||||
encoder.encode(infiniteSeq.buffer, buffer, true);
|
||||
infiniteSeq.clear();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -186,10 +186,7 @@ final class APIUtil {
|
|||
* @return the String as a ByteBuffer
|
||||
*/
|
||||
static ByteBuffer getBuffer(final CharSequence string) {
|
||||
final ByteBuffer buffer = getBufferByte(string.length());
|
||||
|
||||
encode(buffer, string);
|
||||
|
||||
final ByteBuffer buffer = encode(getBufferByte(string.length()), string);
|
||||
buffer.flip();
|
||||
return buffer;
|
||||
}
|
||||
|
@ -202,10 +199,7 @@ final class APIUtil {
|
|||
* @return the String as a ByteBuffer
|
||||
*/
|
||||
static ByteBuffer getBuffer(final CharSequence string, final int offset) {
|
||||
final ByteBuffer buffer = getBufferByteOffset(offset + string.length());
|
||||
|
||||
encode(buffer, string);
|
||||
|
||||
final ByteBuffer buffer = encode(getBufferByteOffset(offset + string.length()), string);
|
||||
buffer.flip();
|
||||
return buffer;
|
||||
}
|
||||
|
@ -218,10 +212,7 @@ final class APIUtil {
|
|||
* @return the String as a ByteBuffer
|
||||
*/
|
||||
static ByteBuffer getBufferNT(final CharSequence string) {
|
||||
final ByteBuffer buffer = getBufferByte(string.length() + 1);
|
||||
|
||||
encode(buffer, string);
|
||||
|
||||
final ByteBuffer buffer = encode(getBufferByte(string.length() + 1), string);
|
||||
buffer.put((byte)0);
|
||||
buffer.flip();
|
||||
return buffer;
|
||||
|
@ -245,12 +236,8 @@ final class APIUtil {
|
|||
static ByteBuffer getBuffer(final CharSequence[] strings) {
|
||||
final ByteBuffer buffer = getBufferByte(getTotalLength(strings));
|
||||
|
||||
final InfiniteCharSequence infiniteSeq = getInfiniteSeq();
|
||||
for ( CharSequence string : strings ) {
|
||||
infiniteSeq.setString(string);
|
||||
encoder.encode(infiniteSeq.buffer, buffer, true);
|
||||
}
|
||||
infiniteSeq.clear();
|
||||
for ( CharSequence string : strings )
|
||||
encode(buffer, string);
|
||||
|
||||
buffer.flip();
|
||||
return buffer;
|
||||
|
@ -266,13 +253,10 @@ final class APIUtil {
|
|||
static ByteBuffer getBufferNT(final CharSequence[] strings) {
|
||||
final ByteBuffer buffer = getBufferByte(getTotalLength(strings) + strings.length);
|
||||
|
||||
final InfiniteCharSequence infiniteSeq = getInfiniteSeq();
|
||||
for ( CharSequence string : strings ) {
|
||||
infiniteSeq.setString(string);
|
||||
encoder.encode(infiniteSeq.buffer, buffer, true);
|
||||
encode(buffer, string);
|
||||
buffer.put((byte)0);
|
||||
}
|
||||
infiniteSeq.clear();
|
||||
|
||||
buffer.flip();
|
||||
return buffer;
|
||||
|
@ -295,43 +279,6 @@ final class APIUtil {
|
|||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* A mutable CharSequence with very large initial length. We can wrap this in a re-usable CharBuffer for decoding.
|
||||
* We cannot subclass CharBuffer because of {@link CharBuffer#toString(int,int)}.
|
||||
*/
|
||||
private static class InfiniteCharSequence implements CharSequence {
|
||||
|
||||
final CharBuffer buffer;
|
||||
|
||||
CharSequence string;
|
||||
|
||||
InfiniteCharSequence() {
|
||||
buffer = CharBuffer.wrap(this);
|
||||
}
|
||||
|
||||
void setString(final CharSequence string) {
|
||||
this.string = string;
|
||||
this.buffer.position(0);
|
||||
this.buffer.limit(string.length());
|
||||
}
|
||||
|
||||
void clear() {
|
||||
this.string = null;
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
public char charAt(final int index) {
|
||||
return string.charAt(index);
|
||||
}
|
||||
|
||||
public CharSequence subSequence(final int start, final int end) {
|
||||
return string.subSequence(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Buffers {
|
||||
|
||||
final ShortBuffer shorts;
|
||||
|
|
|
@ -156,9 +156,9 @@ static void CL_USER_FUNC_CALLBACK nativeKernelCallback(void *args) {
|
|||
for ( i = 0; i < num_mem_objects; i++ ) {
|
||||
buffer = (*env)->NewDirectByteBuffer(env,
|
||||
// Pointer to cl_mem buffer
|
||||
(void *)((char *)args + (12 + 4 + (i * (4 + sizeof(size_t))))),
|
||||
(void *)((char *)args + (12 + 4 + (i * (4 + sizeof(void *))))),
|
||||
// cl_mem buffer size
|
||||
*((jint *)((char *)args + (12 + (i * (4 + sizeof(size_t))))))
|
||||
*((jint *)((char *)args + (12 + (i * (4 + sizeof(void *))))))
|
||||
);
|
||||
(*env)->SetObjectArrayElement(env, memobjs, i, buffer);
|
||||
}
|
||||
|
|
|
@ -1061,7 +1061,7 @@ public interface CL10 {
|
|||
nativeAfterVars = "\tvoid **args_mem_loc = num_mem_objects == 0 ? NULL : (void **)malloc(num_mem_objects * sizeof(void *));",
|
||||
nativeBeforeCall = "\t_ptr_i = 0;\n" +
|
||||
"\twhile ( _ptr_i < num_mem_objects ) {\n" +
|
||||
"\t\targs_mem_loc[_ptr_i] = (cl_void *)((char *)args_address + (4 + _ptr_i * (4 + sizeof(size_t))));\n" +
|
||||
"\t\targs_mem_loc[_ptr_i] = (cl_void *)((char *)args_address + (4 + _ptr_i * (4 + sizeof(void *))));\n" +
|
||||
"\t\t_ptr_i++;\n" +
|
||||
"\t}",
|
||||
nativeAfterCall = "\tfree(args_mem_loc);"
|
||||
|
|
Loading…
Reference in New Issue