implemented LWJGL3 BufferAllocator

native-compilation-test
javasabr 8 years ago
parent 8d818a21bc
commit d468c20fba
  1. 31
      jme3-core/src/main/java/com/jme3/util/BufferAllocatorFactory.java
  2. 50
      jme3-core/src/main/java/com/jme3/util/BufferUtils.java
  3. 80
      jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglContext.java
  4. 24
      jme3-lwjgl3/src/main/java/com/jme3/util/LWJGLBufferAllocator.java

@ -0,0 +1,31 @@
package com.jme3.util;
import com.jme3.system.Annotations.Internal;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* The factory of buffer allocators.
*
* @author JavaSaBR
*/
@Internal
public class BufferAllocatorFactory {
public static final String PROPERTY_BUFFER_ALLOCATOR_IMPLEMENTATION = "com.jme3.BufferAllocatorImplementation";
private static final Logger LOGGER = Logger.getLogger(BufferAllocatorFactory.class.getName());
@Internal
protected static BufferAllocator create() {
final String className = System.getProperty(PROPERTY_BUFFER_ALLOCATOR_IMPLEMENTATION, ReflectionAllocator.class.getName());
try {
return (BufferAllocator) Class.forName(className).newInstance();
} catch (final Throwable e) {
LOGGER.log(Level.WARNING, "Unable to access {0}", className);
return new PrimitiveAllocator();
}
}
}

@ -31,6 +31,12 @@
*/
package com.jme3.util;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.math.Vector4f;
import java.io.UnsupportedEncodingException;
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
@ -45,12 +51,6 @@ import java.nio.LongBuffer;
import java.nio.ShortBuffer;
import java.util.concurrent.ConcurrentHashMap;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.math.Vector4f;
/**
* <code>BufferUtils</code> is a helper class for generating nio buffers from
* jME data classes such as Vectors and ColorRGBA.
@ -59,7 +59,11 @@ import com.jme3.math.Vector4f;
* @version $Id: BufferUtils.java,v 1.16 2007/10/29 16:56:18 nca Exp $
*/
public final class BufferUtils {
private static BufferAllocator allocator = new PrimitiveAllocator();
/**
* The field should be final to support thread-safe.
*/
private static final BufferAllocator ALLOCATOR = BufferAllocatorFactory.create();
private static boolean trackDirectMemory = false;
private static ReferenceQueue<Buffer> removeCollected = new ReferenceQueue<Buffer>();
@ -68,26 +72,6 @@ public final class BufferUtils {
private static boolean used;
static {
try {
allocator = new ReflectionAllocator();
} catch (Throwable t) {
t.printStackTrace();
System.err.println("Error using ReflectionAllocator");
}
}
/**
* Warning! do only set this before JME is started!
*/
public static void setAllocator(BufferAllocator allocator) {
if (used) {
throw new IllegalStateException(
"An Buffer was already allocated, since it is quite likely that other dispose methods will create native dangling pointers or other fun things, this is forbidden to be changed at runtime");
}
BufferUtils.allocator = allocator;
}
/**
* Set it to true if you want to enable direct memory tracking for debugging
* purpose. Default is false. To print direct memory usage use
@ -809,7 +793,7 @@ public final class BufferUtils {
* @return the new DoubleBuffer
*/
public static DoubleBuffer createDoubleBuffer(int size) {
DoubleBuffer buf = allocator.allocate(8 * size).order(ByteOrder.nativeOrder()).asDoubleBuffer();
DoubleBuffer buf = ALLOCATOR.allocate(8 * size).order(ByteOrder.nativeOrder()).asDoubleBuffer();
buf.clear();
onBufferAllocated(buf);
return buf;
@ -872,7 +856,7 @@ public final class BufferUtils {
* @return the new FloatBuffer
*/
public static FloatBuffer createFloatBuffer(int size) {
FloatBuffer buf = allocator.allocate(4 * size).order(ByteOrder.nativeOrder()).asFloatBuffer();
FloatBuffer buf = ALLOCATOR.allocate(4 * size).order(ByteOrder.nativeOrder()).asFloatBuffer();
buf.clear();
onBufferAllocated(buf);
return buf;
@ -934,7 +918,7 @@ public final class BufferUtils {
* @return the new IntBuffer
*/
public static IntBuffer createIntBuffer(int size) {
IntBuffer buf = allocator.allocate(4 * size).order(ByteOrder.nativeOrder()).asIntBuffer();
IntBuffer buf = ALLOCATOR.allocate(4 * size).order(ByteOrder.nativeOrder()).asIntBuffer();
buf.clear();
onBufferAllocated(buf);
return buf;
@ -997,7 +981,7 @@ public final class BufferUtils {
* @return the new IntBuffer
*/
public static ByteBuffer createByteBuffer(int size) {
ByteBuffer buf = allocator.allocate(size).order(ByteOrder.nativeOrder());
ByteBuffer buf = ALLOCATOR.allocate(size).order(ByteOrder.nativeOrder());
buf.clear();
onBufferAllocated(buf);
return buf;
@ -1079,7 +1063,7 @@ public final class BufferUtils {
* @return the new ShortBuffer
*/
public static ShortBuffer createShortBuffer(int size) {
ShortBuffer buf = allocator.allocate(2 * size).order(ByteOrder.nativeOrder()).asShortBuffer();
ShortBuffer buf = ALLOCATOR.allocate(2 * size).order(ByteOrder.nativeOrder()).asShortBuffer();
buf.clear();
onBufferAllocated(buf);
return buf;
@ -1292,7 +1276,7 @@ public final class BufferUtils {
if (!isDirect(toBeDestroyed)) {
return;
}
allocator.destroyDirectBuffer(toBeDestroyed);
ALLOCATOR.destroyDirectBuffer(toBeDestroyed);
}
/*

@ -32,6 +32,10 @@
package com.jme3.system.lwjgl;
import static org.lwjgl.opencl.CL10.CL_CONTEXT_PLATFORM;
import static org.lwjgl.opengl.GL.createCapabilities;
import static org.lwjgl.opengl.GL11.glGetInteger;
import com.jme3.input.lwjgl.GlfwJoystickInput;
import com.jme3.input.lwjgl.GlfwKeyInput;
import com.jme3.input.lwjgl.GlfwMouseInput;
@ -48,14 +52,24 @@ import com.jme3.renderer.lwjgl.LwjglGL;
import com.jme3.renderer.lwjgl.LwjglGLExt;
import com.jme3.renderer.lwjgl.LwjglGLFboEXT;
import com.jme3.renderer.lwjgl.LwjglGLFboGL3;
import com.jme3.renderer.opengl.*;
import com.jme3.system.*;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.jme3.renderer.opengl.GL;
import com.jme3.renderer.opengl.GL2;
import com.jme3.renderer.opengl.GL3;
import com.jme3.renderer.opengl.GL4;
import com.jme3.renderer.opengl.GLDebugDesktop;
import com.jme3.renderer.opengl.GLExt;
import com.jme3.renderer.opengl.GLFbo;
import com.jme3.renderer.opengl.GLRenderer;
import com.jme3.renderer.opengl.GLTiming;
import com.jme3.renderer.opengl.GLTimingState;
import com.jme3.renderer.opengl.GLTracer;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeContext;
import com.jme3.system.SystemListener;
import com.jme3.system.Timer;
import com.jme3.util.BufferAllocatorFactory;
import com.jme3.util.LWJGLBufferAllocator;
import org.lwjgl.PointerBuffer;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opencl.*;
@ -63,18 +77,25 @@ import org.lwjgl.opengl.ARBDebugOutput;
import org.lwjgl.opengl.ARBFramebufferObject;
import org.lwjgl.opengl.EXTFramebufferMultisample;
import org.lwjgl.opengl.GLCapabilities;
import org.lwjgl.system.Platform;
import static org.lwjgl.glfw.GLFW.GLFW_TRUE;
import static org.lwjgl.opencl.CL10.CL_CONTEXT_PLATFORM;
import static org.lwjgl.opengl.GL.createCapabilities;
import static org.lwjgl.opengl.GL11.glGetInteger;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* A LWJGL implementation of a graphics context.
*/
public abstract class LwjglContext implements JmeContext {
private static final Logger logger = Logger.getLogger(LwjglContext.class.getName());
private static final Logger LOGGER = Logger.getLogger(LwjglContext.class.getName());
static {
System.setProperty(BufferAllocatorFactory.PROPERTY_BUFFER_ALLOCATOR_IMPLEMENTATION, LWJGLBufferAllocator.class.getName());
}
public static final boolean CL_GL_SHARING_POSSIBLE = true;
@ -99,7 +120,7 @@ public abstract class LwjglContext implements JmeContext {
}
protected void printContextInitInfo() {
logger.log(Level.INFO, "LWJGL {0} context running on thread {1}\n"
LOGGER.log(Level.INFO, "LWJGL {0} context running on thread {1}\n"
+ " * Graphics Adapter: GLFW {2}",
new Object[]{org.lwjgl.Version.getVersion(), Thread.currentThread().getName(), GLFW.glfwGetVersionString()});
}
@ -121,7 +142,7 @@ public abstract class LwjglContext implements JmeContext {
samples = settings.getSamples();
final int supportedSamples = determineMaxSamples();
if (supportedSamples < samples) {
logger.log(Level.WARNING,
LOGGER.log(Level.WARNING,
"Couldn't satisfy antialiasing samples requirement: x{0}. "
+ "Video hardware only supports: x{1}",
new Object[]{samples, supportedSamples});
@ -205,8 +226,6 @@ public abstract class LwjglContext implements JmeContext {
*
* Copied from the old release
*
* @param filter the platform filter
*
* @return the available platforms
*/
private static long[] getPlatforms() {
@ -233,12 +252,12 @@ public abstract class LwjglContext implements JmeContext {
}
protected void initOpenCL(long window) {
logger.info("Initialize OpenCL with LWJGL3");
LOGGER.info("Initialize OpenCL with LWJGL3");
// try {
// CL.create();
// } catch (Exception ex) {
// logger.log(Level.SEVERE, "Unable to initialize OpenCL", ex);
// LOGGER.log(Level.SEVERE, "Unable to initialize OpenCL", ex);
// return;
// }
@ -279,7 +298,7 @@ public abstract class LwjglContext implements JmeContext {
platformInfos.append("\n * * Supports interop: ").append(device.hasOpenGLInterop());
}
}
logger.info(platformInfos.toString());
LOGGER.info(platformInfos.toString());
//choose devices
PlatformChooser chooser = null;
@ -287,7 +306,7 @@ public abstract class LwjglContext implements JmeContext {
try {
chooser = (PlatformChooser) Class.forName(settings.getOpenCLPlatformChooser()).newInstance();
} catch (Exception ex) {
logger.log(Level.WARNING, "unable to instantiate custom PlatformChooser", ex);
LOGGER.log(Level.WARNING, "unable to instantiate custom PlatformChooser", ex);
}
}
if (chooser == null) {
@ -298,35 +317,35 @@ public abstract class LwjglContext implements JmeContext {
LwjglPlatform platform = null;
for (Device d : choosenDevices) {
if (!(d instanceof LwjglDevice)) {
logger.log(Level.SEVERE, "attempt to return a custom Device implementation from PlatformChooser: {0}", d);
LOGGER.log(Level.SEVERE, "attempt to return a custom Device implementation from PlatformChooser: {0}", d);
return;
}
LwjglDevice ld = (LwjglDevice) d;
if (platform == null) {
platform = ld.getPlatform();
} else if (platform != ld.getPlatform()) {
logger.severe("attempt to use devices from different platforms");
LOGGER.severe("attempt to use devices from different platforms");
return;
}
devices.add(ld.getDevice());
}
if (devices.isEmpty()) {
logger.warning("no devices specified, no OpenCL context created");
LOGGER.warning("no devices specified, no OpenCL context created");
return;
}
logger.log(Level.INFO, "chosen platform: {0}", platform.getName());
logger.log(Level.INFO, "chosen devices: {0}", choosenDevices);
LOGGER.log(Level.INFO, "chosen platform: {0}", platform.getName());
LOGGER.log(Level.INFO, "chosen devices: {0}", choosenDevices);
//create context
try {
long c = createContext(platform.getPlatform(), devices, window);
clContext = new com.jme3.opencl.lwjgl.LwjglContext(c, (List<LwjglDevice>) choosenDevices);
} catch (Exception ex) {
logger.log(Level.SEVERE, "Unable to create OpenCL context", ex);
} catch (final Exception ex) {
LOGGER.log(Level.SEVERE, "Unable to create OpenCL context", ex);
return;
}
logger.info("OpenCL context created");
LOGGER.info("OpenCL context created");
}
private long createContext(final long platform, final List<Long> devices, long window) throws Exception {
@ -338,7 +357,7 @@ public abstract class LwjglContext implements JmeContext {
//https://github.com/glfw/glfw/issues/104
//https://github.com/LWJGL/lwjgl3/blob/master/modules/core/src/test/java/org/lwjgl/demo/opencl/Mandelbrot.java
//TODO: test on Linus and MacOSX
switch (org.lwjgl.system.Platform.get()) {
switch (Platform.get()) {
case WINDOWS:
properties
.put(KHRGLSharing.CL_GL_CONTEXT_KHR)
@ -446,5 +465,4 @@ public abstract class LwjglContext implements JmeContext {
public Context getOpenCLContext() {
return clContext;
}
}

@ -0,0 +1,24 @@
package com.jme3.util;
import org.lwjgl.system.MemoryUtil;
import java.nio.Buffer;
import java.nio.ByteBuffer;
/**
* The implementation of the {@link BufferAllocator} which use {@link MemoryUtil} to manage memory.
*
* @author JavaSaBr
*/
public class LWJGLBufferAllocator implements BufferAllocator {
@Override
public void destroyDirectBuffer(final Buffer buffer) {
MemoryUtil.memFree(buffer);
}
@Override
public ByteBuffer allocate(final int size) {
return MemoryUtil.memAlloc(size);
}
}
Loading…
Cancel
Save