Skip to content

Commit

Permalink
merged with latest jdk10 changes & marlin-fx 0.9.1
Browse files Browse the repository at this point in the history
  • Loading branch information
bourgesl committed Apr 25, 2018
1 parent 4b7acfa commit 0f2f2e8
Show file tree
Hide file tree
Showing 42 changed files with 4,036 additions and 1,735 deletions.
16 changes: 10 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<groupId>org.marlin</groupId>
<artifactId>marlinfx</artifactId>
<packaging>jar</packaging>
<version>0.8.2-Unsafe-OpenJDK9</version>
<version>0.9.1-Unsafe-OpenJDK9</version>
<name>Marlin software rasterizer</name>

<url>https://github.com/bourgesl/marlin-renderer</url>
Expand Down Expand Up @@ -62,7 +62,7 @@
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
Expand All @@ -78,6 +78,10 @@
<compilerArgs>
<arg>--patch-module</arg>
<arg>javafx.graphics=src</arg>
<arg>--add-modules</arg>
<arg>jdk.unsupported,java.logging</arg>
<arg>--add-reads</arg>
<arg>javafx.graphics=jdk.unsupported,java.logging</arg>
</compilerArgs>
</configuration>
<executions>
Expand All @@ -94,15 +98,15 @@
<arg>--module-path</arg>
<arg>${project.build.directory}/test-libs</arg>
<arg>--add-modules</arg>
<arg>java.logging,junit,hamcrest.core</arg>
<arg>jdk.unsupported,java.logging,junit,hamcrest.core</arg>
<arg>--add-reads</arg>
<arg>javafx.graphics=java.logging,junit,hamcrest.core</arg>
<arg>javafx.graphics=jdk.unsupported,java.logging,junit,hamcrest.core</arg>
</compilerArgs>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
Expand All @@ -118,7 +122,7 @@
</archive>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
Expand Down
16 changes: 6 additions & 10 deletions src/main/java/com/sun/marlin/ByteArrayCache.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -99,7 +99,7 @@ static final class Reference {
Reference(final ByteArrayCache cache, final int initialSize) {
this.cache = cache;
this.clean = cache.clean;
this.initial = createArray(initialSize, clean);
this.initial = createArray(initialSize);
if (DO_STATS) {
cache.stats.totalInitial += initialSize;
}
Expand All @@ -116,7 +116,7 @@ byte[] getArray(final int length) {
logInfo(getLogPrefix(clean) + "ByteArrayCache: "
+ "getArray[oversize]: length=\t" + length);
}
return createArray(length, clean);
return createArray(length);
}

byte[] widenArray(final byte[] array, final int usedSize,
Expand Down Expand Up @@ -202,7 +202,7 @@ byte[] getArray() {
if (DO_STATS) {
stats.createOp++;
}
return createArray(arraySize, clean);
return createArray(arraySize);
}

void putArray(final byte[] array)
Expand All @@ -229,12 +229,8 @@ void putArray(final byte[] array)
}
}

static byte[] createArray(final int length, final boolean clean) {
if (clean) {
return new byte[length];
}
// use JDK9 Unsafe.allocateUninitializedArray(class, length):
return (byte[]) OffHeapArray.UNSAFE.allocateUninitializedArray(byte.class, length);
static byte[] createArray(final int length) {
return new byte[length];
}

static void fill(final byte[] array, final int fromIndex,
Expand Down
163 changes: 92 additions & 71 deletions src/main/java/com/sun/marlin/Curve.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -33,86 +33,94 @@ final class Curve {
Curve() {
}

void set(float[] points, int type) {
switch(type) {
case 8:
void set(final float[] points, final int type) {
// if instead of switch (perf + most probable cases first)
if (type == 8) {
set(points[0], points[1],
points[2], points[3],
points[4], points[5],
points[6], points[7]);
return;
case 6:
} else if (type == 4) {
set(points[0], points[1],
points[2], points[3]);
} else {
set(points[0], points[1],
points[2], points[3],
points[4], points[5]);
return;
default:
throw new InternalError("Curves can only be cubic or quadratic");
}
}

void set(float x1, float y1,
float x2, float y2,
float x3, float y3,
float x4, float y4)
void set(final float x1, final float y1,
final float x2, final float y2,
final float x3, final float y3,
final float x4, final float y4)
{
final float dx32 = 3.0f * (x3 - x2);
final float dy32 = 3.0f * (y3 - y2);
final float dx21 = 3.0f * (x2 - x1);
final float dy21 = 3.0f * (y2 - y1);
ax = (x4 - x1) - dx32;
ax = (x4 - x1) - dx32; // A = P3 - P0 - 3 (P2 - P1) = (P3 - P0) + 3 (P1 - P2)
ay = (y4 - y1) - dy32;
bx = (dx32 - dx21);
bx = (dx32 - dx21); // B = 3 (P2 - P1) - 3(P1 - P0) = 3 (P2 + P0) - 6 P1
by = (dy32 - dy21);
cx = dx21;
cx = dx21; // C = 3 (P1 - P0)
cy = dy21;
dx = x1;
dx = x1; // D = P0
dy = y1;
dax = 3.0f * ax; day = 3.0f * ay;
dbx = 2.0f * bx; dby = 2.0f * by;
dax = 3.0f * ax;
day = 3.0f * ay;
dbx = 2.0f * bx;
dby = 2.0f * by;
}

void set(float x1, float y1,
float x2, float y2,
float x3, float y3)
void set(final float x1, final float y1,
final float x2, final float y2,
final float x3, final float y3)
{
final float dx21 = (x2 - x1);
final float dy21 = (y2 - y1);
ax = 0.0f; ay = 0.0f;
bx = (x3 - x2) - dx21;
ax = 0.0f; // A = 0
ay = 0.0f;
bx = (x3 - x2) - dx21; // B = P3 - P0 - 2 P2
by = (y3 - y2) - dy21;
cx = 2.0f * dx21;
cx = 2.0f * dx21; // C = 2 (P2 - P1)
cy = 2.0f * dy21;
dx = x1;
dx = x1; // D = P1
dy = y1;
dax = 0.0f; day = 0.0f;
dbx = 2.0f * bx; dby = 2.0f * by;
}

float xat(float t) {
return t * (t * (t * ax + bx) + cx) + dx;
}
float yat(float t) {
return t * (t * (t * ay + by) + cy) + dy;
}

float dxat(float t) {
return t * (t * dax + dbx) + cx;
dax = 0.0f;
day = 0.0f;
dbx = 2.0f * bx;
dby = 2.0f * by;
}

float dyat(float t) {
return t * (t * day + dby) + cy;
void set(final float x1, final float y1,
final float x2, final float y2)
{
final float dx21 = (x2 - x1);
final float dy21 = (y2 - y1);
ax = 0.0f; // A = 0
ay = 0.0f;
bx = 0.0f; // B = 0
by = 0.0f;
cx = dx21; // C = (P2 - P1)
cy = dy21;
dx = x1; // D = P1
dy = y1;
dax = 0.0f;
day = 0.0f;
dbx = 0.0f;
dby = 0.0f;
}

int dxRoots(float[] roots, int off) {
int dxRoots(final float[] roots, final int off) {
return Helpers.quadraticRoots(dax, dbx, cx, roots, off);
}

int dyRoots(float[] roots, int off) {
int dyRoots(final float[] roots, final int off) {
return Helpers.quadraticRoots(day, dby, cy, roots, off);
}

int infPoints(float[] pts, int off) {
int infPoints(final float[] pts, final int off) {
// inflection point at t if -f'(t)x*f''(t)y + f'(t)y*f''(t)x == 0
// Fortunately, this turns out to be quadratic, so there are at
// most 2 inflection points.
Expand All @@ -123,19 +131,30 @@ int infPoints(float[] pts, int off) {
return Helpers.quadraticRoots(a, b, c, pts, off);
}

int xPoints(final float[] ts, final int off, final float x)
{
return Helpers.cubicRootsInAB(ax, bx, cx, dx - x, ts, off, 0.0f, 1.0f);
}

int yPoints(final float[] ts, final int off, final float y)
{
return Helpers.cubicRootsInAB(ay, by, cy, dy - y, ts, off, 0.0f, 1.0f);
}

// finds points where the first and second derivative are
// perpendicular. This happens when g(t) = f'(t)*f''(t) == 0 (where
// * is a dot product). Unfortunately, we have to solve a cubic.
private int perpendiculardfddf(float[] pts, int off) {
private int perpendiculardfddf(final float[] pts, final int off) {
assert pts.length >= off + 4;

// these are the coefficients of some multiple of g(t) (not g(t),
// because the roots of a polynomial are not changed after multiplication
// by a constant, and this way we save a few multiplications).
final float a = 2.0f * (dax*dax + day*day);
final float b = 3.0f * (dax*dbx + day*dby);
final float c = 2.0f * (dax*cx + day*cy) + dbx*dbx + dby*dby;
final float d = dbx*cx + dby*cy;
final float a = 2.0f * (dax * dax + day * day);
final float b = 3.0f * (dax * dbx + day * dby);
final float c = 2.0f * (dax * cx + day * cy) + dbx * dbx + dby * dby;
final float d = dbx * cx + dby * cy;

return Helpers.cubicRootsInAB(a, b, c, d, pts, off, 0.0f, 1.0f);
}

Expand All @@ -152,22 +171,24 @@ private int perpendiculardfddf(float[] pts, int off) {
// at most 4 sub-intervals of (0,1). ROC has asymptotes at inflection
// points, so roc-w can have at least 6 roots. This shouldn't be a
// problem for what we're trying to do (draw a nice looking curve).
int rootsOfROCMinusW(float[] roots, int off, final float w, final float err) {
int rootsOfROCMinusW(final float[] roots, final int off, final float w2, final float err) {
// no OOB exception, because by now off<=6, and roots.length >= 10
assert off <= 6 && roots.length >= 10;

int ret = off;
int numPerpdfddf = perpendiculardfddf(roots, off);
float t0 = 0.0f, ft0 = ROCsq(t0) - w*w;
roots[off + numPerpdfddf] = 1.0f; // always check interval end points
numPerpdfddf++;
for (int i = off; i < off + numPerpdfddf; i++) {
float t1 = roots[i], ft1 = ROCsq(t1) - w*w;
final int end = off + perpendiculardfddf(roots, off);
roots[end] = 1.0f; // always check interval end points

float t0 = 0.0f, ft0 = ROCsq(t0) - w2;

for (int i = off; i <= end; i++) {
float t1 = roots[i], ft1 = ROCsq(t1) - w2;
if (ft0 == 0.0f) {
roots[ret++] = t0;
} else if (ft1 * ft0 < 0.0f) { // have opposite signs
// (ROC(t)^2 == w^2) == (ROC(t) == w) is true because
// ROC(t) >= 0 for all t.
roots[ret++] = falsePositionROCsqMinusX(t0, t1, w*w, err);
roots[ret++] = falsePositionROCsqMinusX(t0, t1, w2, err);
}
t0 = t1;
ft0 = ft1;
Expand All @@ -176,9 +197,9 @@ int rootsOfROCMinusW(float[] roots, int off, final float w, final float err) {
return ret - off;
}

private static float eliminateInf(float x) {
private static float eliminateInf(final float x) {
return (x == Float.POSITIVE_INFINITY ? Float.MAX_VALUE :
(x == Float.NEGATIVE_INFINITY ? Float.MIN_VALUE : x));
(x == Float.NEGATIVE_INFINITY ? Float.MIN_VALUE : x));
}

// A slight modification of the false position algorithm on wikipedia.
Expand All @@ -188,17 +209,18 @@ private static float eliminateInf(float x) {
// expressions make it into the language), depending on how closures
// and turn out. Same goes for the newton's method
// algorithm in Helpers.java
private float falsePositionROCsqMinusX(float x0, float x1,
final float x, final float err)
private float falsePositionROCsqMinusX(final float t0, final float t1,
final float w2, final float err)
{
final int iterLimit = 100;
int side = 0;
float t = x1, ft = eliminateInf(ROCsq(t) - x);
float s = x0, fs = eliminateInf(ROCsq(s) - x);
float t = t1, ft = eliminateInf(ROCsq(t) - w2);
float s = t0, fs = eliminateInf(ROCsq(s) - w2);
float r = s, fr;

for (int i = 0; i < iterLimit && Math.abs(t - s) > err * Math.abs(t + s); i++) {
r = (fs * t - ft * s) / (fs - ft);
fr = ROCsq(r) - x;
fr = ROCsq(r) - w2;
if (sameSign(fr, ft)) {
ft = fr; t = r;
if (side < 0) {
Expand All @@ -207,7 +229,7 @@ private float falsePositionROCsqMinusX(float x0, float x1,
} else {
side = -1;
}
} else if (fr * fs > 0) {
} else if (fr * fs > 0.0f) {
fs = fr; s = r;
if (side > 0) {
ft /= (1 << side);
Expand All @@ -222,22 +244,21 @@ private float falsePositionROCsqMinusX(float x0, float x1,
return r;
}

private static boolean sameSign(float x, float y) {
private static boolean sameSign(final float x, final float y) {
// another way is to test if x*y > 0. This is bad for small x, y.
return (x < 0.0f && y < 0.0f) || (x > 0.0f && y > 0.0f);
}

// returns the radius of curvature squared at t of this curve
// see http://en.wikipedia.org/wiki/Radius_of_curvature_(applications)
private float ROCsq(final float t) {
// dx=xat(t) and dy=yat(t). These calls have been inlined for efficiency
final float dx = t * (t * dax + dbx) + cx;
final float dy = t * (t * day + dby) + cy;
final float ddx = 2.0f * dax * t + dbx;
final float ddy = 2.0f * day * t + dby;
final float dx2dy2 = dx*dx + dy*dy;
final float ddx2ddy2 = ddx*ddx + ddy*ddy;
final float ddxdxddydy = ddx*dx + ddy*dy;
return dx2dy2*((dx2dy2*dx2dy2) / (dx2dy2 * ddx2ddy2 - ddxdxddydy*ddxdxddydy));
final float dx2dy2 = dx * dx + dy * dy;
final float ddx2ddy2 = ddx * ddx + ddy * ddy;
final float ddxdxddydy = ddx * dx + ddy * dy;
return dx2dy2 * ((dx2dy2 * dx2dy2) / (dx2dy2 * ddx2ddy2 - ddxdxddydy * ddxdxddydy));
}
}
Loading

0 comments on commit 0f2f2e8

Please sign in to comment.