# Space-separated list of JVM arguments used when running the project.
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
# To set system properties for unit tests define test-sys-prop.name=value:
-run.jvmargs=-Djava.library.path=../nativez/bin/notzed.nativez/linux-amd64/lib:bin/notzed.zcl/linux-amd64/lib
+run.jvmargs=--add-exports jdk.incubator.foreign/jdk.incubator.foreign.unsafe=notzed.zcl
run.modulepath=\
${javac.modulepath}:\
${build.modules.dir}
import javafx.util.Duration;
import java.nio.ByteBuffer;
import au.notzed.zcl.CLMemory;
+import au.notzed.zcl.CLObject;
import java.io.IOException;
import java.io.InputStream;
+import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import javafx.geometry.Rectangle2D;
import javafx.stage.Screen;
return t;
});
+ Timeline tofps;
+ Transition spin;
+ Zoom zoom;
long nframes;
long lframes;
case "target":
if (v.equals("list")) {
System.out.println("Available targets:");
- for (Target t : targets) {
+ for (Target t: targets) {
System.out.print("\t");
System.out.println(t.name);
}
case "size":
if (v.equals("full")) {
Rectangle2D size = Screen.getPrimary().getBounds();
- width = (int) size.getWidth();
- height = (int) size.getHeight();
+ width = (int)size.getWidth();
+ height = (int)size.getHeight();
fullscreen = true;
} else {
String coords[] = v.split(",");
buffer = CLMemory.alloc(width * height * 4);
- Timeline tofps = new Timeline(new KeyFrame(Duration.seconds(0.1), (ActionEvent event) -> {
+ tofps = new Timeline(new KeyFrame(Duration.seconds(0.1), (ActionEvent event) -> {
fps.setText(String.format("fps %4d maxiter %d", (nframes - lframes) * 10, lastiter));
lframes = nframes;
}));
tofps.play();
if (delta != 0.0) {
- Transition spin = new Transition(rate) {
+ spin = new Transition(rate) {
{
setCycleDuration(Duration.seconds(360 / (Math.abs(delta))));
}
arg = Math.toRadians(90);
}
- Zoom zoom = synchronous ? new Zoom() : new Zoom(rate);
+ zoom = synchronous ? new Zoom() : new Zoom(rate);
zoom.setInterpolator(Interpolator.EASE_BOTH);
zoom.setAutoReverse(true);
zoom.setCycleCount(Timeline.INDEFINITE);
@Override
public void stop() throws Exception {
+ // weird, one needs to explitly stop animations?
+ zoom.stop();
+ tofps.stop();
+ if (spin != null)
+ spin.stop();
+ CLObject.debugDumpReachable("Running objects at exit");
+ queue.shutdown();
+ queue.awaitTermination(5, TimeUnit.SECONDS);
calc.release();
+ System.gc();
+ Thread.sleep(1000);
+ CLObject.debugDumpReachable("Post release");
}
class Zoom extends Transition {
@Override
protected void interpolate(double frac) {
double scale = alpha / Math.exp(frac * beta);
- int depth = (int) (-Math.log(scale) * gamma);
+ int depth = (int)(-Math.log(scale) * gamma);
recalc(target, isdouble, scale, arg, depth);
}
.setPixels(0, 0, width, height, PixelFormat.getByteBgraInstance(), buffer, width * 4);
}
}
+
+ public static void main(String[] args) {
+ launch(args);
+ }
}
this.func = func;
}
+ @Override
+ public String toString() {
+ return func == null ? "Callback.NULL" : func.toString();
+ }
+
/*
* A callback that resolve to MemoryAddress.NULL.
* This can be released safely any number of times.
final MemorySegment stack;
final MemoryAddress base;
long sp;
+ Thread origin;
Stack(MemoryAddress p, long size) {
super(p);
stack = ForeignUnsafe.ofNativeUnchecked(addr(), size);
base = stack.baseAddress();
sp = size;
+
+ origin = Thread.currentThread();
+ }
+
+ public String toString() {
+ return "api.Memory$Stack thread=" + origin.toString();
}
private static void release(MemoryAddress p) {
/**
* Base class for all native objects.
- *
+ *
* Handles instantiation and provides helper functions for native access.
- *
+ *
* Work in progress.
+ *
+ * For better safety the 'p' field should be the CHandle, and addr() would
+ * call get(). Otherwise one must not release ANY object which might ever
+ * be used again - including any objects returned by the getInfo(). However ...
+ * it's a trade-off and it's a lot of code to change.
+ *
*/
public class Native {
T o;
boolean step = false;
- if (dolog)
- log().log(Level.DEBUG, () -> String.format(" resolv $%016x %s", Memory.toLong(p), create));
+ //if (dolog)
+ // log().log(Level.DEBUG, () -> String.format(" resolv $%016x %s", Memory.toLong(p), create));
- // ??? who the fuck knows if this will work
- if (p.offset() == 0)
+ if (Memory.toLong(p) == 0)
return null;
// Instantiation needs to be synchronized for obvious reasons.
synchronized (map) {
CHandle h = (CHandle) map.get(p);
+ String fmt;
+
if (h == null || (o = (T)(h.get())) == null) {
o = create.apply(p);
+
+ fmt = h == null ? " create $%016x %s" : " replac $%016x %s";
+
h = new CHandle(o, references, p);
map.put(h);
step = true;
+ } else {
+ fmt = " exists $%016x %s";
+ }
+ {
+ T x = o;
+ log().log(Level.DEBUG, () -> String.format(fmt, Memory.toLong(p), x.getClass().getName()));
}
}
WeakReference<? extends Native> ref;
synchronized (map) {
- ref = map.remove(p);
+ //ref = map.remove(p);
+ ref = map.get(p);
}
if (ref != null) {
if (dolog)
log().log(Level.DEBUG, () -> String.format(" force $%016x %s", Memory.toLong(p), getClass().getName()));
+ ref.clear();
ref.enqueue();
}
}
}
}
+ public static void debugDumpReachable(String title) {
+ synchronized (map) {
+ System.out.println(title);
+ for (CHandle h: map.table) {
+ while (h != null) {
+ Native o = h.get();
+ System.out.printf(" $%016x: %s %-40s %s\n",
+ Memory.toLong(h.p),
+ o == null ? "dead" : "live",
+ h.jtype.getName(),
+ o);
+ h = h.next;
+ }
+ }
+ }
+ }
+
/**
* Lightweight pointer hashtable.
* <p>
private static void release(MemoryAddress p) {
// noop
- }
-
- @Override
- public void release() {
- // noop
+ System.out.println("** release clplatform");
}
@Override
res = (int)clGetPlatformIDs.invokeExact(0, MemoryAddress.NULL, lenp);
if (res != 0)
throw new CLRuntimeException(res);
-
+
len = Native.getInt(lenp);
list = frame.alloca(8 * len);
/**
* Get the platform api versiom.
- *
+ *
* This may be compared to the version constants
* {@link #VERSION_1_0}, {@link #VERSION_1_1}, and so on.
- *
+ *
* @return platform api version.
*/
public int getAPIVersion() {
return apiVersion;
}
-
+
/**
* get CL_PLATFORM_PROFILE.
*