Skip to content

Commit d468c20

Browse files
committed
implemented LWJGL3 BufferAllocator
1 parent 8d818a2 commit d468c20

File tree

4 files changed

+122
-65
lines changed

4 files changed

+122
-65
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.jme3.util;
2+
3+
import com.jme3.system.Annotations.Internal;
4+
5+
import java.util.logging.Level;
6+
import java.util.logging.Logger;
7+
8+
/**
9+
* The factory of buffer allocators.
10+
*
11+
* @author JavaSaBR
12+
*/
13+
@Internal
14+
public class BufferAllocatorFactory {
15+
16+
public static final String PROPERTY_BUFFER_ALLOCATOR_IMPLEMENTATION = "com.jme3.BufferAllocatorImplementation";
17+
18+
private static final Logger LOGGER = Logger.getLogger(BufferAllocatorFactory.class.getName());
19+
20+
@Internal
21+
protected static BufferAllocator create() {
22+
23+
final String className = System.getProperty(PROPERTY_BUFFER_ALLOCATOR_IMPLEMENTATION, ReflectionAllocator.class.getName());
24+
try {
25+
return (BufferAllocator) Class.forName(className).newInstance();
26+
} catch (final Throwable e) {
27+
LOGGER.log(Level.WARNING, "Unable to access {0}", className);
28+
return new PrimitiveAllocator();
29+
}
30+
}
31+
}

jme3-core/src/main/java/com/jme3/util/BufferUtils.java

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@
3131
*/
3232
package com.jme3.util;
3333

34+
import com.jme3.math.ColorRGBA;
35+
import com.jme3.math.Quaternion;
36+
import com.jme3.math.Vector2f;
37+
import com.jme3.math.Vector3f;
38+
import com.jme3.math.Vector4f;
39+
3440
import java.io.UnsupportedEncodingException;
3541
import java.lang.ref.PhantomReference;
3642
import java.lang.ref.Reference;
@@ -45,12 +51,6 @@
4551
import java.nio.ShortBuffer;
4652
import java.util.concurrent.ConcurrentHashMap;
4753

48-
import com.jme3.math.ColorRGBA;
49-
import com.jme3.math.Quaternion;
50-
import com.jme3.math.Vector2f;
51-
import com.jme3.math.Vector3f;
52-
import com.jme3.math.Vector4f;
53-
5454
/**
5555
* <code>BufferUtils</code> is a helper class for generating nio buffers from
5656
* jME data classes such as Vectors and ColorRGBA.
@@ -59,7 +59,11 @@
5959
* @version $Id: BufferUtils.java,v 1.16 2007/10/29 16:56:18 nca Exp $
6060
*/
6161
public final class BufferUtils {
62-
private static BufferAllocator allocator = new PrimitiveAllocator();
62+
63+
/**
64+
* The field should be final to support thread-safe.
65+
*/
66+
private static final BufferAllocator ALLOCATOR = BufferAllocatorFactory.create();
6367

6468
private static boolean trackDirectMemory = false;
6569
private static ReferenceQueue<Buffer> removeCollected = new ReferenceQueue<Buffer>();
@@ -68,26 +72,6 @@ public final class BufferUtils {
6872

6973
private static boolean used;
7074

71-
static {
72-
try {
73-
allocator = new ReflectionAllocator();
74-
} catch (Throwable t) {
75-
t.printStackTrace();
76-
System.err.println("Error using ReflectionAllocator");
77-
}
78-
}
79-
80-
/**
81-
* Warning! do only set this before JME is started!
82-
*/
83-
public static void setAllocator(BufferAllocator allocator) {
84-
if (used) {
85-
throw new IllegalStateException(
86-
"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");
87-
}
88-
BufferUtils.allocator = allocator;
89-
}
90-
9175
/**
9276
* Set it to true if you want to enable direct memory tracking for debugging
9377
* purpose. Default is false. To print direct memory usage use
@@ -809,7 +793,7 @@ public static float[] getFloatArray(FloatBuffer buff) {
809793
* @return the new DoubleBuffer
810794
*/
811795
public static DoubleBuffer createDoubleBuffer(int size) {
812-
DoubleBuffer buf = allocator.allocate(8 * size).order(ByteOrder.nativeOrder()).asDoubleBuffer();
796+
DoubleBuffer buf = ALLOCATOR.allocate(8 * size).order(ByteOrder.nativeOrder()).asDoubleBuffer();
813797
buf.clear();
814798
onBufferAllocated(buf);
815799
return buf;
@@ -872,7 +856,7 @@ public static DoubleBuffer clone(DoubleBuffer buf) {
872856
* @return the new FloatBuffer
873857
*/
874858
public static FloatBuffer createFloatBuffer(int size) {
875-
FloatBuffer buf = allocator.allocate(4 * size).order(ByteOrder.nativeOrder()).asFloatBuffer();
859+
FloatBuffer buf = ALLOCATOR.allocate(4 * size).order(ByteOrder.nativeOrder()).asFloatBuffer();
876860
buf.clear();
877861
onBufferAllocated(buf);
878862
return buf;
@@ -934,7 +918,7 @@ public static FloatBuffer clone(FloatBuffer buf) {
934918
* @return the new IntBuffer
935919
*/
936920
public static IntBuffer createIntBuffer(int size) {
937-
IntBuffer buf = allocator.allocate(4 * size).order(ByteOrder.nativeOrder()).asIntBuffer();
921+
IntBuffer buf = ALLOCATOR.allocate(4 * size).order(ByteOrder.nativeOrder()).asIntBuffer();
938922
buf.clear();
939923
onBufferAllocated(buf);
940924
return buf;
@@ -997,7 +981,7 @@ public static IntBuffer clone(IntBuffer buf) {
997981
* @return the new IntBuffer
998982
*/
999983
public static ByteBuffer createByteBuffer(int size) {
1000-
ByteBuffer buf = allocator.allocate(size).order(ByteOrder.nativeOrder());
984+
ByteBuffer buf = ALLOCATOR.allocate(size).order(ByteOrder.nativeOrder());
1001985
buf.clear();
1002986
onBufferAllocated(buf);
1003987
return buf;
@@ -1079,7 +1063,7 @@ public static ByteBuffer clone(ByteBuffer buf) {
10791063
* @return the new ShortBuffer
10801064
*/
10811065
public static ShortBuffer createShortBuffer(int size) {
1082-
ShortBuffer buf = allocator.allocate(2 * size).order(ByteOrder.nativeOrder()).asShortBuffer();
1066+
ShortBuffer buf = ALLOCATOR.allocate(2 * size).order(ByteOrder.nativeOrder()).asShortBuffer();
10831067
buf.clear();
10841068
onBufferAllocated(buf);
10851069
return buf;
@@ -1292,7 +1276,7 @@ public static void destroyDirectBuffer(Buffer toBeDestroyed) {
12921276
if (!isDirect(toBeDestroyed)) {
12931277
return;
12941278
}
1295-
allocator.destroyDirectBuffer(toBeDestroyed);
1279+
ALLOCATOR.destroyDirectBuffer(toBeDestroyed);
12961280
}
12971281

12981282
/*

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

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232

3333
package com.jme3.system.lwjgl;
3434

35+
import static org.lwjgl.opencl.CL10.CL_CONTEXT_PLATFORM;
36+
import static org.lwjgl.opengl.GL.createCapabilities;
37+
import static org.lwjgl.opengl.GL11.glGetInteger;
38+
3539
import com.jme3.input.lwjgl.GlfwJoystickInput;
3640
import com.jme3.input.lwjgl.GlfwKeyInput;
3741
import com.jme3.input.lwjgl.GlfwMouseInput;
@@ -48,33 +52,50 @@
4852
import com.jme3.renderer.lwjgl.LwjglGLExt;
4953
import com.jme3.renderer.lwjgl.LwjglGLFboEXT;
5054
import com.jme3.renderer.lwjgl.LwjglGLFboGL3;
51-
import com.jme3.renderer.opengl.*;
52-
import com.jme3.system.*;
53-
import java.nio.IntBuffer;
54-
import java.util.ArrayList;
55-
import java.util.List;
56-
import java.util.concurrent.atomic.AtomicBoolean;
57-
import java.util.logging.Level;
58-
import java.util.logging.Logger;
55+
import com.jme3.renderer.opengl.GL;
56+
import com.jme3.renderer.opengl.GL2;
57+
import com.jme3.renderer.opengl.GL3;
58+
import com.jme3.renderer.opengl.GL4;
59+
import com.jme3.renderer.opengl.GLDebugDesktop;
60+
import com.jme3.renderer.opengl.GLExt;
61+
import com.jme3.renderer.opengl.GLFbo;
62+
import com.jme3.renderer.opengl.GLRenderer;
63+
import com.jme3.renderer.opengl.GLTiming;
64+
import com.jme3.renderer.opengl.GLTimingState;
65+
import com.jme3.renderer.opengl.GLTracer;
66+
import com.jme3.system.AppSettings;
67+
import com.jme3.system.JmeContext;
68+
import com.jme3.system.SystemListener;
69+
import com.jme3.system.Timer;
70+
import com.jme3.util.BufferAllocatorFactory;
71+
import com.jme3.util.LWJGLBufferAllocator;
72+
5973
import org.lwjgl.PointerBuffer;
6074
import org.lwjgl.glfw.GLFW;
6175
import org.lwjgl.opencl.*;
6276
import org.lwjgl.opengl.ARBDebugOutput;
6377
import org.lwjgl.opengl.ARBFramebufferObject;
6478
import org.lwjgl.opengl.EXTFramebufferMultisample;
6579
import org.lwjgl.opengl.GLCapabilities;
80+
import org.lwjgl.system.Platform;
6681

67-
import static org.lwjgl.glfw.GLFW.GLFW_TRUE;
68-
import static org.lwjgl.opencl.CL10.CL_CONTEXT_PLATFORM;
69-
import static org.lwjgl.opengl.GL.createCapabilities;
70-
import static org.lwjgl.opengl.GL11.glGetInteger;
82+
import java.nio.IntBuffer;
83+
import java.util.ArrayList;
84+
import java.util.List;
85+
import java.util.concurrent.atomic.AtomicBoolean;
86+
import java.util.logging.Level;
87+
import java.util.logging.Logger;
7188

7289
/**
7390
* A LWJGL implementation of a graphics context.
7491
*/
7592
public abstract class LwjglContext implements JmeContext {
7693

77-
private static final Logger logger = Logger.getLogger(LwjglContext.class.getName());
94+
private static final Logger LOGGER = Logger.getLogger(LwjglContext.class.getName());
95+
96+
static {
97+
System.setProperty(BufferAllocatorFactory.PROPERTY_BUFFER_ALLOCATOR_IMPLEMENTATION, LWJGLBufferAllocator.class.getName());
98+
}
7899

79100
public static final boolean CL_GL_SHARING_POSSIBLE = true;
80101

@@ -99,8 +120,8 @@ public void setSystemListener(SystemListener listener) {
99120
}
100121

101122
protected void printContextInitInfo() {
102-
logger.log(Level.INFO, "LWJGL {0} context running on thread {1}\n"
103-
+ " * Graphics Adapter: GLFW {2}",
123+
LOGGER.log(Level.INFO, "LWJGL {0} context running on thread {1}\n"
124+
+ " * Graphics Adapter: GLFW {2}",
104125
new Object[]{org.lwjgl.Version.getVersion(), Thread.currentThread().getName(), GLFW.glfwGetVersionString()});
105126
}
106127

@@ -121,7 +142,7 @@ protected int getNumSamplesToUse() {
121142
samples = settings.getSamples();
122143
final int supportedSamples = determineMaxSamples();
123144
if (supportedSamples < samples) {
124-
logger.log(Level.WARNING,
145+
LOGGER.log(Level.WARNING,
125146
"Couldn't satisfy antialiasing samples requirement: x{0}. "
126147
+ "Video hardware only supports: x{1}",
127148
new Object[]{samples, supportedSamples});
@@ -205,8 +226,6 @@ protected void initContextFirstTime() {
205226
*
206227
* Copied from the old release
207228
*
208-
* @param filter the platform filter
209-
*
210229
* @return the available platforms
211230
*/
212231
private static long[] getPlatforms() {
@@ -233,12 +252,12 @@ private static long[] getPlatforms() {
233252
}
234253

235254
protected void initOpenCL(long window) {
236-
logger.info("Initialize OpenCL with LWJGL3");
255+
LOGGER.info("Initialize OpenCL with LWJGL3");
237256

238257
// try {
239258
// CL.create();
240259
// } catch (Exception ex) {
241-
// logger.log(Level.SEVERE, "Unable to initialize OpenCL", ex);
260+
// LOGGER.log(Level.SEVERE, "Unable to initialize OpenCL", ex);
242261
// return;
243262
// }
244263

@@ -279,15 +298,15 @@ protected void initOpenCL(long window) {
279298
platformInfos.append("\n * * Supports interop: ").append(device.hasOpenGLInterop());
280299
}
281300
}
282-
logger.info(platformInfos.toString());
301+
LOGGER.info(platformInfos.toString());
283302

284303
//choose devices
285304
PlatformChooser chooser = null;
286305
if (settings.getOpenCLPlatformChooser() != null) {
287306
try {
288307
chooser = (PlatformChooser) Class.forName(settings.getOpenCLPlatformChooser()).newInstance();
289308
} catch (Exception ex) {
290-
logger.log(Level.WARNING, "unable to instantiate custom PlatformChooser", ex);
309+
LOGGER.log(Level.WARNING, "unable to instantiate custom PlatformChooser", ex);
291310
}
292311
}
293312
if (chooser == null) {
@@ -298,35 +317,35 @@ protected void initOpenCL(long window) {
298317
LwjglPlatform platform = null;
299318
for (Device d : choosenDevices) {
300319
if (!(d instanceof LwjglDevice)) {
301-
logger.log(Level.SEVERE, "attempt to return a custom Device implementation from PlatformChooser: {0}", d);
320+
LOGGER.log(Level.SEVERE, "attempt to return a custom Device implementation from PlatformChooser: {0}", d);
302321
return;
303322
}
304323
LwjglDevice ld = (LwjglDevice) d;
305324
if (platform == null) {
306325
platform = ld.getPlatform();
307326
} else if (platform != ld.getPlatform()) {
308-
logger.severe("attempt to use devices from different platforms");
327+
LOGGER.severe("attempt to use devices from different platforms");
309328
return;
310329
}
311330
devices.add(ld.getDevice());
312331
}
313332
if (devices.isEmpty()) {
314-
logger.warning("no devices specified, no OpenCL context created");
333+
LOGGER.warning("no devices specified, no OpenCL context created");
315334
return;
316335
}
317-
logger.log(Level.INFO, "chosen platform: {0}", platform.getName());
318-
logger.log(Level.INFO, "chosen devices: {0}", choosenDevices);
336+
LOGGER.log(Level.INFO, "chosen platform: {0}", platform.getName());
337+
LOGGER.log(Level.INFO, "chosen devices: {0}", choosenDevices);
319338

320339
//create context
321340
try {
322341
long c = createContext(platform.getPlatform(), devices, window);
323342
clContext = new com.jme3.opencl.lwjgl.LwjglContext(c, (List<LwjglDevice>) choosenDevices);
324-
} catch (Exception ex) {
325-
logger.log(Level.SEVERE, "Unable to create OpenCL context", ex);
343+
} catch (final Exception ex) {
344+
LOGGER.log(Level.SEVERE, "Unable to create OpenCL context", ex);
326345
return;
327346
}
328347

329-
logger.info("OpenCL context created");
348+
LOGGER.info("OpenCL context created");
330349
}
331350
private long createContext(final long platform, final List<Long> devices, long window) throws Exception {
332351

@@ -338,7 +357,7 @@ private long createContext(final long platform, final List<Long> devices, long w
338357
//https://github.com/glfw/glfw/issues/104
339358
//https://github.com/LWJGL/lwjgl3/blob/master/modules/core/src/test/java/org/lwjgl/demo/opencl/Mandelbrot.java
340359
//TODO: test on Linus and MacOSX
341-
switch (org.lwjgl.system.Platform.get()) {
360+
switch (Platform.get()) {
342361
case WINDOWS:
343362
properties
344363
.put(KHRGLSharing.CL_GL_CONTEXT_KHR)
@@ -446,5 +465,4 @@ public Timer getTimer() {
446465
public Context getOpenCLContext() {
447466
return clContext;
448467
}
449-
450468
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.jme3.util;
2+
3+
import org.lwjgl.system.MemoryUtil;
4+
5+
import java.nio.Buffer;
6+
import java.nio.ByteBuffer;
7+
8+
/**
9+
* The implementation of the {@link BufferAllocator} which use {@link MemoryUtil} to manage memory.
10+
*
11+
* @author JavaSaBr
12+
*/
13+
public class LWJGLBufferAllocator implements BufferAllocator {
14+
15+
@Override
16+
public void destroyDirectBuffer(final Buffer buffer) {
17+
MemoryUtil.memFree(buffer);
18+
}
19+
20+
@Override
21+
public ByteBuffer allocate(final int size) {
22+
return MemoryUtil.memAlloc(size);
23+
}
24+
}

0 commit comments

Comments
 (0)