reworked releasing system.

Now one has to either release a native OpenCLObject manually with release() or register it for automatic garbage collection using register().
These changes greatly improve the performance by reducing the load on the OpenCLObjectManager.
define_list_fix
shamanDevel 9 years ago
parent a26e526945
commit 4be6013068
  1. 62
      jme3-core/src/main/java/com/jme3/opencl/AbstractOpenCLObject.java
  2. 6
      jme3-core/src/main/java/com/jme3/opencl/Buffer.java
  3. 10
      jme3-core/src/main/java/com/jme3/opencl/CommandQueue.java
  4. 6
      jme3-core/src/main/java/com/jme3/opencl/Context.java
  5. 16
      jme3-core/src/main/java/com/jme3/opencl/Event.java
  6. 52
      jme3-core/src/main/java/com/jme3/opencl/Image.java
  7. 5
      jme3-core/src/main/java/com/jme3/opencl/Kernel.java
  8. 34
      jme3-core/src/main/java/com/jme3/opencl/OpenCLObject.java
  9. 7
      jme3-core/src/main/java/com/jme3/opencl/OpenCLObjectManager.java
  10. 18
      jme3-core/src/main/java/com/jme3/opencl/Program.java
  11. 19
      jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java
  12. 10
      jme3-examples/src/main/java/jme3test/opencl/TestVertexBufferSharing.java
  13. 11
      jme3-examples/src/main/java/jme3test/opencl/TestWriteToTexture.java
  14. 6
      jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclBuffer.java
  15. 14
      jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclCommandQueue.java
  16. 8
      jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclContext.java
  17. 11
      jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclEvent.java
  18. 8
      jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclImage.java
  19. 6
      jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclKernel.java
  20. 13
      jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclProgram.java
  21. 6
      jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java
  22. 8
      jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglCommandQueue.java
  23. 6
      jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglContext.java
  24. 20
      jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglEvent.java
  25. 8
      jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java
  26. 2
      jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglKernel.java
  27. 13
      jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglProgram.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;
}
}

@ -47,8 +47,12 @@ import java.nio.ByteBuffer;
* @see Context#createBuffer(long, com.jme3.opencl.MemoryAccess) * @see Context#createBuffer(long, com.jme3.opencl.MemoryAccess)
* @author shaman * @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. * @return the size of the buffer in bytes.
* @see Context#createBuffer(long) * @see Context#createBuffer(long)

@ -42,8 +42,12 @@ package com.jme3.opencl;
* and all commands are sent to this device. * and all commands are sent to this device.
* @author shaman * @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 * Issues all previously queued OpenCL commands in command_queue to the
* device associated with command queue. Flush only guarantees that all * 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 * appropriate device. There is no guarantee that they will be complete
* after flush returns. * after flush returns.
*/ */
void flush(); public abstract void flush();
/** /**
* Blocks until all previously queued OpenCL commands in command queue are * 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 * return until all previously queued commands in command queue have been
* processed and completed. Finish is also a synchronization point. * processed and completed. Finish is also a synchronization point.
*/ */
void finish(); public abstract void finish();
} }

@ -63,9 +63,13 @@ import java.util.logging.Logger;
* </ul> * </ul>
* @author shaman * @author shaman
*/ */
public abstract class Context implements OpenCLObject { public abstract class Context extends AbstractOpenCLObject {
private static final Logger LOG = Logger.getLogger(Context.class.getName()); private static final Logger LOG = Logger.getLogger(Context.class.getName());
protected Context(ObjectReleaser releaser) {
super(releaser);
}
/** /**
* Returns all available devices for this context. * Returns all available devices for this context.
* These devices all belong to the same {@link Platform}. * These devices all belong to the same {@link Platform}.

@ -38,16 +38,22 @@ package com.jme3.opencl;
* is done. * is done.
* @author shaman * @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 * @return {@code true} if the action is completed
*/ */
boolean isCompleted(); public abstract boolean isCompleted();
} }

@ -74,7 +74,7 @@ import java.util.Objects;
* *
* @author shaman * @author shaman
*/ */
public interface Image extends OpenCLObject { public abstract class Image extends AbstractOpenCLObject {
/** /**
* {@code ImageChannelType} describes the size of the channel data type. * {@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 * @return the width of the image
*/ */
long getWidth(); public abstract long getWidth();
/** /**
* @return the height of the image * @return the height of the image
*/ */
long getHeight(); public abstract long getHeight();
/** /**
* @return the depth of the image * @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 * @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) * @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 * @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) * @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 * @return the number of elements in the image array
* @see ImageType#IMAGE_1D_ARRAY * @see ImageType#IMAGE_1D_ARRAY
* @see ImageType#IMAGE_2D_ARRAY * @see ImageType#IMAGE_2D_ARRAY
*/ */
long getArraySize(); public abstract long getArraySize();
/** /**
* @return the image format * @return the image format
*/ */
ImageFormat getImageFormat(); public abstract ImageFormat getImageFormat();
/** /**
* @return the image type * @return the image type
*/ */
ImageType getImageType(); public abstract ImageType getImageType();
/** /**
* @return the number of bytes per pixel * @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. * 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. * @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} * 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. * Performs an async/non-blocking read of the image into the specified byte buffer.
* @param queue the command queue * @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} * 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 * @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. * 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. * @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} * 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. * Performs an async/non-blocking write from the specified byte buffer into the image.
* @param queue the command queue * @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} * 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 * @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. * 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 destOrigin the target image origin, see class description for the format
* @param region the copied region, 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. * Performs an async/non-blocking copy operation from one image to another.
* <b>Important:</b> Both images must have the same format! * <b>Important:</b> 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 * @param region the copied region, see class description for the format
* @return the event object indicating the status of the operation * @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. * 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 * @return a structure describing the mapped memory
* @see #unmap(com.jme3.opencl.CommandQueue, com.jme3.opencl.Image.ImageMapping) * @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) }. * 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. * 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 * @return a structure describing the mapped memory
* @see #unmap(com.jme3.opencl.CommandQueue, com.jme3.opencl.Image.ImageMapping) * @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 * Unmaps the mapped memory
* @param queue the command queue * @param queue the command queue
* @param mapping the mapped memory * @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 * 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 * @param color the color to fill
* @return an event object to detect for the completion * @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. * Fills the image with the specified color given as four integer variables.
* Does <b>not</b> work if the image channel is {@link ImageChannelType#FLOAT} * Does <b>not</b> 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 * @param color the color to fill, must be an array of length 4
* @return an event object to detect for the completion * @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. * 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 * @param destOffset an offset into the target buffer
* @return the event object to detect the completion of the operation * @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 * 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 * @param queue the command queue
* @return the event object * @return the event object
*/ */
Event acquireImageForSharingAsync(CommandQueue queue); public abstract Event acquireImageForSharingAsync(CommandQueue queue);
/** /**
* Releases a shared image object. * Releases a shared image object.
* Call this method after the image object was acquired by * 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 * @param queue the command queue
* @return the event object * @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 //TODO: add variants of the above two methods that don't create the event object, but release the event immediately
} }

@ -82,7 +82,7 @@ import java.util.Arrays;
* @author shaman * @author shaman
* @see Program#createKernel(java.lang.String) * @see Program#createKernel(java.lang.String)
*/ */
public abstract class Kernel implements OpenCLObject { public abstract class Kernel extends AbstractOpenCLObject {
/** /**
* The current global work size * The current global work size
*/ */
@ -92,7 +92,8 @@ public abstract class Kernel implements OpenCLObject {
*/ */
protected final WorkSize workGroupSize; protected final WorkSize workGroupSize;
protected Kernel() { protected Kernel(ObjectReleaser releaser) {
super(releaser);
this.globalWorkSize = new WorkSize(0); this.globalWorkSize = new WorkSize(0);
this.workGroupSize = new WorkSize(0); this.workGroupSize = new WorkSize(0);
} }

@ -32,14 +32,44 @@
package com.jme3.opencl; package com.jme3.opencl;
/** /**
* * Base interface of all native OpenCL objects.
* This interface provides the functionality for savely release the object.
* @author shaman * @author shaman
*/ */
public interface OpenCLObject { 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 { 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(); 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(); 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();
} }

@ -43,8 +43,8 @@ import java.util.logging.Logger;
*/ */
public class OpenCLObjectManager { public class OpenCLObjectManager {
private static final Logger LOG = Logger.getLogger(OpenCLObjectManager.class.getName()); private static final Logger LOG = Logger.getLogger(OpenCLObjectManager.class.getName());
private static final Level LOG_LEVEL1 = Level.FINER; private static final Level LOG_LEVEL1 = Level.INFO;
private static final Level LOG_LEVEL2 = Level.FINE; private static final Level LOG_LEVEL2 = Level.INFO;
/** /**
* Call Runtime.getRuntime().gc() every these frames * Call Runtime.getRuntime().gc() every these frames
*/ */
@ -85,6 +85,7 @@ public class OpenCLObjectManager {
public void deleteUnusedObjects() { public void deleteUnusedObjects() {
if (activeObjects.isEmpty()) { if (activeObjects.isEmpty()) {
LOG.log(LOG_LEVEL2, "no active natives");
return; //nothing to do return; //nothing to do
} }
@ -108,7 +109,7 @@ public class OpenCLObjectManager {
removed++; removed++;
} }
if (removed >= 1) { 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);
} }
} }

@ -42,8 +42,12 @@ package com.jme3.opencl;
* @see #createKernel(java.lang.String) * @see #createKernel(java.lang.String)
* @author shaman * @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. * Builds this program with the specified argument string.
* Please see the official OpenCL specification for a definition of * 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 * @throws KernelCompilationException if the compilation fails
* @see #build() * @see #build()
*/ */
void build(String args) throws KernelCompilationException; public abstract void build(String args) throws KernelCompilationException;
/** /**
* Builds this program without additional arguments * Builds this program without additional arguments
* @throws KernelCompilationException if the compilation fails * @throws KernelCompilationException if the compilation fails
* @see #build(java.lang.String) * @see #build(java.lang.String)
*/ */
void build() throws KernelCompilationException; public void build() throws KernelCompilationException {
build("");
}
/** /**
* Creates the kernel with the specified name. * 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 * @throws OpenCLException if the kernel was not found or some other
* error occured * error occured
*/ */
Kernel createKernel(String name); public abstract Kernel createKernel(String name);
/** /**
* Creates all available kernels in this program. * Creates all available kernels in this program.
* The names of the kernels can then by queried by {@link Kernel#getName() }. * The names of the kernels can then by queried by {@link Kernel#getName() }.
* @return an array of all kernels * @return an array of all kernels
*/ */
Kernel[] createAllKernels(); public abstract Kernel[] createAllKernels();
} }

@ -85,6 +85,8 @@ public class HelloOpenCL extends SimpleApplication {
str.append("\n Kernel: ").append(testKernel(clContext, clQueue)); str.append("\n Kernel: ").append(testKernel(clContext, clQueue));
str.append("\n Images: ").append(testImages(clContext, clQueue)); str.append("\n Images: ").append(testImages(clContext, clQueue));
clQueue.release();
BitmapText txt1 = new BitmapText(fnt); BitmapText txt1 = new BitmapText(fnt);
txt1.setText(str.toString()); txt1.setText(str.toString());
txt1.setLocalTranslation(5, settings.getHeight() - 5, 0); txt1.setLocalTranslation(5, settings.getHeight() - 5, 0);
@ -159,6 +161,10 @@ public class HelloOpenCL extends SimpleApplication {
assertEquals((byte) (i+low), b, "Wrong byte read"); assertEquals((byte) (i+low), b, "Wrong byte read");
} }
//release
b1.release();
b2.release();
} catch (AssertionError ex) { } catch (AssertionError ex) {
LOG.log(Level.SEVERE, "Buffer test failed with an assertion error"); LOG.log(Level.SEVERE, "Buffer test failed with an assertion error");
return false; return false;
@ -193,6 +199,11 @@ public class HelloOpenCL extends SimpleApplication {
assertEquals(value, v, "Buffer filled with the wrong value at index "+i); assertEquals(value, v, "Buffer filled with the wrong value at index "+i);
} }
buffer.unmap(clQueue, buf); buffer.unmap(clQueue, buf);
//release
buffer.release();
kernel.release();
program.release();
} catch (AssertionError ex) { } catch (AssertionError ex) {
LOG.log(Level.SEVERE, "kernel test failed with an assertion error"); LOG.log(Level.SEVERE, "kernel test failed with an assertion error");
@ -239,7 +250,8 @@ public class HelloOpenCL extends SimpleApplication {
//copy to a buffer //copy to a buffer
Buffer buffer = clContext.createBuffer(4*4*500*1024); 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 //this buffer must be completely red
ByteBuffer map1 = buffer.map(clQueue, MappingAccess.MAP_READ_ONLY); ByteBuffer map1 = buffer.map(clQueue, MappingAccess.MAP_READ_ONLY);
FloatBuffer map1F = map1.asFloatBuffer(); map1F.rewind(); FloatBuffer map1F = map1.asFloatBuffer(); map1F.rewind();
@ -282,6 +294,11 @@ public class HelloOpenCL extends SimpleApplication {
} }
image2.unmap(clQueue, map2); image2.unmap(clQueue, map2);
//release
image.release();
image2.release();
buffer.release();
} catch (AssertionError ex) { } catch (AssertionError ex) {
LOG.log(Level.SEVERE, "image test failed with an assertion error"); LOG.log(Level.SEVERE, "image test failed with an assertion error");
return false; return false;

@ -107,6 +107,7 @@ public class TestVertexBufferSharing extends SimpleApplication {
private void initOpenCL1() { private void initOpenCL1() {
clContext = context.getOpenCLContext(); clContext = context.getOpenCLContext();
clQueue = clContext.createQueue(); clQueue = clContext.createQueue();
clQueue.register();
//create kernel //create kernel
String source = "" String source = ""
+ "__kernel void ScaleKernel(__global float* vb, float scale)\n" + "__kernel void ScaleKernel(__global float* vb, float scale)\n"
@ -118,12 +119,15 @@ public class TestVertexBufferSharing extends SimpleApplication {
+ "}\n"; + "}\n";
Program program = clContext.createProgramFromSourceCode(source); Program program = clContext.createProgramFromSourceCode(source);
program.build(); program.build();
program.register();
kernel = program.createKernel("ScaleKernel"); kernel = program.createKernel("ScaleKernel");
kernel.register();
} }
private void initOpenCL2() { private void initOpenCL2() {
//bind vertex buffer to OpenCL //bind vertex buffer to OpenCL
VertexBuffer vb = geom.getMesh().getBuffer(VertexBuffer.Type.Position); VertexBuffer vb = geom.getMesh().getBuffer(VertexBuffer.Type.Position);
buffer = clContext.bindVertexBuffer(vb, MemoryAccess.READ_WRITE); buffer = clContext.bindVertexBuffer(vb, MemoryAccess.READ_WRITE);
buffer.register();
ws = new com.jme3.opencl.Kernel.WorkSize(geom.getMesh().getVertexCount()); ws = new com.jme3.opencl.Kernel.WorkSize(geom.getMesh().getVertexCount());
} }
private void updateOpenCL(float tpf) { private void updateOpenCL(float tpf) {
@ -131,15 +135,15 @@ public class TestVertexBufferSharing extends SimpleApplication {
time += tpf; time += tpf;
//aquire resource //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) //no need to wait for the returned event, since the kernel implicitely waits for it (same command queue)
//execute kernel //execute kernel
float scale = (float) Math.pow(1.1, (1.0 - time%2) / 16.0); 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 //release resource
buffer.releaseBufferForSharingAsync(clQueue); buffer.releaseBufferForSharingAsync(clQueue).release();
} }
} }

@ -120,26 +120,31 @@ public class TestWriteToTexture extends SimpleApplication implements AnalogListe
private void initOpenCL1() { private void initOpenCL1() {
clContext = context.getOpenCLContext(); clContext = context.getOpenCLContext();
clQueue = clContext.createQueue(); clQueue = clContext.createQueue();
clQueue.register();
//create kernel //create kernel
Program program = clContext.createProgramFromSourceFiles(assetManager, "jme3test/opencl/JuliaSet.cl"); Program program = clContext.createProgramFromSourceFiles(assetManager, "jme3test/opencl/JuliaSet.cl");
program.build(); program.build();
program.register();
kernel = program.createKernel("JuliaSet"); kernel = program.createKernel("JuliaSet");
kernel.register();
C = new Vector2f(0.12f, -0.2f); C = new Vector2f(0.12f, -0.2f);
} }
private void initOpenCL2() { private void initOpenCL2() {
//bind image to OpenCL //bind image to OpenCL
texCL = clContext.bindImage(tex, MemoryAccess.WRITE_ONLY); texCL = clContext.bindImage(tex, MemoryAccess.WRITE_ONLY);
texCL.register();
} }
private void updateOpenCL(float tpf) { private void updateOpenCL(float tpf) {
//aquire resource //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) //no need to wait for the returned event, since the kernel implicitely waits for it (same command queue)
//execute kernel //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 //release resource
texCL.releaseImageForSharingAsync(clQueue); texCL.releaseImageForSharingAsync(clQueue).release();
} }
@Override @Override

@ -48,9 +48,9 @@ public class JoclBuffer extends Buffer {
final CL cl; final CL cl;
public JoclBuffer(long id) { public JoclBuffer(long id) {
super(new ReleaserImpl(id));
this.id = id; this.id = id;
this.cl = CLPlatform.getLowLevelCLInterface(); this.cl = CLPlatform.getLowLevelCLInterface();
OpenCLObjectManager.getInstance().registerObject(this);
} }
@Override @Override
@ -203,10 +203,6 @@ public class JoclBuffer extends Buffer {
return new JoclEvent(event); return new JoclEvent(event);
} }
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(id);
}
private static class ReleaserImpl implements ObjectReleaser { private static class ReleaserImpl implements ObjectReleaser {
private long mem; private long mem;
private ReleaserImpl(long mem) { private ReleaserImpl(long mem) {

@ -42,15 +42,15 @@ import com.jogamp.opencl.llb.CLCommandQueueBinding;
* *
* @author shaman * @author shaman
*/ */
public class JoclCommandQueue implements CommandQueue { public class JoclCommandQueue extends CommandQueue {
final CL cl; final CL cl;
final long id; final long id;
public JoclCommandQueue(long id) { public JoclCommandQueue(long id) {
super(new ReleaserImpl(id));
this.id = id; this.id = id;
this.cl = CLPlatform.getLowLevelCLInterface(); this.cl = CLPlatform.getLowLevelCLInterface();
OpenCLObjectManager.getInstance().registerObject(this);
} }
@Override @Override
@ -65,23 +65,17 @@ public class JoclCommandQueue implements CommandQueue {
Utils.checkError(ret, "clFinish"); Utils.checkError(ret, "clFinish");
} }
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(id, cl);
}
private static class ReleaserImpl implements ObjectReleaser { private static class ReleaserImpl implements ObjectReleaser {
private long id; private long id;
private CLCommandQueueBinding cl;
private ReleaserImpl(long id, CLCommandQueueBinding cl) { private ReleaserImpl(long id) {
this.id = id; this.id = id;
this.cl = cl;
} }
@Override @Override
public void release() { public void release() {
if (id != 0) { if (id != 0) {
int ret = cl.clReleaseCommandQueue(id); int ret = CLPlatform.getLowLevelCLInterface().clReleaseCommandQueue(id);
id = 0; id = 0;
Utils.reportError(ret, "clReleaseCommandQueue"); Utils.reportError(ret, "clReleaseCommandQueue");
} }

@ -40,7 +40,6 @@ import com.jme3.texture.FrameBuffer;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
import com.jogamp.opencl.CLContext; import com.jogamp.opencl.CLContext;
import com.jogamp.opencl.CLImageFormat; import com.jogamp.opencl.CLImageFormat;
import com.jogamp.opencl.CLMemory;
import com.jogamp.opencl.CLMemory.Mem; import com.jogamp.opencl.CLMemory.Mem;
import com.jogamp.opencl.CLPlatform; import com.jogamp.opencl.CLPlatform;
import com.jogamp.opencl.llb.CL; 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.opencl.llb.impl.CLImageFormatImpl;
import com.jogamp.opengl.GL; import com.jogamp.opengl.GL;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -66,11 +64,11 @@ public class JoclContext extends Context {
private final List<JoclDevice> devices; private final List<JoclDevice> devices;
public JoclContext(CLContext context, List<JoclDevice> devices) { public JoclContext(CLContext context, List<JoclDevice> devices) {
super(new ReleaserImpl(context.ID, devices));
this.context = context; this.context = context;
this.id = context.ID; this.id = context.ID;
this.cl = context.getCL(); this.cl = context.getCL();
this.devices = devices; this.devices = devices;
OpenCLObjectManager.getInstance().registerObject(this);
} }
public CLContext getContext() { public CLContext getContext() {
@ -224,10 +222,6 @@ public class JoclContext extends Context {
return new JoclProgram(p, this); return new JoclProgram(p, this);
} }
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(id, devices);
}
private static class ReleaserImpl implements ObjectReleaser { private static class ReleaserImpl implements ObjectReleaser {
private long id; private long id;
private final List<JoclDevice> devices; private final List<JoclDevice> devices;

@ -41,16 +41,16 @@ import java.util.logging.Logger;
* *
* @author shaman * @author shaman
*/ */
public class JoclEvent implements Event { public class JoclEvent extends Event {
private static final Logger LOG = Logger.getLogger(JoclEvent.class.getName()); private static final Logger LOG = Logger.getLogger(JoclEvent.class.getName());
final long id; final long id;
final CL cl; final CL cl;
public JoclEvent(long id) { public JoclEvent(long id) {
super(new ReleaserImpl(id));
this.id = id; this.id = id;
this.cl = CLPlatform.getLowLevelCLInterface(); this.cl = CLPlatform.getLowLevelCLInterface();
OpenCLObjectManager.getInstance().registerObject(this);
} }
@Override @Override
@ -59,6 +59,7 @@ public class JoclEvent implements Event {
Utils.pointers[0].put(0, id); Utils.pointers[0].put(0, id);
int ret = cl.clWaitForEvents(1, Utils.pointers[0]); int ret = cl.clWaitForEvents(1, Utils.pointers[0]);
Utils.checkError(ret, "clWaitForEvents"); Utils.checkError(ret, "clWaitForEvents");
release();
} }
@Override @Override
@ -68,6 +69,7 @@ public class JoclEvent implements Event {
Utils.checkError(err, "clGetEventInfo"); Utils.checkError(err, "clGetEventInfo");
int status = Utils.tempBuffers[0].b16i.get(0); int status = Utils.tempBuffers[0].b16i.get(0);
if (status == CL.CL_SUCCESS) { if (status == CL.CL_SUCCESS) {
release();
return true; return true;
} else if (status < 0) { } else if (status < 0) {
Utils.checkError(status, "EventStatus"); Utils.checkError(status, "EventStatus");
@ -76,11 +78,6 @@ public class JoclEvent implements Event {
return false; return false;
} }
} }
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(id);
}
private static class ReleaserImpl implements ObjectReleaser { private static class ReleaserImpl implements ObjectReleaser {
private long event; private long event;

@ -44,16 +44,16 @@ import java.util.logging.Logger;
* *
* @author shaman * @author shaman
*/ */
public class JoclImage implements Image { public class JoclImage extends Image {
private static final Logger LOG = Logger.getLogger(JoclImage.class.getName()); private static final Logger LOG = Logger.getLogger(JoclImage.class.getName());
final long id; final long id;
final CL cl; final CL cl;
public JoclImage(long image) { public JoclImage(long image) {
super(new ReleaserImpl(image));
this.id = image; this.id = image;
this.cl = CLPlatform.getLowLevelCLInterface(); this.cl = CLPlatform.getLowLevelCLInterface();
OpenCLObjectManager.getInstance().registerObject(this);
} }
public static int decodeImageChannelOrder(ImageChannelOrder order) { public static int decodeImageChannelOrder(ImageChannelOrder order) {
@ -512,10 +512,6 @@ public class JoclImage implements Image {
return new JoclEvent(event); return new JoclEvent(event);
} }
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(id);
}
private static class ReleaserImpl implements ObjectReleaser { private static class ReleaserImpl implements ObjectReleaser {
private long mem; private long mem;
private ReleaserImpl(long mem) { private ReleaserImpl(long mem) {

@ -37,7 +37,6 @@ import com.jme3.math.Vector4f;
import com.jme3.opencl.*; import com.jme3.opencl.*;
import com.jme3.opencl.Buffer; import com.jme3.opencl.Buffer;
import com.jogamp.common.nio.PointerBuffer; import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.opencl.CLKernel;
import com.jogamp.opencl.CLPlatform; import com.jogamp.opencl.CLPlatform;
import com.jogamp.opencl.llb.CL; import com.jogamp.opencl.llb.CL;
import java.nio.*; import java.nio.*;
@ -55,6 +54,7 @@ public class JoclKernel extends Kernel {
final CL cl; final CL cl;
public JoclKernel(long kernel) { public JoclKernel(long kernel) {
super(new ReleaserImpl(kernel));
this.kernel = kernel; this.kernel = kernel;
this.cl = CLPlatform.getLowLevelCLInterface(); this.cl = CLPlatform.getLowLevelCLInterface();
OpenCLObjectManager.getInstance().registerObject(this); OpenCLObjectManager.getInstance().registerObject(this);
@ -240,10 +240,6 @@ public class JoclKernel extends Kernel {
return new JoclEvent(Utils.pointers[0].get(0)); return new JoclEvent(Utils.pointers[0].get(0));
} }
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(kernel);
}
private static class ReleaserImpl implements ObjectReleaser { private static class ReleaserImpl implements ObjectReleaser {
private long kernel; private long kernel;
private ReleaserImpl(long kernel) { private ReleaserImpl(long kernel) {

@ -50,7 +50,7 @@ import static com.jogamp.opencl.llb.CL.CL_SUCCESS;
* *
* @author shaman * @author shaman
*/ */
public class JoclProgram implements Program { public class JoclProgram extends Program {
private static final Logger LOG = Logger.getLogger(JoclProgram.class.getName()); private static final Logger LOG = Logger.getLogger(JoclProgram.class.getName());
final long program; final long program;
@ -58,10 +58,10 @@ public class JoclProgram implements Program {
private final JoclContext context; private final JoclContext context;
public JoclProgram(long program, JoclContext context) { public JoclProgram(long program, JoclContext context) {
super(new ReleaserImpl(program));
this.program = program; this.program = program;
this.context = context; this.context = context;
this.cl = CLPlatform.getLowLevelCLInterface(); this.cl = CLPlatform.getLowLevelCLInterface();
OpenCLObjectManager.getInstance().registerObject(this);
} }
@Override @Override
@ -79,11 +79,6 @@ public class JoclProgram implements Program {
LOG.log(Level.INFO, "Program compiled:\n{0}", Log()); LOG.log(Level.INFO, "Program compiled:\n{0}", Log());
} }
} }
@Override
public void build() throws KernelCompilationException {
build("");
}
private String Log(long device) { private String Log(long device) {
Utils.pointers[0].rewind(); Utils.pointers[0].rewind();
@ -131,10 +126,6 @@ public class JoclProgram implements Program {
return kx; return kx;
} }
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(program);
}
private static class ReleaserImpl implements ObjectReleaser { private static class ReleaserImpl implements ObjectReleaser {
private long program; private long program;
private ReleaserImpl(long program) { private ReleaserImpl(long program) {

@ -44,8 +44,8 @@ public class LwjglBuffer extends Buffer {
private final CLMem buffer; private final CLMem buffer;
public LwjglBuffer(CLMem buffer) { public LwjglBuffer(CLMem buffer) {
super(new ReleaserImpl(buffer));
this.buffer = buffer; this.buffer = buffer;
OpenCLObjectManager.getInstance().registerObject(this);
} }
public CLMem getBuffer() { public CLMem getBuffer() {
return buffer; return buffer;
@ -205,10 +205,6 @@ public class LwjglBuffer extends Buffer {
return new LwjglEvent(q.getCLEvent(event)); return new LwjglEvent(q.getCLEvent(event));
} }
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(buffer);
}
private static class ReleaserImpl implements ObjectReleaser { private static class ReleaserImpl implements ObjectReleaser {
private CLMem mem; private CLMem mem;
private ReleaserImpl(CLMem mem) { private ReleaserImpl(CLMem mem) {

@ -40,13 +40,13 @@ import org.lwjgl.opencl.CLCommandQueue;
* *
* @author shaman * @author shaman
*/ */
public class LwjglCommandQueue implements CommandQueue { public class LwjglCommandQueue extends CommandQueue {
private final CLCommandQueue queue; private final CLCommandQueue queue;
public LwjglCommandQueue(CLCommandQueue queue) { public LwjglCommandQueue(CLCommandQueue queue) {
super(new ReleaserImpl(queue));
this.queue = queue; this.queue = queue;
OpenCLObjectManager.getInstance().registerObject(this);
} }
public CLCommandQueue getQueue() { public CLCommandQueue getQueue() {
@ -65,10 +65,6 @@ public class LwjglCommandQueue implements CommandQueue {
Utils.checkError(ret, "clFinish"); Utils.checkError(ret, "clFinish");
} }
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(queue);
}
private static class ReleaserImpl implements ObjectReleaser { private static class ReleaserImpl implements ObjectReleaser {
private CLCommandQueue queue; private CLCommandQueue queue;
private ReleaserImpl(CLCommandQueue queue) { private ReleaserImpl(CLCommandQueue queue) {

@ -57,9 +57,9 @@ public class LwjglContext extends Context {
private final List<LwjglDevice> devices; private final List<LwjglDevice> devices;
public LwjglContext(CLContext context, List<LwjglDevice> devices) { public LwjglContext(CLContext context, List<LwjglDevice> devices) {
super(new ReleaserImpl(context, devices));
this.context = context; this.context = context;
this.devices = devices; this.devices = devices;
OpenCLObjectManager.getInstance().registerObject(this);
} }
public CLContext getContext() { public CLContext getContext() {
@ -208,10 +208,6 @@ public class LwjglContext extends Context {
return new LwjglProgram(p, this); return new LwjglProgram(p, this);
} }
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(context, devices);
}
private static class ReleaserImpl implements ObjectReleaser { private static class ReleaserImpl implements ObjectReleaser {
private CLContext context; private CLContext context;
private final List<LwjglDevice> devices; private final List<LwjglDevice> devices;

@ -41,31 +41,24 @@ import org.lwjgl.opencl.CLEvent;
* *
* @author shaman * @author shaman
*/ */
public class LwjglEvent implements Event { public class LwjglEvent extends Event {
private static final Logger LOG = Logger.getLogger(LwjglEvent.class.getName()); private static final Logger LOG = Logger.getLogger(LwjglEvent.class.getName());
private CLEvent event; private CLEvent event;
private ReleaserImpl releaser;
public LwjglEvent(CLEvent event) { public LwjglEvent(CLEvent event) {
super(new ReleaserImpl(event));
this.event = event; this.event = event;
if (event == null) { if (event == null) {
LOG.warning("event is null!"); LOG.warning("event is null!");
} else { } else {
OpenCLObjectManager.getInstance().registerObject(this); this.releaser = new ReleaserImpl(event);
} }
} }
public CLEvent getEvent() { public CLEvent getEvent() {
return event; 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 @Override
public void waitForFinished() { 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 static class ReleaserImpl implements ObjectReleaser {
private CLEvent event; private CLEvent event;

@ -43,14 +43,14 @@ import org.lwjgl.opencl.api.CLImageFormat;
* *
* @author shaman * @author shaman
*/ */
public class LwjglImage implements Image { public class LwjglImage extends Image {
private static final Logger LOG = Logger.getLogger(LwjglImage.class.getName()); private static final Logger LOG = Logger.getLogger(LwjglImage.class.getName());
private final CLMem image; private final CLMem image;
public LwjglImage(CLMem image) { public LwjglImage(CLMem image) {
super(new ReleaserImpl(image));
this.image = image; this.image = image;
OpenCLObjectManager.getInstance().registerObject(this);
} }
public CLMem getImage() { public CLMem getImage() {
@ -543,10 +543,6 @@ public class LwjglImage implements Image {
return new LwjglEvent(q.getCLEvent(event)); return new LwjglEvent(q.getCLEvent(event));
} }
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(image);
}
private static class ReleaserImpl implements ObjectReleaser { private static class ReleaserImpl implements ObjectReleaser {
private CLMem mem; private CLMem mem;
private ReleaserImpl(CLMem mem) { private ReleaserImpl(CLMem mem) {

@ -52,8 +52,8 @@ public class LwjglKernel extends Kernel {
private final CLKernel kernel; private final CLKernel kernel;
public LwjglKernel(CLKernel kernel) { public LwjglKernel(CLKernel kernel) {
super(new ReleaserImpl(kernel));
this.kernel = kernel; this.kernel = kernel;
OpenCLObjectManager.getInstance().registerObject(this);
} }
public CLKernel getKernel() { public CLKernel getKernel() {

@ -44,16 +44,16 @@ import org.lwjgl.opencl.*;
* *
* @author shaman * @author shaman
*/ */
public class LwjglProgram implements Program { public class LwjglProgram extends Program {
private static final Logger LOG = Logger.getLogger(LwjglProgram.class.getName()); private static final Logger LOG = Logger.getLogger(LwjglProgram.class.getName());
private final CLProgram program; private final CLProgram program;
private final LwjglContext context; private final LwjglContext context;
public LwjglProgram(CLProgram program, LwjglContext context) { public LwjglProgram(CLProgram program, LwjglContext context) {
super(new ReleaserImpl(program));
this.program = program; this.program = program;
this.context = context; this.context = context;
OpenCLObjectManager.getInstance().registerObject(this);
} }
public CLProgram getProgram() { public CLProgram getProgram() {
@ -75,11 +75,6 @@ public class LwjglProgram implements Program {
LOG.log(Level.INFO, "Program compiled:\n{0}", Log()); LOG.log(Level.INFO, "Program compiled:\n{0}", Log());
} }
} }
@Override
public void build() throws KernelCompilationException {
build("");
}
private String Log() { private String Log() {
StringBuilder str = new StringBuilder(); StringBuilder str = new StringBuilder();
@ -109,10 +104,6 @@ public class LwjglProgram implements Program {
return kx; return kx;
} }
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(program);
}
private static class ReleaserImpl implements ObjectReleaser { private static class ReleaserImpl implements ObjectReleaser {
private CLProgram program; private CLProgram program;
private ReleaserImpl(CLProgram program) { private ReleaserImpl(CLProgram program) {

Loading…
Cancel
Save