فهرست منبع

implemented LWJGL3 BufferAllocator

javasabr 8 سال پیش
والد
کامیت
d468c20fba

+ 31 - 0
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();
+        }
+    }
+}

+ 17 - 33
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;
-
 /**
  * <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);
     }
 
     /*

+ 50 - 32
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,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,8 +120,8 @@ 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}",
+        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;
     }
-
 }

+ 24 - 0
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);
+    }
+}