diff --git a/jme3-core/src/main/java/com/jme3/opencl/AbstractOpenCLObject.java b/jme3-core/src/main/java/com/jme3/opencl/AbstractOpenCLObject.java
new file mode 100644
index 000000000..fce0f481d
--- /dev/null
+++ b/jme3-core/src/main/java/com/jme3/opencl/AbstractOpenCLObject.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2009-2016 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.opencl;
+
+/**
+ * Abstract implementation of {@link OpenCLObject} providing the release
+ * mechanisms.
+ * @author Sebastian Weiss
+ */
+public abstract class AbstractOpenCLObject implements OpenCLObject {
+
+ protected final ObjectReleaser releaser;
+ protected AbstractOpenCLObject(ObjectReleaser releaser) {
+ this.releaser = releaser;
+ }
+ @Override
+ public void register() {
+ OpenCLObjectManager.getInstance().registerObject(this);
+ }
+ @Override
+ public void release() {
+ releaser.release();
+ }
+ @Override
+ @SuppressWarnings("FinalizeDeclaration")
+ protected void finalize() throws Throwable {
+ release();
+ }
+ @Override
+ public ObjectReleaser getReleaser() {
+ return releaser;
+ }
+}
diff --git a/jme3-core/src/main/java/com/jme3/opencl/Buffer.java b/jme3-core/src/main/java/com/jme3/opencl/Buffer.java
index 5bb474e36..66ce0c8f7 100644
--- a/jme3-core/src/main/java/com/jme3/opencl/Buffer.java
+++ b/jme3-core/src/main/java/com/jme3/opencl/Buffer.java
@@ -47,8 +47,12 @@ import java.nio.ByteBuffer;
* @see Context#createBuffer(long, com.jme3.opencl.MemoryAccess)
* @author shaman
*/
-public abstract class Buffer implements OpenCLObject {
+public abstract class Buffer extends AbstractOpenCLObject {
+ protected Buffer(ObjectReleaser releaser) {
+ super(releaser);
+ }
+
/**
* @return the size of the buffer in bytes.
* @see Context#createBuffer(long)
diff --git a/jme3-core/src/main/java/com/jme3/opencl/CommandQueue.java b/jme3-core/src/main/java/com/jme3/opencl/CommandQueue.java
index 3fb5bcf6f..6d54237f9 100644
--- a/jme3-core/src/main/java/com/jme3/opencl/CommandQueue.java
+++ b/jme3-core/src/main/java/com/jme3/opencl/CommandQueue.java
@@ -42,8 +42,12 @@ package com.jme3.opencl;
* and all commands are sent to this device.
* @author shaman
*/
-public interface CommandQueue extends OpenCLObject {
+public abstract class CommandQueue extends AbstractOpenCLObject {
+ protected CommandQueue(ObjectReleaser releaser) {
+ super(releaser);
+ }
+
/**
* Issues all previously queued OpenCL commands in command_queue to the
* device associated with command queue. Flush only guarantees that all
@@ -51,7 +55,7 @@ public interface CommandQueue extends OpenCLObject {
* appropriate device. There is no guarantee that they will be complete
* after flush returns.
*/
- void flush();
+ public abstract void flush();
/**
* Blocks until all previously queued OpenCL commands in command queue are
@@ -59,6 +63,6 @@ public interface CommandQueue extends OpenCLObject {
* return until all previously queued commands in command queue have been
* processed and completed. Finish is also a synchronization point.
*/
- void finish();
+ public abstract void finish();
}
diff --git a/jme3-core/src/main/java/com/jme3/opencl/Context.java b/jme3-core/src/main/java/com/jme3/opencl/Context.java
index 5dbfa961c..10dde71fc 100644
--- a/jme3-core/src/main/java/com/jme3/opencl/Context.java
+++ b/jme3-core/src/main/java/com/jme3/opencl/Context.java
@@ -63,9 +63,13 @@ import java.util.logging.Logger;
*
* @author shaman
*/
-public abstract class Context implements OpenCLObject {
+public abstract class Context extends AbstractOpenCLObject {
private static final Logger LOG = Logger.getLogger(Context.class.getName());
+ protected Context(ObjectReleaser releaser) {
+ super(releaser);
+ }
+
/**
* Returns all available devices for this context.
* These devices all belong to the same {@link Platform}.
diff --git a/jme3-core/src/main/java/com/jme3/opencl/Event.java b/jme3-core/src/main/java/com/jme3/opencl/Event.java
index 5399a97ef..44ea3da16 100644
--- a/jme3-core/src/main/java/com/jme3/opencl/Event.java
+++ b/jme3-core/src/main/java/com/jme3/opencl/Event.java
@@ -38,16 +38,22 @@ package com.jme3.opencl;
* is done.
* @author shaman
*/
-public interface Event extends OpenCLObject {
+public abstract class Event extends AbstractOpenCLObject {
+
+ protected Event(ObjectReleaser releaser) {
+ super(releaser);
+ }
/**
- * Waits until the action has finished (blocking)
+ * Waits until the action has finished (blocking).
+ * This automatically releases the event.
*/
- void waitForFinished();
+ public abstract void waitForFinished();
/**
- * Tests if the action is completed
+ * Tests if the action is completed.
+ * If the action is completed, the event is released.
* @return {@code true} if the action is completed
*/
- boolean isCompleted();
+ public abstract boolean isCompleted();
}
diff --git a/jme3-core/src/main/java/com/jme3/opencl/Image.java b/jme3-core/src/main/java/com/jme3/opencl/Image.java
index 92545021a..e58c20f7e 100644
--- a/jme3-core/src/main/java/com/jme3/opencl/Image.java
+++ b/jme3-core/src/main/java/com/jme3/opencl/Image.java
@@ -74,7 +74,7 @@ import java.util.Objects;
*
* @author shaman
*/
-public interface Image extends OpenCLObject {
+public abstract class Image extends AbstractOpenCLObject {
/**
* {@code ImageChannelType} describes the size of the channel data type.
@@ -245,47 +245,51 @@ memory layout in which channels are stored in the image.
}
}
+
+ protected Image(ObjectReleaser releaser) {
+ super(releaser);
+ }
/**
* @return the width of the image
*/
- long getWidth();
+ public abstract long getWidth();
/**
* @return the height of the image
*/
- long getHeight();
+ public abstract long getHeight();
/**
* @return the depth of the image
*/
- long getDepth();
+ public abstract long getDepth();
/**
* @return the row pitch when the image was created from a host buffer
* @see ImageDescriptor#ImageDescriptor(com.jme3.opencl.Image.ImageType, long, long, long, long, long, long, java.nio.ByteBuffer)
*/
- long getRowPitch();
+ public abstract long getRowPitch();
/**
* @return the slice pitch when the image was created from a host buffer
* @see ImageDescriptor#ImageDescriptor(com.jme3.opencl.Image.ImageType, long, long, long, long, long, long, java.nio.ByteBuffer)
*/
- long getSlicePitch();
+ public abstract long getSlicePitch();
/**
* @return the number of elements in the image array
* @see ImageType#IMAGE_1D_ARRAY
* @see ImageType#IMAGE_2D_ARRAY
*/
- long getArraySize();
+ public abstract long getArraySize();
/**
* @return the image format
*/
- ImageFormat getImageFormat();
+ public abstract ImageFormat getImageFormat();
/**
* @return the image type
*/
- ImageType getImageType();
+ public abstract ImageType getImageType();
/**
* @return the number of bytes per pixel
*/
- int getElementSize();
+ public abstract int getElementSize();
/**
* Performs a blocking read of the image into the specified byte buffer.
@@ -298,7 +302,7 @@ memory layout in which channels are stored in the image.
* @param slicePitch the slice pitch of the target buffer, must be set to 0 for 1D and 2D images.
* If set to 0 for 3D images, the slice pitch is calculated as {@code rowPitch * height}
*/
- void readImage(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch);
+ public abstract void readImage(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch);
/**
* Performs an async/non-blocking read of the image into the specified byte buffer.
* @param queue the command queue
@@ -311,7 +315,7 @@ memory layout in which channels are stored in the image.
* If set to 0 for 3D images, the slice pitch is calculated as {@code rowPitch * height}
* @return the event object indicating the status of the operation
*/
- Event readImageAsync(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch);
+ public abstract Event readImageAsync(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch);
/**
* Performs a blocking write from the specified byte buffer into the image.
@@ -324,7 +328,7 @@ memory layout in which channels are stored in the image.
* @param slicePitch the slice pitch of the target buffer, must be set to 0 for 1D and 2D images.
* If set to 0 for 3D images, the slice pitch is calculated as {@code rowPitch * height}
*/
- void writeImage(CommandQueue queue, ByteBuffer src, long[] origin, long[] region, long rowPitch, long slicePitch);
+ public abstract void writeImage(CommandQueue queue, ByteBuffer src, long[] origin, long[] region, long rowPitch, long slicePitch);
/**
* Performs an async/non-blocking write from the specified byte buffer into the image.
* @param queue the command queue
@@ -337,7 +341,7 @@ memory layout in which channels are stored in the image.
* If set to 0 for 3D images, the slice pitch is calculated as {@code rowPitch * height}
* @return the event object indicating the status of the operation
*/
- Event writeImageAsync(CommandQueue queue, ByteBuffer src, long[] origin, long[] region, long rowPitch, long slicePitch);
+ public abstract Event writeImageAsync(CommandQueue queue, ByteBuffer src, long[] origin, long[] region, long rowPitch, long slicePitch);
/**
* Performs a blocking copy operation from one image to another.
@@ -348,7 +352,7 @@ memory layout in which channels are stored in the image.
* @param destOrigin the target image origin, see class description for the format
* @param region the copied region, see class description for the format
*/
- void copyTo(CommandQueue queue, Image dest, long[] srcOrigin, long[] destOrigin, long[] region);
+ public abstract void copyTo(CommandQueue queue, Image dest, long[] srcOrigin, long[] destOrigin, long[] region);
/**
* Performs an async/non-blocking copy operation from one image to another.
* Important: Both images must have the same format!
@@ -359,7 +363,7 @@ memory layout in which channels are stored in the image.
* @param region the copied region, see class description for the format
* @return the event object indicating the status of the operation
*/
- Event copyToAsync(CommandQueue queue, Image dest, long[] srcOrigin, long[] destOrigin, long[] region);
+ public abstract Event copyToAsync(CommandQueue queue, Image dest, long[] srcOrigin, long[] destOrigin, long[] region);
/**
* Maps the image into host memory.
@@ -373,7 +377,7 @@ memory layout in which channels are stored in the image.
* @return a structure describing the mapped memory
* @see #unmap(com.jme3.opencl.CommandQueue, com.jme3.opencl.Image.ImageMapping)
*/
- ImageMapping map(CommandQueue queue, long[] origin, long[] region, MappingAccess access);
+ public abstract ImageMapping map(CommandQueue queue, long[] origin, long[] region, MappingAccess access);
/**
* Non-blocking version of {@link #map(com.jme3.opencl.CommandQueue, long[], long[], com.jme3.opencl.MappingAccess) }.
* The returned structure contains the mapped byte buffer and row and slice pitch.
@@ -385,13 +389,13 @@ memory layout in which channels are stored in the image.
* @return a structure describing the mapped memory
* @see #unmap(com.jme3.opencl.CommandQueue, com.jme3.opencl.Image.ImageMapping)
*/
- ImageMapping mapAsync(CommandQueue queue, long[] origin, long[] region, MappingAccess access);
+ public abstract ImageMapping mapAsync(CommandQueue queue, long[] origin, long[] region, MappingAccess access);
/**
* Unmaps the mapped memory
* @param queue the command queue
* @param mapping the mapped memory
*/
- void unmap(CommandQueue queue, ImageMapping mapping);
+ public abstract void unmap(CommandQueue queue, ImageMapping mapping);
/**
* Describes a mapped region of the image
@@ -442,7 +446,7 @@ memory layout in which channels are stored in the image.
* @param color the color to fill
* @return an event object to detect for the completion
*/
- Event fillAsync(CommandQueue queue, long[] origin, long[] region, ColorRGBA color);
+ public abstract Event fillAsync(CommandQueue queue, long[] origin, long[] region, ColorRGBA color);
/**
* Fills the image with the specified color given as four integer variables.
* Does not work if the image channel is {@link ImageChannelType#FLOAT}
@@ -453,7 +457,7 @@ memory layout in which channels are stored in the image.
* @param color the color to fill, must be an array of length 4
* @return an event object to detect for the completion
*/
- Event fillAsync(CommandQueue queue, long[] origin, long[] region, int[] color);
+ public abstract Event fillAsync(CommandQueue queue, long[] origin, long[] region, int[] color);
/**
* Copies this image into the specified buffer, no format conversion is done.
@@ -466,7 +470,7 @@ memory layout in which channels are stored in the image.
* @param destOffset an offset into the target buffer
* @return the event object to detect the completion of the operation
*/
- Event copyToBufferAsync(CommandQueue queue, Buffer dest, long[] srcOrigin, long[] srcRegion, long destOffset);
+ public abstract Event copyToBufferAsync(CommandQueue queue, Buffer dest, long[] srcOrigin, long[] srcRegion, long destOffset);
/**
* Aquires this image object for using. Only call this method if this image
@@ -480,7 +484,7 @@ memory layout in which channels are stored in the image.
* @param queue the command queue
* @return the event object
*/
- Event acquireImageForSharingAsync(CommandQueue queue);
+ public abstract Event acquireImageForSharingAsync(CommandQueue queue);
/**
* Releases a shared image object.
* Call this method after the image object was acquired by
@@ -489,7 +493,7 @@ memory layout in which channels are stored in the image.
* @param queue the command queue
* @return the event object
*/
- Event releaseImageForSharingAsync(CommandQueue queue);
+ public abstract Event releaseImageForSharingAsync(CommandQueue queue);
//TODO: add variants of the above two methods that don't create the event object, but release the event immediately
}
diff --git a/jme3-core/src/main/java/com/jme3/opencl/Kernel.java b/jme3-core/src/main/java/com/jme3/opencl/Kernel.java
index c7482a937..82fbf9018 100644
--- a/jme3-core/src/main/java/com/jme3/opencl/Kernel.java
+++ b/jme3-core/src/main/java/com/jme3/opencl/Kernel.java
@@ -82,7 +82,7 @@ import java.util.Arrays;
* @author shaman
* @see Program#createKernel(java.lang.String)
*/
-public abstract class Kernel implements OpenCLObject {
+public abstract class Kernel extends AbstractOpenCLObject {
/**
* The current global work size
*/
@@ -92,7 +92,8 @@ public abstract class Kernel implements OpenCLObject {
*/
protected final WorkSize workGroupSize;
- protected Kernel() {
+ protected Kernel(ObjectReleaser releaser) {
+ super(releaser);
this.globalWorkSize = new WorkSize(0);
this.workGroupSize = new WorkSize(0);
}
diff --git a/jme3-core/src/main/java/com/jme3/opencl/OpenCLObject.java b/jme3-core/src/main/java/com/jme3/opencl/OpenCLObject.java
index 6ee0bc121..f9d631346 100644
--- a/jme3-core/src/main/java/com/jme3/opencl/OpenCLObject.java
+++ b/jme3-core/src/main/java/com/jme3/opencl/OpenCLObject.java
@@ -32,14 +32,44 @@
package com.jme3.opencl;
/**
- *
+ * Base interface of all native OpenCL objects.
+ * This interface provides the functionality for savely release the object.
* @author shaman
*/
public interface OpenCLObject {
+ /**
+ * Releaser for an {@link OpenCLObject}.
+ * Implementations of this interface must not hold a reference to the
+ * {@code OpenCLObject} directly.
+ */
public static interface ObjectReleaser {
+ /**
+ * Releases the native resources of the associated {@link OpenCLObject}.
+ * This method must be guarded against multiple calls: only the first
+ * call should release, the next ones must not throw an exception.
+ */
void release();
}
+ /**
+ * Returns the releaser object. Multiple calls should return the same object.
+ * The ObjectReleaser is used to release the OpenCLObject when it is garbage
+ * collected. Therefore, the returned object must not hold a reference to
+ * the OpenCLObject.
+ * @return the object releaser
+ */
ObjectReleaser getReleaser();
-
+ /**
+ * Releases this native object.
+ * Should delegate to {@code getReleaser().release()}.
+ */
+ void release();
+ /**
+ * Registers this object for automatic releasing on garbage collection.
+ * By default, OpenCLObjects are not registered in the
+ * {@link OpenCLObjectManager}, you have to release it manually
+ * by calling {@link #release() }.
+ * Without registering or releasing, a memory leak might occur.
+ */
+ void register();
}
diff --git a/jme3-core/src/main/java/com/jme3/opencl/OpenCLObjectManager.java b/jme3-core/src/main/java/com/jme3/opencl/OpenCLObjectManager.java
index 7895781d3..1d29a829f 100644
--- a/jme3-core/src/main/java/com/jme3/opencl/OpenCLObjectManager.java
+++ b/jme3-core/src/main/java/com/jme3/opencl/OpenCLObjectManager.java
@@ -43,8 +43,8 @@ import java.util.logging.Logger;
*/
public class OpenCLObjectManager {
private static final Logger LOG = Logger.getLogger(OpenCLObjectManager.class.getName());
- private static final Level LOG_LEVEL1 = Level.FINER;
- private static final Level LOG_LEVEL2 = Level.FINE;
+ private static final Level LOG_LEVEL1 = Level.INFO;
+ private static final Level LOG_LEVEL2 = Level.INFO;
/**
* Call Runtime.getRuntime().gc() every these frames
*/
@@ -85,6 +85,7 @@ public class OpenCLObjectManager {
public void deleteUnusedObjects() {
if (activeObjects.isEmpty()) {
+ LOG.log(LOG_LEVEL2, "no active natives");
return; //nothing to do
}
@@ -108,7 +109,7 @@ public class OpenCLObjectManager {
removed++;
}
if (removed >= 1) {
- LOG.log(LOG_LEVEL2, "NativeObjectManager: {0} native objects were removed from native", removed);
+ LOG.log(LOG_LEVEL2, "{0} native objects were removed from native", removed);
}
}
diff --git a/jme3-core/src/main/java/com/jme3/opencl/Program.java b/jme3-core/src/main/java/com/jme3/opencl/Program.java
index 8774b7c45..3cfe7bf05 100644
--- a/jme3-core/src/main/java/com/jme3/opencl/Program.java
+++ b/jme3-core/src/main/java/com/jme3/opencl/Program.java
@@ -42,8 +42,12 @@ package com.jme3.opencl;
* @see #createKernel(java.lang.String)
* @author shaman
*/
-public interface Program extends OpenCLObject {
-
+public abstract class Program extends AbstractOpenCLObject {
+
+ protected Program(ObjectReleaser releaser) {
+ super(releaser);
+ }
+
/**
* Builds this program with the specified argument string.
* Please see the official OpenCL specification for a definition of
@@ -52,13 +56,15 @@ public interface Program extends OpenCLObject {
* @throws KernelCompilationException if the compilation fails
* @see #build()
*/
- void build(String args) throws KernelCompilationException;
+ public abstract void build(String args) throws KernelCompilationException;
/**
* Builds this program without additional arguments
* @throws KernelCompilationException if the compilation fails
* @see #build(java.lang.String)
*/
- void build() throws KernelCompilationException;
+ public void build() throws KernelCompilationException {
+ build("");
+ }
/**
* Creates the kernel with the specified name.
@@ -67,13 +73,13 @@ public interface Program extends OpenCLObject {
* @throws OpenCLException if the kernel was not found or some other
* error occured
*/
- Kernel createKernel(String name);
+ public abstract Kernel createKernel(String name);
/**
* Creates all available kernels in this program.
* The names of the kernels can then by queried by {@link Kernel#getName() }.
* @return an array of all kernels
*/
- Kernel[] createAllKernels();
+ public abstract Kernel[] createAllKernels();
}
diff --git a/jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java b/jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java
index 4100fd92b..e08802785 100644
--- a/jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java
+++ b/jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java
@@ -85,6 +85,8 @@ public class HelloOpenCL extends SimpleApplication {
str.append("\n Kernel: ").append(testKernel(clContext, clQueue));
str.append("\n Images: ").append(testImages(clContext, clQueue));
+ clQueue.release();
+
BitmapText txt1 = new BitmapText(fnt);
txt1.setText(str.toString());
txt1.setLocalTranslation(5, settings.getHeight() - 5, 0);
@@ -159,6 +161,10 @@ public class HelloOpenCL extends SimpleApplication {
assertEquals((byte) (i+low), b, "Wrong byte read");
}
+ //release
+ b1.release();
+ b2.release();
+
} catch (AssertionError ex) {
LOG.log(Level.SEVERE, "Buffer test failed with an assertion error");
return false;
@@ -193,6 +199,11 @@ public class HelloOpenCL extends SimpleApplication {
assertEquals(value, v, "Buffer filled with the wrong value at index "+i);
}
buffer.unmap(clQueue, buf);
+
+ //release
+ buffer.release();
+ kernel.release();
+ program.release();
} catch (AssertionError ex) {
LOG.log(Level.SEVERE, "kernel test failed with an assertion error");
@@ -239,7 +250,8 @@ public class HelloOpenCL extends SimpleApplication {
//copy to a buffer
Buffer buffer = clContext.createBuffer(4*4*500*1024);
- image.copyToBufferAsync(clQueue, buffer, new long[]{10,10,0}, new long[]{500,1024,1}, 0);
+ Event e3 = image.copyToBufferAsync(clQueue, buffer, new long[]{10,10,0}, new long[]{500,1024,1}, 0);
+ e3.release();
//this buffer must be completely red
ByteBuffer map1 = buffer.map(clQueue, MappingAccess.MAP_READ_ONLY);
FloatBuffer map1F = map1.asFloatBuffer(); map1F.rewind();
@@ -282,6 +294,11 @@ public class HelloOpenCL extends SimpleApplication {
}
image2.unmap(clQueue, map2);
+ //release
+ image.release();
+ image2.release();
+ buffer.release();
+
} catch (AssertionError ex) {
LOG.log(Level.SEVERE, "image test failed with an assertion error");
return false;
diff --git a/jme3-examples/src/main/java/jme3test/opencl/TestVertexBufferSharing.java b/jme3-examples/src/main/java/jme3test/opencl/TestVertexBufferSharing.java
index 06e2684dc..0d2257817 100644
--- a/jme3-examples/src/main/java/jme3test/opencl/TestVertexBufferSharing.java
+++ b/jme3-examples/src/main/java/jme3test/opencl/TestVertexBufferSharing.java
@@ -107,6 +107,7 @@ public class TestVertexBufferSharing extends SimpleApplication {
private void initOpenCL1() {
clContext = context.getOpenCLContext();
clQueue = clContext.createQueue();
+ clQueue.register();
//create kernel
String source = ""
+ "__kernel void ScaleKernel(__global float* vb, float scale)\n"
@@ -118,12 +119,15 @@ public class TestVertexBufferSharing extends SimpleApplication {
+ "}\n";
Program program = clContext.createProgramFromSourceCode(source);
program.build();
+ program.register();
kernel = program.createKernel("ScaleKernel");
+ kernel.register();
}
private void initOpenCL2() {
//bind vertex buffer to OpenCL
VertexBuffer vb = geom.getMesh().getBuffer(VertexBuffer.Type.Position);
buffer = clContext.bindVertexBuffer(vb, MemoryAccess.READ_WRITE);
+ buffer.register();
ws = new com.jme3.opencl.Kernel.WorkSize(geom.getMesh().getVertexCount());
}
private void updateOpenCL(float tpf) {
@@ -131,15 +135,15 @@ public class TestVertexBufferSharing extends SimpleApplication {
time += tpf;
//aquire resource
- buffer.acquireBufferForSharingAsync(clQueue);
+ buffer.acquireBufferForSharingAsync(clQueue).release();
//no need to wait for the returned event, since the kernel implicitely waits for it (same command queue)
//execute kernel
float scale = (float) Math.pow(1.1, (1.0 - time%2) / 16.0);
- kernel.Run1(clQueue, ws, buffer, scale);
+ kernel.Run1(clQueue, ws, buffer, scale).release();
//release resource
- buffer.releaseBufferForSharingAsync(clQueue);
+ buffer.releaseBufferForSharingAsync(clQueue).release();
}
}
\ No newline at end of file
diff --git a/jme3-examples/src/main/java/jme3test/opencl/TestWriteToTexture.java b/jme3-examples/src/main/java/jme3test/opencl/TestWriteToTexture.java
index 5230fb69d..c1f3e612f 100644
--- a/jme3-examples/src/main/java/jme3test/opencl/TestWriteToTexture.java
+++ b/jme3-examples/src/main/java/jme3test/opencl/TestWriteToTexture.java
@@ -120,26 +120,31 @@ public class TestWriteToTexture extends SimpleApplication implements AnalogListe
private void initOpenCL1() {
clContext = context.getOpenCLContext();
clQueue = clContext.createQueue();
+ clQueue.register();
//create kernel
Program program = clContext.createProgramFromSourceFiles(assetManager, "jme3test/opencl/JuliaSet.cl");
program.build();
+ program.register();
kernel = program.createKernel("JuliaSet");
+ kernel.register();
C = new Vector2f(0.12f, -0.2f);
}
private void initOpenCL2() {
//bind image to OpenCL
texCL = clContext.bindImage(tex, MemoryAccess.WRITE_ONLY);
+ texCL.register();
}
private void updateOpenCL(float tpf) {
//aquire resource
- texCL.acquireImageForSharingAsync(clQueue);
+ texCL.acquireImageForSharingAsync(clQueue).release();
//no need to wait for the returned event, since the kernel implicitely waits for it (same command queue)
//execute kernel
- kernel.Run1(clQueue, new com.jme3.opencl.Kernel.WorkSize(settings.getWidth(), settings.getHeight()), texCL, C, 16);
+ kernel.Run1(clQueue, new com.jme3.opencl.Kernel.WorkSize(settings.getWidth(), settings.getHeight()), texCL, C, 16)
+ .release();
//release resource
- texCL.releaseImageForSharingAsync(clQueue);
+ texCL.releaseImageForSharingAsync(clQueue).release();
}
@Override
diff --git a/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclBuffer.java b/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclBuffer.java
index 773b581b1..06d417827 100644
--- a/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclBuffer.java
+++ b/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclBuffer.java
@@ -48,9 +48,9 @@ public class JoclBuffer extends Buffer {
final CL cl;
public JoclBuffer(long id) {
+ super(new ReleaserImpl(id));
this.id = id;
this.cl = CLPlatform.getLowLevelCLInterface();
- OpenCLObjectManager.getInstance().registerObject(this);
}
@Override
@@ -203,10 +203,6 @@ public class JoclBuffer extends Buffer {
return new JoclEvent(event);
}
- @Override
- public ObjectReleaser getReleaser() {
- return new ReleaserImpl(id);
- }
private static class ReleaserImpl implements ObjectReleaser {
private long mem;
private ReleaserImpl(long mem) {
diff --git a/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclCommandQueue.java b/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclCommandQueue.java
index 790bc152b..e7b8a3743 100644
--- a/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclCommandQueue.java
+++ b/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclCommandQueue.java
@@ -42,15 +42,15 @@ import com.jogamp.opencl.llb.CLCommandQueueBinding;
*
* @author shaman
*/
-public class JoclCommandQueue implements CommandQueue {
+public class JoclCommandQueue extends CommandQueue {
final CL cl;
final long id;
public JoclCommandQueue(long id) {
+ super(new ReleaserImpl(id));
this.id = id;
this.cl = CLPlatform.getLowLevelCLInterface();
- OpenCLObjectManager.getInstance().registerObject(this);
}
@Override
@@ -65,23 +65,17 @@ public class JoclCommandQueue implements CommandQueue {
Utils.checkError(ret, "clFinish");
}
- @Override
- public ObjectReleaser getReleaser() {
- return new ReleaserImpl(id, cl);
- }
private static class ReleaserImpl implements ObjectReleaser {
private long id;
- private CLCommandQueueBinding cl;
- private ReleaserImpl(long id, CLCommandQueueBinding cl) {
+ private ReleaserImpl(long id) {
this.id = id;
- this.cl = cl;
}
@Override
public void release() {
if (id != 0) {
- int ret = cl.clReleaseCommandQueue(id);
+ int ret = CLPlatform.getLowLevelCLInterface().clReleaseCommandQueue(id);
id = 0;
Utils.reportError(ret, "clReleaseCommandQueue");
}
diff --git a/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclContext.java b/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclContext.java
index 4e9b6e920..eca2db012 100644
--- a/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclContext.java
+++ b/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclContext.java
@@ -40,7 +40,6 @@ import com.jme3.texture.FrameBuffer;
import com.jme3.texture.Texture;
import com.jogamp.opencl.CLContext;
import com.jogamp.opencl.CLImageFormat;
-import com.jogamp.opencl.CLMemory;
import com.jogamp.opencl.CLMemory.Mem;
import com.jogamp.opencl.CLPlatform;
import com.jogamp.opencl.llb.CL;
@@ -48,7 +47,6 @@ import com.jogamp.opencl.llb.gl.CLGL;
import com.jogamp.opencl.llb.impl.CLImageFormatImpl;
import com.jogamp.opengl.GL;
import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -66,11 +64,11 @@ public class JoclContext extends Context {
private final List devices;
public JoclContext(CLContext context, List devices) {
+ super(new ReleaserImpl(context.ID, devices));
this.context = context;
this.id = context.ID;
this.cl = context.getCL();
this.devices = devices;
- OpenCLObjectManager.getInstance().registerObject(this);
}
public CLContext getContext() {
@@ -224,10 +222,6 @@ public class JoclContext extends Context {
return new JoclProgram(p, this);
}
- @Override
- public ObjectReleaser getReleaser() {
- return new ReleaserImpl(id, devices);
- }
private static class ReleaserImpl implements ObjectReleaser {
private long id;
private final List devices;
diff --git a/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclEvent.java b/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclEvent.java
index cb6fa9235..c79504dfa 100644
--- a/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclEvent.java
+++ b/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclEvent.java
@@ -41,16 +41,16 @@ import java.util.logging.Logger;
*
* @author shaman
*/
-public class JoclEvent implements Event {
+public class JoclEvent extends Event {
private static final Logger LOG = Logger.getLogger(JoclEvent.class.getName());
final long id;
final CL cl;
public JoclEvent(long id) {
+ super(new ReleaserImpl(id));
this.id = id;
this.cl = CLPlatform.getLowLevelCLInterface();
- OpenCLObjectManager.getInstance().registerObject(this);
}
@Override
@@ -59,6 +59,7 @@ public class JoclEvent implements Event {
Utils.pointers[0].put(0, id);
int ret = cl.clWaitForEvents(1, Utils.pointers[0]);
Utils.checkError(ret, "clWaitForEvents");
+ release();
}
@Override
@@ -68,6 +69,7 @@ public class JoclEvent implements Event {
Utils.checkError(err, "clGetEventInfo");
int status = Utils.tempBuffers[0].b16i.get(0);
if (status == CL.CL_SUCCESS) {
+ release();
return true;
} else if (status < 0) {
Utils.checkError(status, "EventStatus");
@@ -76,11 +78,6 @@ public class JoclEvent implements Event {
return false;
}
}
-
- @Override
- public ObjectReleaser getReleaser() {
- return new ReleaserImpl(id);
- }
private static class ReleaserImpl implements ObjectReleaser {
private long event;
diff --git a/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclImage.java b/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclImage.java
index aa6ce5ae7..0041147f9 100644
--- a/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclImage.java
+++ b/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclImage.java
@@ -44,16 +44,16 @@ import java.util.logging.Logger;
*
* @author shaman
*/
-public class JoclImage implements Image {
+public class JoclImage extends Image {
private static final Logger LOG = Logger.getLogger(JoclImage.class.getName());
final long id;
final CL cl;
public JoclImage(long image) {
+ super(new ReleaserImpl(image));
this.id = image;
this.cl = CLPlatform.getLowLevelCLInterface();
- OpenCLObjectManager.getInstance().registerObject(this);
}
public static int decodeImageChannelOrder(ImageChannelOrder order) {
@@ -512,10 +512,6 @@ public class JoclImage implements Image {
return new JoclEvent(event);
}
- @Override
- public ObjectReleaser getReleaser() {
- return new ReleaserImpl(id);
- }
private static class ReleaserImpl implements ObjectReleaser {
private long mem;
private ReleaserImpl(long mem) {
diff --git a/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclKernel.java b/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclKernel.java
index b7d99c5bc..43bac1a30 100644
--- a/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclKernel.java
+++ b/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclKernel.java
@@ -37,7 +37,6 @@ import com.jme3.math.Vector4f;
import com.jme3.opencl.*;
import com.jme3.opencl.Buffer;
import com.jogamp.common.nio.PointerBuffer;
-import com.jogamp.opencl.CLKernel;
import com.jogamp.opencl.CLPlatform;
import com.jogamp.opencl.llb.CL;
import java.nio.*;
@@ -55,6 +54,7 @@ public class JoclKernel extends Kernel {
final CL cl;
public JoclKernel(long kernel) {
+ super(new ReleaserImpl(kernel));
this.kernel = kernel;
this.cl = CLPlatform.getLowLevelCLInterface();
OpenCLObjectManager.getInstance().registerObject(this);
@@ -240,10 +240,6 @@ public class JoclKernel extends Kernel {
return new JoclEvent(Utils.pointers[0].get(0));
}
- @Override
- public ObjectReleaser getReleaser() {
- return new ReleaserImpl(kernel);
- }
private static class ReleaserImpl implements ObjectReleaser {
private long kernel;
private ReleaserImpl(long kernel) {
diff --git a/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclProgram.java b/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclProgram.java
index dcc32014a..1714446cf 100644
--- a/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclProgram.java
+++ b/jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclProgram.java
@@ -50,7 +50,7 @@ import static com.jogamp.opencl.llb.CL.CL_SUCCESS;
*
* @author shaman
*/
-public class JoclProgram implements Program {
+public class JoclProgram extends Program {
private static final Logger LOG = Logger.getLogger(JoclProgram.class.getName());
final long program;
@@ -58,10 +58,10 @@ public class JoclProgram implements Program {
private final JoclContext context;
public JoclProgram(long program, JoclContext context) {
+ super(new ReleaserImpl(program));
this.program = program;
this.context = context;
this.cl = CLPlatform.getLowLevelCLInterface();
- OpenCLObjectManager.getInstance().registerObject(this);
}
@Override
@@ -79,11 +79,6 @@ public class JoclProgram implements Program {
LOG.log(Level.INFO, "Program compiled:\n{0}", Log());
}
}
-
- @Override
- public void build() throws KernelCompilationException {
- build("");
- }
private String Log(long device) {
Utils.pointers[0].rewind();
@@ -131,10 +126,6 @@ public class JoclProgram implements Program {
return kx;
}
- @Override
- public ObjectReleaser getReleaser() {
- return new ReleaserImpl(program);
- }
private static class ReleaserImpl implements ObjectReleaser {
private long program;
private ReleaserImpl(long program) {
diff --git a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java
index 60277427a..9a90c6eb1 100644
--- a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java
+++ b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java
@@ -44,8 +44,8 @@ public class LwjglBuffer extends Buffer {
private final CLMem buffer;
public LwjglBuffer(CLMem buffer) {
+ super(new ReleaserImpl(buffer));
this.buffer = buffer;
- OpenCLObjectManager.getInstance().registerObject(this);
}
public CLMem getBuffer() {
return buffer;
@@ -205,10 +205,6 @@ public class LwjglBuffer extends Buffer {
return new LwjglEvent(q.getCLEvent(event));
}
- @Override
- public ObjectReleaser getReleaser() {
- return new ReleaserImpl(buffer);
- }
private static class ReleaserImpl implements ObjectReleaser {
private CLMem mem;
private ReleaserImpl(CLMem mem) {
diff --git a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglCommandQueue.java b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglCommandQueue.java
index a0fd04ddc..c413d6a8e 100644
--- a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglCommandQueue.java
+++ b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglCommandQueue.java
@@ -40,13 +40,13 @@ import org.lwjgl.opencl.CLCommandQueue;
*
* @author shaman
*/
-public class LwjglCommandQueue implements CommandQueue {
+public class LwjglCommandQueue extends CommandQueue {
private final CLCommandQueue queue;
public LwjglCommandQueue(CLCommandQueue queue) {
+ super(new ReleaserImpl(queue));
this.queue = queue;
- OpenCLObjectManager.getInstance().registerObject(this);
}
public CLCommandQueue getQueue() {
@@ -65,10 +65,6 @@ public class LwjglCommandQueue implements CommandQueue {
Utils.checkError(ret, "clFinish");
}
- @Override
- public ObjectReleaser getReleaser() {
- return new ReleaserImpl(queue);
- }
private static class ReleaserImpl implements ObjectReleaser {
private CLCommandQueue queue;
private ReleaserImpl(CLCommandQueue queue) {
diff --git a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglContext.java b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglContext.java
index ad3450f8f..af5463f33 100644
--- a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglContext.java
+++ b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglContext.java
@@ -57,9 +57,9 @@ public class LwjglContext extends Context {
private final List devices;
public LwjglContext(CLContext context, List devices) {
+ super(new ReleaserImpl(context, devices));
this.context = context;
this.devices = devices;
- OpenCLObjectManager.getInstance().registerObject(this);
}
public CLContext getContext() {
@@ -208,10 +208,6 @@ public class LwjglContext extends Context {
return new LwjglProgram(p, this);
}
- @Override
- public ObjectReleaser getReleaser() {
- return new ReleaserImpl(context, devices);
- }
private static class ReleaserImpl implements ObjectReleaser {
private CLContext context;
private final List devices;
diff --git a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglEvent.java b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglEvent.java
index 5055ac7af..1078c8c17 100644
--- a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglEvent.java
+++ b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglEvent.java
@@ -41,31 +41,24 @@ import org.lwjgl.opencl.CLEvent;
*
* @author shaman
*/
-public class LwjglEvent implements Event {
+public class LwjglEvent extends Event {
private static final Logger LOG = Logger.getLogger(LwjglEvent.class.getName());
private CLEvent event;
+ private ReleaserImpl releaser;
public LwjglEvent(CLEvent event) {
+ super(new ReleaserImpl(event));
this.event = event;
if (event == null) {
LOG.warning("event is null!");
} else {
- OpenCLObjectManager.getInstance().registerObject(this);
+ this.releaser = new ReleaserImpl(event);
}
}
public CLEvent getEvent() {
return event;
}
-
- protected void release() {
- if (event != null && event.isValid()) {
- int ret = CL10.clReleaseEvent(event);
- event = null;
- Utils.reportError(ret, "clReleaseEvent");
- LOG.finer("Event deleted");
- }
- }
@Override
public void waitForFinished() {
@@ -93,11 +86,6 @@ public class LwjglEvent implements Event {
}
}
- @Override
- public ObjectReleaser getReleaser() {
- return new ReleaserImpl(event);
- }
-
private static class ReleaserImpl implements ObjectReleaser {
private CLEvent event;
diff --git a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java
index 1ed59641b..46b8b0ff7 100644
--- a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java
+++ b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java
@@ -43,14 +43,14 @@ import org.lwjgl.opencl.api.CLImageFormat;
*
* @author shaman
*/
-public class LwjglImage implements Image {
+public class LwjglImage extends Image {
private static final Logger LOG = Logger.getLogger(LwjglImage.class.getName());
private final CLMem image;
public LwjglImage(CLMem image) {
+ super(new ReleaserImpl(image));
this.image = image;
- OpenCLObjectManager.getInstance().registerObject(this);
}
public CLMem getImage() {
@@ -543,10 +543,6 @@ public class LwjglImage implements Image {
return new LwjglEvent(q.getCLEvent(event));
}
- @Override
- public ObjectReleaser getReleaser() {
- return new ReleaserImpl(image);
- }
private static class ReleaserImpl implements ObjectReleaser {
private CLMem mem;
private ReleaserImpl(CLMem mem) {
diff --git a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglKernel.java b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglKernel.java
index 21f165df6..1897e2501 100644
--- a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglKernel.java
+++ b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglKernel.java
@@ -52,8 +52,8 @@ public class LwjglKernel extends Kernel {
private final CLKernel kernel;
public LwjglKernel(CLKernel kernel) {
+ super(new ReleaserImpl(kernel));
this.kernel = kernel;
- OpenCLObjectManager.getInstance().registerObject(this);
}
public CLKernel getKernel() {
diff --git a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglProgram.java b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglProgram.java
index a926c3d14..641951235 100644
--- a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglProgram.java
+++ b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglProgram.java
@@ -44,16 +44,16 @@ import org.lwjgl.opencl.*;
*
* @author shaman
*/
-public class LwjglProgram implements Program {
+public class LwjglProgram extends Program {
private static final Logger LOG = Logger.getLogger(LwjglProgram.class.getName());
private final CLProgram program;
private final LwjglContext context;
public LwjglProgram(CLProgram program, LwjglContext context) {
+ super(new ReleaserImpl(program));
this.program = program;
this.context = context;
- OpenCLObjectManager.getInstance().registerObject(this);
}
public CLProgram getProgram() {
@@ -75,11 +75,6 @@ public class LwjglProgram implements Program {
LOG.log(Level.INFO, "Program compiled:\n{0}", Log());
}
}
-
- @Override
- public void build() throws KernelCompilationException {
- build("");
- }
private String Log() {
StringBuilder str = new StringBuilder();
@@ -109,10 +104,6 @@ public class LwjglProgram implements Program {
return kx;
}
- @Override
- public ObjectReleaser getReleaser() {
- return new ReleaserImpl(program);
- }
private static class ReleaserImpl implements ObjectReleaser {
private CLProgram program;
private ReleaserImpl(CLProgram program) {