< prev index next >
modules/javafx.graphics/src/main/java/com/sun/marlin/RendererNoAA.java
Print this page
*** 57,105 ****
public static final int SIZEOF_EDGE_BYTES = (int)(OFF_YMAX + SIZE_INT);
// curve break into lines
// cubic error in subpixels to decrement step
private static final float CUB_DEC_ERR_SUBPIX
! = 1f * (1f / 8f); // 1 pixel
// cubic error in subpixels to increment step
private static final float CUB_INC_ERR_SUBPIX
! = 0.4f * (1f / 8f); // 0.4 pixel
// bad paths (59294/100000 == 59,29%, 94335 bad pixels (avg = 1,59), 3966 warnings (avg = 0,07)
// cubic bind length to decrement step
public static final float CUB_DEC_BND
! = 8f * CUB_DEC_ERR_SUBPIX;
// cubic bind length to increment step
public static final float CUB_INC_BND
! = 8f * CUB_INC_ERR_SUBPIX;
// cubic countlg
public static final int CUB_COUNT_LG = 2;
// cubic count = 2^countlg
private static final int CUB_COUNT = 1 << CUB_COUNT_LG;
// cubic count^2 = 4^countlg
private static final int CUB_COUNT_2 = 1 << (2 * CUB_COUNT_LG);
// cubic count^3 = 8^countlg
private static final int CUB_COUNT_3 = 1 << (3 * CUB_COUNT_LG);
// cubic dt = 1 / count
! private static final float CUB_INV_COUNT = 1f / CUB_COUNT;
// cubic dt^2 = 1 / count^2 = 1 / 4^countlg
! private static final float CUB_INV_COUNT_2 = 1f / CUB_COUNT_2;
// cubic dt^3 = 1 / count^3 = 1 / 8^countlg
! private static final float CUB_INV_COUNT_3 = 1f / CUB_COUNT_3;
// quad break into lines
// quadratic error in subpixels
private static final float QUAD_DEC_ERR_SUBPIX
! = 0.5f * (1f / 8f); // 0.5 pixel
// bad paths (62916/100000 == 62,92%, 103818 bad pixels (avg = 1,65), 6514 warnings (avg = 0,10)
// quadratic bind length to decrement step
public static final float QUAD_DEC_BND
! = 8f * QUAD_DEC_ERR_SUBPIX;
//////////////////////////////////////////////////////////////////////////////
// SCAN LINE
//////////////////////////////////////////////////////////////////////////////
// crossings ie subpixel edge x coordinates
--- 57,105 ----
public static final int SIZEOF_EDGE_BYTES = (int)(OFF_YMAX + SIZE_INT);
// curve break into lines
// cubic error in subpixels to decrement step
private static final float CUB_DEC_ERR_SUBPIX
! = 1.0f * (1.0f / 8.0f); // 1 pixel
// cubic error in subpixels to increment step
private static final float CUB_INC_ERR_SUBPIX
! = 0.4f * (1.0f / 8.0f); // 0.4 pixel
// bad paths (59294/100000 == 59,29%, 94335 bad pixels (avg = 1,59), 3966 warnings (avg = 0,07)
// cubic bind length to decrement step
public static final float CUB_DEC_BND
! = 8.0f * CUB_DEC_ERR_SUBPIX;
// cubic bind length to increment step
public static final float CUB_INC_BND
! = 8.0f * CUB_INC_ERR_SUBPIX;
// cubic countlg
public static final int CUB_COUNT_LG = 2;
// cubic count = 2^countlg
private static final int CUB_COUNT = 1 << CUB_COUNT_LG;
// cubic count^2 = 4^countlg
private static final int CUB_COUNT_2 = 1 << (2 * CUB_COUNT_LG);
// cubic count^3 = 8^countlg
private static final int CUB_COUNT_3 = 1 << (3 * CUB_COUNT_LG);
// cubic dt = 1 / count
! private static final float CUB_INV_COUNT = 1.0f / CUB_COUNT;
// cubic dt^2 = 1 / count^2 = 1 / 4^countlg
! private static final float CUB_INV_COUNT_2 = 1.0f / CUB_COUNT_2;
// cubic dt^3 = 1 / count^3 = 1 / 8^countlg
! private static final float CUB_INV_COUNT_3 = 1.0f / CUB_COUNT_3;
// quad break into lines
// quadratic error in subpixels
private static final float QUAD_DEC_ERR_SUBPIX
! = 0.5f * (1.0f / 8.0f); // 0.5 pixel
// bad paths (62916/100000 == 62,92%, 103818 bad pixels (avg = 1,65), 6514 warnings (avg = 0,10)
// quadratic bind length to decrement step
public static final float QUAD_DEC_BND
! = 8.0f * QUAD_DEC_ERR_SUBPIX;
//////////////////////////////////////////////////////////////////////////////
// SCAN LINE
//////////////////////////////////////////////////////////////////////////////
// crossings ie subpixel edge x coordinates
*** 166,186 ****
final float _DEC_BND = QUAD_DEC_BND;
while (maxDD >= _DEC_BND) {
// divide step by half:
! maxDD /= 4f; // error divided by 2^2 = 4
count <<= 1;
if (DO_STATS) {
rdrCtx.stats.stat_rdr_quadBreak_dec.add(count);
}
}
int nL = 0; // line count
if (count > 1) {
! final float icount = 1f / count; // dt
final float icount2 = icount * icount; // dt^2
final float ddx = c.dbx * icount2;
final float ddy = c.dby * icount2;
float dx = c.bx * icount2 + c.cx * icount;
--- 166,186 ----
final float _DEC_BND = QUAD_DEC_BND;
while (maxDD >= _DEC_BND) {
// divide step by half:
! maxDD /= 4.0f; // error divided by 2^2 = 4
count <<= 1;
if (DO_STATS) {
rdrCtx.stats.stat_rdr_quadBreak_dec.add(count);
}
}
int nL = 0; // line count
if (count > 1) {
! final float icount = 1.0f / count; // dt
final float icount2 = icount * icount; // dt^2
final float ddx = c.dbx * icount2;
final float ddy = c.dby * icount2;
float dx = c.bx * icount2 + c.cx * icount;
*** 223,234 ****
final float icount3 = CUB_INV_COUNT_3; // dt^3
// the dx and dy refer to forward differencing variables, not the last
// coefficients of the "points" polynomial
float dddx, dddy, ddx, ddy, dx, dy;
! dddx = 2f * c.dax * icount3;
! dddy = 2f * c.day * icount3;
ddx = dddx + c.dbx * icount2;
ddy = dddy + c.dby * icount2;
dx = c.ax * icount3 + c.bx * icount2 + c.cx * icount;
dy = c.ay * icount3 + c.by * icount2 + c.cy * icount;
--- 223,234 ----
final float icount3 = CUB_INV_COUNT_3; // dt^3
// the dx and dy refer to forward differencing variables, not the last
// coefficients of the "points" polynomial
float dddx, dddy, ddx, ddy, dx, dy;
! dddx = 2.0f * c.dax * icount3;
! dddy = 2.0f * c.day * icount3;
ddx = dddx + c.dbx * icount2;
ddy = dddy + c.dby * icount2;
dx = c.ax * icount3 + c.bx * icount2 + c.cx * icount;
dy = c.ay * icount3 + c.by * icount2 + c.cy * icount;
*** 240,276 ****
final float _INC_BND = CUB_INC_BND;
while (count > 0) {
// divide step by half:
while (Math.abs(ddx) + Math.abs(ddy) >= _DEC_BND) {
! dddx /= 8f;
! dddy /= 8f;
! ddx = ddx/4f - dddx;
! ddy = ddy/4f - dddy;
! dx = (dx - ddx) / 2f;
! dy = (dy - ddy) / 2f;
count <<= 1;
if (DO_STATS) {
rdrCtx.stats.stat_rdr_curveBreak_dec.add(count);
}
}
// double step:
- // TODO: why use first derivative dX|Y instead of second ddX|Y ?
- // both scale changes should use speed or acceleration to have the same metric.
-
// can only do this on even "count" values, because we must divide count by 2
while (count % 2 == 0
&& Math.abs(dx) + Math.abs(dy) <= _INC_BND)
{
! dx = 2f * dx + ddx;
! dy = 2f * dy + ddy;
! ddx = 4f * (ddx + dddx);
! ddy = 4f * (ddy + dddy);
! dddx *= 8f;
! dddy *= 8f;
count >>= 1;
if (DO_STATS) {
rdrCtx.stats.stat_rdr_curveBreak_inc.add(count);
}
--- 240,273 ----
final float _INC_BND = CUB_INC_BND;
while (count > 0) {
// divide step by half:
while (Math.abs(ddx) + Math.abs(ddy) >= _DEC_BND) {
! dddx /= 8.0f;
! dddy /= 8.0f;
! ddx = ddx / 4.0f - dddx;
! ddy = ddy / 4.0f - dddy;
! dx = (dx - ddx) / 2.0f;
! dy = (dy - ddy) / 2.0f;
count <<= 1;
if (DO_STATS) {
rdrCtx.stats.stat_rdr_curveBreak_dec.add(count);
}
}
// double step:
// can only do this on even "count" values, because we must divide count by 2
while (count % 2 == 0
&& Math.abs(dx) + Math.abs(dy) <= _INC_BND)
{
! dx = 2.0f * dx + ddx;
! dy = 2.0f * dy + ddy;
! ddx = 4.0f * (ddx + dddx);
! ddy = 4.0f * (ddy + dddy);
! dddx *= 8.0f;
! dddy *= 8.0f;
count >>= 1;
if (DO_STATS) {
rdrCtx.stats.stat_rdr_curveBreak_inc.add(count);
}
*** 338,348 ****
rdrCtx.stats.stat_rdr_addLine_skip.add(1);
}
return;
}
! // edge min/max X/Y are in subpixel space (inclusive) within bounds:
// note: Use integer crossings to ensure consistent range within
// edgeBuckets / edgeBucketCounts arrays in case of NaN values (int = 0)
if (firstCrossing < edgeMinY) {
edgeMinY = firstCrossing;
}
--- 335,345 ----
rdrCtx.stats.stat_rdr_addLine_skip.add(1);
}
return;
}
! // edge min/max X/Y are in subpixel space (half-open interval):
// note: Use integer crossings to ensure consistent range within
// edgeBuckets / edgeBucketCounts arrays in case of NaN values (int = 0)
if (firstCrossing < edgeMinY) {
edgeMinY = firstCrossing;
}
*** 353,363 ****
// Use double-precision for improved accuracy:
final double x1d = x1;
final double y1d = y1;
final double slope = (x1d - x2) / (y1d - y2);
! if (slope >= 0.0) { // <==> x1 < x2
if (x1 < edgeMinX) {
edgeMinX = x1;
}
if (x2 > edgeMaxX) {
edgeMaxX = x2;
--- 350,360 ----
// Use double-precision for improved accuracy:
final double x1d = x1;
final double y1d = y1;
final double slope = (x1d - x2) / (y1d - y2);
! if (slope >= 0.0d) { // <==> x1 < x2
if (x1 < edgeMinX) {
edgeMinX = x1;
}
if (x2 > edgeMaxX) {
edgeMaxX = x2;
*** 451,461 ****
final int bucketIdx = firstCrossing - _boundsMinY;
// pointer from bucket
_unsafe.putInt(addr, _edgeBuckets[bucketIdx]);
addr += SIZE_INT;
! // y max (inclusive)
_unsafe.putInt(addr, lastCrossing);
// Update buckets:
// directly the edge struct "pointer"
_edgeBuckets[bucketIdx] = edgePtr;
--- 448,458 ----
final int bucketIdx = firstCrossing - _boundsMinY;
// pointer from bucket
_unsafe.putInt(addr, _edgeBuckets[bucketIdx]);
addr += SIZE_INT;
! // y max (exclusive)
_unsafe.putInt(addr, lastCrossing);
// Update buckets:
// directly the edge struct "pointer"
_edgeBuckets[bucketIdx] = edgePtr;
< prev index next >