diff --git a/jme3-core/src/main/java/com/jme3/util/BufferAllocatorFactory.java b/jme3-core/src/main/java/com/jme3/util/BufferAllocatorFactory.java new file mode 100644 index 000000000..dd77c4d1a --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/util/BufferAllocatorFactory.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(); + } + } +} diff --git a/jme3-core/src/main/java/com/jme3/util/BufferUtils.java b/jme3-core/src/main/java/com/jme3/util/BufferUtils.java index 6ad4712b8..d8b6bca03 100644 --- a/jme3-core/src/main/java/com/jme3/util/BufferUtils.java +++ b/jme3-core/src/main/java/com/jme3/util/BufferUtils.java @@ -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; - /** * BufferUtils is a helper class for generating nio buffers from * jME data classes such as Vectors and ColorRGBA. @@ -59,35 +59,17 @@ 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 removeCollected = new ReferenceQueue(); private static ConcurrentHashMap trackedBuffers = new ConcurrentHashMap(); static ClearReferences cleanupthread; - 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 @@ -124,7 +106,7 @@ public final class BufferUtils { } private static void onBufferAllocated(Buffer buffer) { - used = true; + if (BufferUtils.trackDirectMemory) { if (BufferUtils.cleanupthread == null) { BufferUtils.cleanupthread = new ClearReferences(); diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglContext.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglContext.java index 04265df97..1add5a529 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglContext.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglContext.java @@ -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,26 +52,41 @@ 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.*; +import org.lwjgl.opencl.APPLEGLSharing; +import org.lwjgl.opencl.CL10; +import org.lwjgl.opencl.KHRGLSharing; 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. @@ -76,6 +95,13 @@ public abstract class LwjglContext implements JmeContext { private static final Logger logger = Logger.getLogger(LwjglContext.class.getName()); + static { + final String implementation = BufferAllocatorFactory.PROPERTY_BUFFER_ALLOCATOR_IMPLEMENTATION; + if(System.getProperty(implementation) == null) { + System.setProperty(implementation, LWJGLBufferAllocator.class.getName()); + } + } + public static final boolean CL_GL_SHARING_POSSIBLE = true; protected static final String THREAD_NAME = "jME3 Main"; @@ -100,7 +126,7 @@ public abstract class LwjglContext implements JmeContext { protected void printContextInitInfo() { logger.log(Level.INFO, "LWJGL {0} context running on thread {1}\n" - + " * Graphics Adapter: GLFW {2}", + + " * Graphics Adapter: GLFW {2}", new Object[]{org.lwjgl.Version.getVersion(), Thread.currentThread().getName(), GLFW.glfwGetVersionString()}); } @@ -205,8 +231,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() { @@ -321,7 +345,7 @@ public abstract class LwjglContext implements JmeContext { try { long c = createContext(platform.getPlatform(), devices, window); clContext = new com.jme3.opencl.lwjgl.LwjglContext(c, (List) choosenDevices); - } catch (Exception ex) { + } catch (final Exception ex) { logger.log(Level.SEVERE, "Unable to create OpenCL context", ex); return; } @@ -338,7 +362,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 +470,4 @@ public abstract class LwjglContext implements JmeContext { public Context getOpenCLContext() { return clContext; } - } diff --git a/jme3-lwjgl3/src/main/java/com/jme3/util/LWJGLBufferAllocator.java b/jme3-lwjgl3/src/main/java/com/jme3/util/LWJGLBufferAllocator.java new file mode 100644 index 000000000..5d65004cb --- /dev/null +++ b/jme3-lwjgl3/src/main/java/com/jme3/util/LWJGLBufferAllocator.java @@ -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); + } +}