Selaa lähdekoodia

Merge pull request #684 from JavaSaBr/fix_lwjgl_buffer

added support multi-threading allocations for LWJGL Buffer Allocator.
empirephoenix 8 vuotta sitten
vanhempi
commit
c6f1da0602

+ 11 - 15
jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglContext.java

@@ -32,10 +32,10 @@
 
 package com.jme3.system.lwjgl;
 
+import static com.jme3.util.LWJGLBufferAllocator.PROPERTY_CONCURRENT_BUFFER_ALLOCATOR;
 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;
@@ -52,24 +52,14 @@ 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.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.renderer.opengl.*;
 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 com.jme3.util.LWJGLBufferAllocator.ConcurrentLWJGLBufferAllocator;
 import org.lwjgl.PointerBuffer;
 import org.lwjgl.glfw.GLFW;
 import org.lwjgl.opencl.APPLEGLSharing;
@@ -96,9 +86,15 @@ 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());
+
+        if (System.getProperty(implementation) == null) {
+            if (Boolean.parseBoolean(System.getProperty(PROPERTY_CONCURRENT_BUFFER_ALLOCATOR, "true"))) {
+                System.setProperty(implementation, ConcurrentLWJGLBufferAllocator.class.getName());
+            } else {
+                System.setProperty(implementation, LWJGLBufferAllocator.class.getName());
+            }
         }
     }
 

+ 42 - 2
jme3-lwjgl3/src/main/java/com/jme3/util/LWJGLBufferAllocator.java

@@ -7,6 +7,7 @@ import java.lang.ref.ReferenceQueue;
 import java.nio.*;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.StampedLock;
 import java.util.logging.Logger;
 
 /**
@@ -18,10 +19,49 @@ public class LWJGLBufferAllocator implements BufferAllocator {
 
     private static final Logger LOGGER = Logger.getLogger(LWJGLBufferAllocator.class.getName());
 
+    public static final String PROPERTY_CONCURRENT_BUFFER_ALLOCATOR = "com.jme3.lwjgl3.ConcurrentBufferAllocator";
+
+    /**
+     * Threadsafe implementation of the {@link LWJGLBufferAllocator}.
+     *
+     * @author JavaSaBr
+     */
+    public static class ConcurrentLWJGLBufferAllocator extends LWJGLBufferAllocator {
+
+        /**
+         * The synchronizer.
+         */
+        private final StampedLock stampedLock;
+
+        public ConcurrentLWJGLBufferAllocator() {
+            this.stampedLock = new StampedLock();
+        }
+
+        @Override
+        public void destroyDirectBuffer(final Buffer buffer) {
+            final long stamp = stampedLock.writeLock();
+            try {
+                super.destroyDirectBuffer(buffer);
+            } finally {
+                stampedLock.unlockWrite(stamp);
+            }
+        }
+
+        @Override
+        public ByteBuffer allocate(final int size) {
+            final long stamp = stampedLock.writeLock();
+            try {
+                return super.allocate(size);
+            } finally {
+                stampedLock.unlockWrite(stamp);
+            }
+        }
+    }
+
     /**
      * The reference queue.
      */
-    private static final ReferenceQueue<Buffer> DUMMY_QUEUE = new ReferenceQueue<Buffer>();
+    private static final ReferenceQueue<Buffer> DUMMY_QUEUE = new ReferenceQueue<>();
 
     /**
      * The LWJGL byte buffer deallocator.
@@ -76,7 +116,7 @@ public class LWJGLBufferAllocator implements BufferAllocator {
      */
     private static void freeByteBuffers() {
         try {
-            for (; ; ) {
+            for (;;) {
                 final Deallocator deallocator = (Deallocator) DUMMY_QUEUE.remove();
                 deallocator.free();
             }