29 import jdk.internal.misc.Unsafe;
30
31 final class DRenderer implements DPathConsumer2D, MarlinRenderer {
32
33 static final boolean DISABLE_RENDER = false;
34
35 static final boolean ENABLE_BLOCK_FLAGS = MarlinProperties.isUseTileFlags();
36 static final boolean ENABLE_BLOCK_FLAGS_HEURISTICS = MarlinProperties.isUseTileFlagsWithHeuristics();
37
38 private static final int ALL_BUT_LSB = 0xFFFFFFFE;
39 private static final int ERR_STEP_MAX = 0x7FFFFFFF; // = 2^31 - 1
40
41 private static final double POWER_2_TO_32 = 0x1.0p32d;
42
43 // use double to make tosubpix methods faster (no int to double conversion)
44 static final double SUBPIXEL_SCALE_X = SUBPIXEL_POSITIONS_X;
45 static final double SUBPIXEL_SCALE_Y = SUBPIXEL_POSITIONS_Y;
46 static final int SUBPIXEL_MASK_X = SUBPIXEL_POSITIONS_X - 1;
47 static final int SUBPIXEL_MASK_Y = SUBPIXEL_POSITIONS_Y - 1;
48
49 // number of subpixels corresponding to a tile line
50 private static final int SUBPIXEL_TILE
51 = TILE_H << SUBPIXEL_LG_POSITIONS_Y;
52
53 // 2048 (pixelSize) pixels (height) x 8 subpixels = 64K
54 static final int INITIAL_BUCKET_ARRAY
55 = INITIAL_PIXEL_DIM * SUBPIXEL_POSITIONS_Y;
56
57 // crossing capacity = edges count / 4 ~ 1024
58 static final int INITIAL_CROSSING_COUNT = INITIAL_EDGES_COUNT >> 2;
59
60 public static final int WIND_EVEN_ODD = 0;
61 public static final int WIND_NON_ZERO = 1;
62
63 // common to all types of input path segments.
64 // OFFSET as bytes
65 // only integer values:
66 public static final long OFF_CURX_OR = 0;
67 public static final long OFF_ERROR = OFF_CURX_OR + SIZE_INT;
68 public static final long OFF_BUMP_X = OFF_ERROR + SIZE_INT;
651 // Force zero-fill dirty arrays:
652 edges.fill(BYTE_0);
653 }
654 if (DO_MONITORS) {
655 rdrCtx.stats.mon_rdr_endRendering.stop();
656 }
657 // recycle the RendererContext instance
658 DMarlinRenderingEngine.returnRendererContext(rdrCtx);
659 }
660
661 private static double tosubpixx(final double pix_x) {
662 return SUBPIXEL_SCALE_X * pix_x;
663 }
664
665 private static double tosubpixy(final double pix_y) {
666 // shift y by -0.5 for fast ceil(y - 0.5):
667 return SUBPIXEL_SCALE_Y * pix_y - 0.5d;
668 }
669
670 @Override
671 public void moveTo(double pix_x0, double pix_y0) {
672 closePath();
673 final double sx = tosubpixx(pix_x0);
674 final double sy = tosubpixy(pix_y0);
675 this.sx0 = sx;
676 this.sy0 = sy;
677 this.x0 = sx;
678 this.y0 = sy;
679 }
680
681 @Override
682 public void lineTo(double pix_x1, double pix_y1) {
683 final double x1 = tosubpixx(pix_x1);
684 final double y1 = tosubpixy(pix_y1);
685 addLine(x0, y0, x1, y1);
686 x0 = x1;
687 y0 = y1;
688 }
689
690 @Override
691 public void curveTo(double x1, double y1,
692 double x2, double y2,
693 double x3, double y3)
694 {
695 final double xe = tosubpixx(x3);
696 final double ye = tosubpixy(y3);
697 curve.set(x0, y0, tosubpixx(x1), tosubpixy(y1),
698 tosubpixx(x2), tosubpixy(y2), xe, ye);
699 curveBreakIntoLinesAndAdd(x0, y0, curve, xe, ye);
700 x0 = xe;
701 y0 = ye;
702 }
703
704 @Override
705 public void quadTo(double x1, double y1, double x2, double y2) {
706 final double xe = tosubpixx(x2);
707 final double ye = tosubpixy(y2);
708 curve.set(x0, y0, tosubpixx(x1), tosubpixy(y1), xe, ye);
709 quadBreakIntoLinesAndAdd(x0, y0, curve, xe, ye);
710 x0 = xe;
711 y0 = ye;
712 }
713
714 @Override
715 public void closePath() {
716 addLine(x0, y0, sx0, sy0);
717 x0 = sx0;
718 y0 = sy0;
719 }
720
721 @Override
722 public void pathDone() {
723 closePath();
724 }
725
726 @Override
727 public long getNativeConsumer() {
728 throw new InternalError("Renderer does not use a native consumer.");
729 }
730
731 private void _endRendering(final int ymin, final int ymax) {
732 if (DISABLE_RENDER) {
733 return;
734 }
735
736 // Get X bounds as true pixel boundaries to compute correct pixel coverage:
737 final int bboxx0 = bbox_spminX;
738 final int bboxx1 = bbox_spmaxX;
|
29 import jdk.internal.misc.Unsafe;
30
31 final class DRenderer implements DPathConsumer2D, MarlinRenderer {
32
33 static final boolean DISABLE_RENDER = false;
34
35 static final boolean ENABLE_BLOCK_FLAGS = MarlinProperties.isUseTileFlags();
36 static final boolean ENABLE_BLOCK_FLAGS_HEURISTICS = MarlinProperties.isUseTileFlagsWithHeuristics();
37
38 private static final int ALL_BUT_LSB = 0xFFFFFFFE;
39 private static final int ERR_STEP_MAX = 0x7FFFFFFF; // = 2^31 - 1
40
41 private static final double POWER_2_TO_32 = 0x1.0p32d;
42
43 // use double to make tosubpix methods faster (no int to double conversion)
44 static final double SUBPIXEL_SCALE_X = SUBPIXEL_POSITIONS_X;
45 static final double SUBPIXEL_SCALE_Y = SUBPIXEL_POSITIONS_Y;
46 static final int SUBPIXEL_MASK_X = SUBPIXEL_POSITIONS_X - 1;
47 static final int SUBPIXEL_MASK_Y = SUBPIXEL_POSITIONS_Y - 1;
48
49 static final double RDR_OFFSET_X = 0.501d / SUBPIXEL_SCALE_X;
50 static final double RDR_OFFSET_Y = 0.501d / SUBPIXEL_SCALE_Y;
51
52 // number of subpixels corresponding to a tile line
53 private static final int SUBPIXEL_TILE
54 = TILE_H << SUBPIXEL_LG_POSITIONS_Y;
55
56 // 2048 (pixelSize) pixels (height) x 8 subpixels = 64K
57 static final int INITIAL_BUCKET_ARRAY
58 = INITIAL_PIXEL_DIM * SUBPIXEL_POSITIONS_Y;
59
60 // crossing capacity = edges count / 4 ~ 1024
61 static final int INITIAL_CROSSING_COUNT = INITIAL_EDGES_COUNT >> 2;
62
63 public static final int WIND_EVEN_ODD = 0;
64 public static final int WIND_NON_ZERO = 1;
65
66 // common to all types of input path segments.
67 // OFFSET as bytes
68 // only integer values:
69 public static final long OFF_CURX_OR = 0;
70 public static final long OFF_ERROR = OFF_CURX_OR + SIZE_INT;
71 public static final long OFF_BUMP_X = OFF_ERROR + SIZE_INT;
654 // Force zero-fill dirty arrays:
655 edges.fill(BYTE_0);
656 }
657 if (DO_MONITORS) {
658 rdrCtx.stats.mon_rdr_endRendering.stop();
659 }
660 // recycle the RendererContext instance
661 DMarlinRenderingEngine.returnRendererContext(rdrCtx);
662 }
663
664 private static double tosubpixx(final double pix_x) {
665 return SUBPIXEL_SCALE_X * pix_x;
666 }
667
668 private static double tosubpixy(final double pix_y) {
669 // shift y by -0.5 for fast ceil(y - 0.5):
670 return SUBPIXEL_SCALE_Y * pix_y - 0.5d;
671 }
672
673 @Override
674 public void moveTo(final double pix_x0, final double pix_y0) {
675 closePath();
676 final double sx = tosubpixx(pix_x0);
677 final double sy = tosubpixy(pix_y0);
678 this.sx0 = sx;
679 this.sy0 = sy;
680 this.x0 = sx;
681 this.y0 = sy;
682 }
683
684 @Override
685 public void lineTo(final double pix_x1, final double pix_y1) {
686 final double x1 = tosubpixx(pix_x1);
687 final double y1 = tosubpixy(pix_y1);
688 addLine(x0, y0, x1, y1);
689 x0 = x1;
690 y0 = y1;
691 }
692
693 @Override
694 public void curveTo(final double pix_x1, final double pix_y1,
695 final double pix_x2, final double pix_y2,
696 final double pix_x3, final double pix_y3)
697 {
698 final double xe = tosubpixx(pix_x3);
699 final double ye = tosubpixy(pix_y3);
700 curve.set(x0, y0, tosubpixx(pix_x1), tosubpixy(pix_y1),
701 tosubpixx(pix_x2), tosubpixy(pix_y2), xe, ye);
702 curveBreakIntoLinesAndAdd(x0, y0, curve, xe, ye);
703 x0 = xe;
704 y0 = ye;
705 }
706
707 @Override
708 public void quadTo(final double pix_x1, final double pix_y1,
709 final double pix_x2, final double pix_y2)
710 {
711 final double xe = tosubpixx(pix_x2);
712 final double ye = tosubpixy(pix_y2);
713 curve.set(x0, y0, tosubpixx(pix_x1), tosubpixy(pix_y1), xe, ye);
714 quadBreakIntoLinesAndAdd(x0, y0, curve, xe, ye);
715 x0 = xe;
716 y0 = ye;
717 }
718
719 @Override
720 public void closePath() {
721 if (x0 != sx0 || y0 != sy0) {
722 addLine(x0, y0, sx0, sy0);
723 x0 = sx0;
724 y0 = sy0;
725 }
726 }
727
728 @Override
729 public void pathDone() {
730 closePath();
731 }
732
733 @Override
734 public long getNativeConsumer() {
735 throw new InternalError("Renderer does not use a native consumer.");
736 }
737
738 private void _endRendering(final int ymin, final int ymax) {
739 if (DISABLE_RENDER) {
740 return;
741 }
742
743 // Get X bounds as true pixel boundaries to compute correct pixel coverage:
744 final int bboxx0 = bbox_spminX;
745 final int bboxx1 = bbox_spmaxX;
|