< prev index next >

modules/javafx.graphics/src/main/java/com/sun/marlin/Renderer.java

Print this page

        

*** 36,49 **** private static final int ERR_STEP_MAX = 0x7FFFFFFF; // = 2^31 - 1 private static final double POWER_2_TO_32 = 0x1.0p32; // use float to make tosubpix methods faster (no int to float conversion) ! static final float F_SUBPIXEL_POSITIONS_X ! = (float) SUBPIXEL_POSITIONS_X; ! static final float F_SUBPIXEL_POSITIONS_Y ! = (float) SUBPIXEL_POSITIONS_Y; static final int SUBPIXEL_MASK_X = SUBPIXEL_POSITIONS_X - 1; static final int SUBPIXEL_MASK_Y = SUBPIXEL_POSITIONS_Y - 1; // 2048 (pixelSize) pixels (height) x 8 subpixels = 64K static final int INITIAL_BUCKET_ARRAY --- 36,47 ---- private static final int ERR_STEP_MAX = 0x7FFFFFFF; // = 2^31 - 1 private static final double POWER_2_TO_32 = 0x1.0p32; // use float to make tosubpix methods faster (no int to float conversion) ! static final float SUBPIXEL_SCALE_X = (float) SUBPIXEL_POSITIONS_X; ! static final float SUBPIXEL_SCALE_Y = (float) SUBPIXEL_POSITIONS_Y; static final int SUBPIXEL_MASK_X = SUBPIXEL_POSITIONS_X - 1; static final int SUBPIXEL_MASK_Y = SUBPIXEL_POSITIONS_Y - 1; // 2048 (pixelSize) pixels (height) x 8 subpixels = 64K static final int INITIAL_BUCKET_ARRAY
*** 66,114 **** 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 * (NORM_SUBPIXELS / 8f); // 1 pixel // cubic error in subpixels to increment step private static final float CUB_INC_ERR_SUBPIX ! = 0.4f * (NORM_SUBPIXELS / 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 * (NORM_SUBPIXELS / 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 --- 64,112 ---- 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 * (NORM_SUBPIXELS / 8.0f); // 1 pixel // cubic error in subpixels to increment step private static final float CUB_INC_ERR_SUBPIX ! = 0.4f * (NORM_SUBPIXELS / 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 * (NORM_SUBPIXELS / 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
*** 175,195 **** 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; --- 173,193 ---- 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;
*** 232,243 **** 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; --- 230,241 ---- 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;
*** 249,285 **** 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); } --- 247,280 ---- 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); }
*** 347,357 **** 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; } --- 342,352 ---- 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; }
*** 362,372 **** // 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; --- 357,367 ---- // 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;
*** 460,470 **** 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; --- 455,465 ---- 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;
*** 652,667 **** rdrCtx.stats.mon_rdr_endRendering.stop(); } } private static float tosubpixx(final float pix_x) { ! return F_SUBPIXEL_POSITIONS_X * pix_x; } private static float tosubpixy(final float pix_y) { // shift y by -0.5 for fast ceil(y - 0.5): ! return F_SUBPIXEL_POSITIONS_Y * pix_y - 0.5f; } @Override public void moveTo(float pix_x0, float pix_y0) { closePath(); --- 647,662 ---- rdrCtx.stats.mon_rdr_endRendering.stop(); } } private static float tosubpixx(final float pix_x) { ! return SUBPIXEL_SCALE_X * pix_x; } private static float tosubpixy(final float pix_y) { // shift y by -0.5 for fast ceil(y - 0.5): ! return SUBPIXEL_SCALE_Y * pix_y - 0.5f; } @Override public void moveTo(float pix_x0, float pix_y0) { closePath();
*** 1179,1190 **** _alpha[pix_x ] += tmp; _alpha[pix_x + 1] -= tmp; if (useBlkFlags) { // flag used blocks: ! _blkFlags[ pix_x >> _BLK_SIZE_LG] = 1; ! _blkFlags[(pix_x + 1) >> _BLK_SIZE_LG] = 1; } } else { tmp = (x0 & _SUBPIXEL_MASK_X); _alpha[pix_x ] += (_SUBPIXEL_POSITIONS_X - tmp); --- 1174,1185 ---- _alpha[pix_x ] += tmp; _alpha[pix_x + 1] -= tmp; if (useBlkFlags) { // flag used blocks: ! // note: block processing handles extra pixel: ! _blkFlags[pix_x >> _BLK_SIZE_LG] = 1; } } else { tmp = (x0 & _SUBPIXEL_MASK_X); _alpha[pix_x ] += (_SUBPIXEL_POSITIONS_X - tmp);
*** 1199,1212 **** _alpha[pix_xmax + 1] -= tmp; if (useBlkFlags) { // flag used blocks: ! _blkFlags[ pix_x >> _BLK_SIZE_LG] = 1; ! _blkFlags[(pix_x + 1) >> _BLK_SIZE_LG] = 1; ! _blkFlags[ pix_xmax >> _BLK_SIZE_LG] = 1; ! _blkFlags[(pix_xmax + 1) >> _BLK_SIZE_LG] = 1; } } } } --- 1194,1206 ---- _alpha[pix_xmax + 1] -= tmp; if (useBlkFlags) { // flag used blocks: ! // note: block processing handles extra pixel: ! _blkFlags[pix_x >> _BLK_SIZE_LG] = 1; ! _blkFlags[pix_xmax >> _BLK_SIZE_LG] = 1; } } } }
*** 1250,1261 **** _alpha[pix_x ] += tmp; _alpha[pix_x + 1] -= tmp; if (useBlkFlags) { // flag used blocks: ! _blkFlags[ pix_x >> _BLK_SIZE_LG] = 1; ! _blkFlags[(pix_x + 1) >> _BLK_SIZE_LG] = 1; } } else { tmp = (x0 & _SUBPIXEL_MASK_X); _alpha[pix_x ] += (_SUBPIXEL_POSITIONS_X - tmp); --- 1244,1255 ---- _alpha[pix_x ] += tmp; _alpha[pix_x + 1] -= tmp; if (useBlkFlags) { // flag used blocks: ! // note: block processing handles extra pixel: ! _blkFlags[pix_x >> _BLK_SIZE_LG] = 1; } } else { tmp = (x0 & _SUBPIXEL_MASK_X); _alpha[pix_x ] += (_SUBPIXEL_POSITIONS_X - tmp);
*** 1270,1283 **** _alpha[pix_xmax + 1] -= tmp; if (useBlkFlags) { // flag used blocks: ! _blkFlags[ pix_x >> _BLK_SIZE_LG] = 1; ! _blkFlags[(pix_x + 1) >> _BLK_SIZE_LG] = 1; ! _blkFlags[ pix_xmax >> _BLK_SIZE_LG] = 1; ! _blkFlags[(pix_xmax + 1) >> _BLK_SIZE_LG] = 1; } } } prev = _MAX_VALUE; } --- 1264,1276 ---- _alpha[pix_xmax + 1] -= tmp; if (useBlkFlags) { // flag used blocks: ! // note: block processing handles extra pixel: ! _blkFlags[pix_x >> _BLK_SIZE_LG] = 1; ! _blkFlags[pix_xmax >> _BLK_SIZE_LG] = 1; } } } prev = _MAX_VALUE; }
< prev index next >