jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinRenderingEngine.java
changeset 39519 21bfc4452441
parent 36902 bb30d89aa00e
child 40421 d5ee65e2b0fb
equal deleted inserted replaced
39518:cf5567d544b4 39519:21bfc4452441
    83     public Shape createStrokedShape(Shape src,
    83     public Shape createStrokedShape(Shape src,
    84                                     float width,
    84                                     float width,
    85                                     int caps,
    85                                     int caps,
    86                                     int join,
    86                                     int join,
    87                                     float miterlimit,
    87                                     float miterlimit,
    88                                     float dashes[],
    88                                     float[] dashes,
    89                                     float dashphase)
    89                                     float dashphase)
    90     {
    90     {
    91         final RendererContext rdrCtx = getRendererContext();
    91         final RendererContext rdrCtx = getRendererContext();
    92         try {
    92         try {
    93             // initialize a large copyable Path2D to avoid a lot of array growing:
    93             // initialize a large copyable Path2D to avoid a lot of array growing:
   276                         float width,
   276                         float width,
   277                         NormMode normalize,
   277                         NormMode normalize,
   278                         int caps,
   278                         int caps,
   279                         int join,
   279                         int join,
   280                         float miterlimit,
   280                         float miterlimit,
   281                         float dashes[],
   281                         float[] dashes,
   282                         float dashphase,
   282                         float dashphase,
   283                         PathConsumer2D pc2d)
   283                         PathConsumer2D pc2d)
   284     {
   284     {
   285         // We use strokerat so that in Stroker and Dasher we can work only
   285         // We use strokerat so that in Stroker and Dasher we can work only
   286         // with the pre-transformation coordinates. This will repeat a lot of
   286         // with the pre-transformation coordinates. This will repeat a lot of
   338                     dashLen = dashes.length;
   338                     dashLen = dashes.length;
   339                     final float[] newDashes;
   339                     final float[] newDashes;
   340                     if (dashLen <= INITIAL_ARRAY) {
   340                     if (dashLen <= INITIAL_ARRAY) {
   341                         newDashes = rdrCtx.dasher.dashes_initial;
   341                         newDashes = rdrCtx.dasher.dashes_initial;
   342                     } else {
   342                     } else {
   343                         if (doStats) {
   343                         if (DO_STATS) {
   344                             RendererContext.stats.stat_array_dasher_dasher
   344                             rdrCtx.stats.stat_array_dasher_dasher
   345                                 .add(dashLen);
   345                                 .add(dashLen);
   346                         }
   346                         }
   347                         newDashes = rdrCtx.getDirtyFloatArray(dashLen);
   347                         newDashes = rdrCtx.getDirtyFloatArray(dashLen);
   348                     }
   348                     }
   349                     System.arraycopy(dashes, 0, newDashes, 0, dashLen);
   349                     System.arraycopy(dashes, 0, newDashes, 0, dashLen);
   378             // either at is null or it's the identity. In either case
   378             // either at is null or it's the identity. In either case
   379             // we don't transform the path.
   379             // we don't transform the path.
   380             at = null;
   380             at = null;
   381         }
   381         }
   382 
   382 
   383         if (useSimplifier) {
   383         if (USE_SIMPLIFIER) {
   384             // Use simplifier after stroker before Renderer
   384             // Use simplifier after stroker before Renderer
   385             // to remove collinear segments (notably due to cap square)
   385             // to remove collinear segments (notably due to cap square)
   386             pc2d = rdrCtx.simplifier.init(pc2d);
   386             pc2d = rdrCtx.simplifier.init(pc2d);
   387         }
   387         }
   388 
   388 
   472             this.src = null;
   472             this.src = null;
   473         }
   473         }
   474 
   474 
   475         @Override
   475         @Override
   476         public final int currentSegment(final float[] coords) {
   476         public final int currentSegment(final float[] coords) {
   477             if (doMonitors) {
       
   478                 RendererContext.stats.mon_npi_currentSegment.start();
       
   479             }
       
   480             int lastCoord;
   477             int lastCoord;
   481             final int type = src.currentSegment(coords);
   478             final int type = src.currentSegment(coords);
   482 
   479 
   483             switch(type) {
   480             switch(type) {
   484                 case PathIterator.SEG_MOVETO:
   481                 case PathIterator.SEG_MOVETO:
   493                     break;
   490                     break;
   494                 case PathIterator.SEG_CLOSE:
   491                 case PathIterator.SEG_CLOSE:
   495                     // we don't want to deal with this case later. We just exit now
   492                     // we don't want to deal with this case later. We just exit now
   496                     curx_adjust = movx_adjust;
   493                     curx_adjust = movx_adjust;
   497                     cury_adjust = movy_adjust;
   494                     cury_adjust = movy_adjust;
   498 
       
   499                     if (doMonitors) {
       
   500                         RendererContext.stats.mon_npi_currentSegment.stop();
       
   501                     }
       
   502                     return type;
   495                     return type;
   503                 default:
   496                 default:
   504                     throw new InternalError("Unrecognized curve type");
   497                     throw new InternalError("Unrecognized curve type");
   505             }
   498             }
   506 
       
   507             // TODO: handle NaN, Inf and overflow
       
   508 
   499 
   509             // normalize endpoint
   500             // normalize endpoint
   510             float coord, x_adjust, y_adjust;
   501             float coord, x_adjust, y_adjust;
   511 
   502 
   512             coord = coords[lastCoord];
   503             coord = coords[lastCoord];
   541                     // handled earlier
   532                     // handled earlier
   542                 default:
   533                 default:
   543             }
   534             }
   544             curx_adjust = x_adjust;
   535             curx_adjust = x_adjust;
   545             cury_adjust = y_adjust;
   536             cury_adjust = y_adjust;
   546 
       
   547             if (doMonitors) {
       
   548                 RendererContext.stats.mon_npi_currentSegment.stop();
       
   549             }
       
   550             return type;
   537             return type;
   551         }
   538         }
   552 
   539 
   553         abstract float normCoord(final float coord);
   540         abstract float normCoord(final float coord);
   554 
   541 
   788                                               AffineTransform at,
   775                                               AffineTransform at,
   789                                               Region clip,
   776                                               Region clip,
   790                                               BasicStroke bs,
   777                                               BasicStroke bs,
   791                                               boolean thin,
   778                                               boolean thin,
   792                                               boolean normalize,
   779                                               boolean normalize,
   793                                               int bbox[])
   780                                               int[] bbox)
   794     {
   781     {
   795         MarlinTileGenerator ptg = null;
   782         MarlinTileGenerator ptg = null;
   796         Renderer r = null;
   783         Renderer r = null;
   797 
   784 
   798         final RendererContext rdrCtx = getRendererContext();
   785         final RendererContext rdrCtx = getRendererContext();
   806             if (bs == null) {
   793             if (bs == null) {
   807                 // fill shape:
   794                 // fill shape:
   808                 final PathIterator pi = getNormalizingPathIterator(rdrCtx, norm,
   795                 final PathIterator pi = getNormalizingPathIterator(rdrCtx, norm,
   809                                             s.getPathIterator(_at));
   796                                             s.getPathIterator(_at));
   810 
   797 
       
   798                 // note: Winding rule may be EvenOdd ONLY for fill operations !
   811                 r = rdrCtx.renderer.init(clip.getLoX(), clip.getLoY(),
   799                 r = rdrCtx.renderer.init(clip.getLoX(), clip.getLoY(),
   812                                          clip.getWidth(), clip.getHeight(),
   800                                          clip.getWidth(), clip.getHeight(),
   813                                          pi.getWindingRule());
   801                                          pi.getWindingRule());
   814 
   802 
   815                 // TODO: subdivide quad/cubic curves into monotonic curves ?
   803                 // TODO: subdivide quad/cubic curves into monotonic curves ?
   846     public final AATileGenerator getAATileGenerator(double x, double y,
   834     public final AATileGenerator getAATileGenerator(double x, double y,
   847                                                     double dx1, double dy1,
   835                                                     double dx1, double dy1,
   848                                                     double dx2, double dy2,
   836                                                     double dx2, double dy2,
   849                                                     double lw1, double lw2,
   837                                                     double lw1, double lw2,
   850                                                     Region clip,
   838                                                     Region clip,
   851                                                     int bbox[])
   839                                                     int[] bbox)
   852     {
   840     {
   853         // REMIND: Deal with large coordinates!
   841         // REMIND: Deal with large coordinates!
   854         double ldx1, ldy1, ldx2, ldy2;
   842         double ldx1, ldy1, ldx2, ldy2;
   855         boolean innerpgram = (lw1 > 0.0 && lw2 > 0.0);
   843         boolean innerpgram = (lw1 > 0.0 && lw2 > 0.0);
   856 
   844 
   947         }
   935         }
   948     }
   936     }
   949 
   937 
   950     // --- RendererContext handling ---
   938     // --- RendererContext handling ---
   951     // use ThreadLocal or ConcurrentLinkedQueue to get one RendererContext
   939     // use ThreadLocal or ConcurrentLinkedQueue to get one RendererContext
   952     private static final boolean useThreadLocal;
   940     private static final boolean USE_THREAD_LOCAL;
   953 
   941 
   954     // reference type stored in either TL or CLQ
   942     // reference type stored in either TL or CLQ
   955     static final int REF_TYPE;
   943     static final int REF_TYPE;
   956 
   944 
   957     // Per-thread RendererContext
   945     // Per-thread RendererContext
   958     private static final ReentrantContextProvider<RendererContext> rdrCtxProvider;
   946     private static final ReentrantContextProvider<RendererContext> RDR_CTX_PROVIDER;
   959 
   947 
   960     // Static initializer to use TL or CLQ mode
   948     // Static initializer to use TL or CLQ mode
   961     static {
   949     static {
   962         useThreadLocal = MarlinProperties.isUseThreadLocal();
   950         USE_THREAD_LOCAL = MarlinProperties.isUseThreadLocal();
   963 
   951 
   964         // Soft reference by default:
   952         // Soft reference by default:
   965         final String refType = AccessController.doPrivileged(
   953         final String refType = AccessController.doPrivileged(
   966                             new GetPropertyAction("sun.java2d.renderer.useRef",
   954                             new GetPropertyAction("sun.java2d.renderer.useRef",
   967                             "soft"));
   955                             "soft"));
   976             case "hard":
   964             case "hard":
   977                 REF_TYPE = ReentrantContextProvider.REF_HARD;
   965                 REF_TYPE = ReentrantContextProvider.REF_HARD;
   978                 break;
   966                 break;
   979         }
   967         }
   980 
   968 
   981         if (useThreadLocal) {
   969         if (USE_THREAD_LOCAL) {
   982             rdrCtxProvider = new ReentrantContextProviderTL<RendererContext>(REF_TYPE)
   970             RDR_CTX_PROVIDER = new ReentrantContextProviderTL<RendererContext>(REF_TYPE)
   983                 {
   971                 {
   984                     @Override
   972                     @Override
   985                     protected RendererContext newContext() {
   973                     protected RendererContext newContext() {
   986                         return RendererContext.createContext();
   974                         return RendererContext.createContext();
   987                     }
   975                     }
   988                 };
   976                 };
   989         } else {
   977         } else {
   990             rdrCtxProvider = new ReentrantContextProviderCLQ<RendererContext>(REF_TYPE)
   978             RDR_CTX_PROVIDER = new ReentrantContextProviderCLQ<RendererContext>(REF_TYPE)
   991                 {
   979                 {
   992                     @Override
   980                     @Override
   993                     protected RendererContext newContext() {
   981                     protected RendererContext newContext() {
   994                         return RendererContext.createContext();
   982                         return RendererContext.createContext();
   995                     }
   983                     }
   996                 };
   984                 };
   997         }
   985         }
   998     }
   986     }
   999 
   987 
  1000     private static boolean settingsLogged = !enableLogs;
   988     private static boolean SETTINGS_LOGGED = !ENABLE_LOGS;
  1001 
   989 
  1002     private static void logSettings(final String reClass) {
   990     private static void logSettings(final String reClass) {
  1003         // log information at startup
   991         // log information at startup
  1004         if (settingsLogged) {
   992         if (SETTINGS_LOGGED) {
  1005             return;
   993             return;
  1006         }
   994         }
  1007         settingsLogged = true;
   995         SETTINGS_LOGGED = true;
  1008 
   996 
  1009         String refType;
   997         String refType;
  1010         switch (REF_TYPE) {
   998         switch (REF_TYPE) {
  1011             default:
   999             default:
  1012             case ReentrantContextProvider.REF_HARD:
  1000             case ReentrantContextProvider.REF_HARD:
  1027         logInfo("Version                              = ["
  1015         logInfo("Version                              = ["
  1028                 + Version.getVersion() + "]");
  1016                 + Version.getVersion() + "]");
  1029         logInfo("sun.java2d.renderer                  = "
  1017         logInfo("sun.java2d.renderer                  = "
  1030                 + reClass);
  1018                 + reClass);
  1031         logInfo("sun.java2d.renderer.useThreadLocal   = "
  1019         logInfo("sun.java2d.renderer.useThreadLocal   = "
  1032                 + useThreadLocal);
  1020                 + USE_THREAD_LOCAL);
  1033         logInfo("sun.java2d.renderer.useRef           = "
  1021         logInfo("sun.java2d.renderer.useRef           = "
  1034                 + refType);
  1022                 + refType);
  1035 
  1023 
  1036         logInfo("sun.java2d.renderer.pixelsize        = "
  1024         logInfo("sun.java2d.renderer.pixelsize        = "
  1037                 + MarlinConst.INITIAL_PIXEL_DIM);
  1025                 + MarlinConst.INITIAL_PIXEL_DIM);
  1061         logInfo("sun.java2d.renderer.rleMinWidth      = "
  1049         logInfo("sun.java2d.renderer.rleMinWidth      = "
  1062                 + MarlinCache.RLE_MIN_WIDTH);
  1050                 + MarlinCache.RLE_MIN_WIDTH);
  1063 
  1051 
  1064         // optimisation parameters
  1052         // optimisation parameters
  1065         logInfo("sun.java2d.renderer.useSimplifier    = "
  1053         logInfo("sun.java2d.renderer.useSimplifier    = "
  1066                 + MarlinConst.useSimplifier);
  1054                 + MarlinConst.USE_SIMPLIFIER);
  1067 
  1055 
  1068         // debugging parameters
  1056         // debugging parameters
  1069         logInfo("sun.java2d.renderer.doStats          = "
  1057         logInfo("sun.java2d.renderer.doStats          = "
  1070                 + MarlinConst.doStats);
  1058                 + MarlinConst.DO_STATS);
  1071         logInfo("sun.java2d.renderer.doMonitors       = "
  1059         logInfo("sun.java2d.renderer.doMonitors       = "
  1072                 + MarlinConst.doMonitors);
  1060                 + MarlinConst.DO_MONITORS);
  1073         logInfo("sun.java2d.renderer.doChecks         = "
  1061         logInfo("sun.java2d.renderer.doChecks         = "
  1074                 + MarlinConst.doChecks);
  1062                 + MarlinConst.DO_CHECKS);
  1075 
  1063 
  1076         // logging parameters
  1064         // logging parameters
  1077         logInfo("sun.java2d.renderer.useLogger        = "
  1065         logInfo("sun.java2d.renderer.useLogger        = "
  1078                 + MarlinConst.useLogger);
  1066                 + MarlinConst.USE_LOGGER);
  1079         logInfo("sun.java2d.renderer.logCreateContext = "
  1067         logInfo("sun.java2d.renderer.logCreateContext = "
  1080                 + MarlinConst.logCreateContext);
  1068                 + MarlinConst.LOG_CREATE_CONTEXT);
  1081         logInfo("sun.java2d.renderer.logUnsafeMalloc  = "
  1069         logInfo("sun.java2d.renderer.logUnsafeMalloc  = "
  1082                 + MarlinConst.logUnsafeMalloc);
  1070                 + MarlinConst.LOG_UNSAFE_MALLOC);
  1083 
  1071 
  1084         // quality settings
  1072         // quality settings
  1085         logInfo("Renderer settings:");
  1073         logInfo("Renderer settings:");
  1086         logInfo("CUB_COUNT_LG = " + Renderer.CUB_COUNT_LG);
  1074         logInfo("CUB_COUNT_LG = " + Renderer.CUB_COUNT_LG);
  1087         logInfo("CUB_DEC_BND  = " + Renderer.CUB_DEC_BND);
  1075         logInfo("CUB_DEC_BND  = " + Renderer.CUB_DEC_BND);
  1096      * Get the RendererContext instance dedicated to the current thread
  1084      * Get the RendererContext instance dedicated to the current thread
  1097      * @return RendererContext instance
  1085      * @return RendererContext instance
  1098      */
  1086      */
  1099     @SuppressWarnings({"unchecked"})
  1087     @SuppressWarnings({"unchecked"})
  1100     static RendererContext getRendererContext() {
  1088     static RendererContext getRendererContext() {
  1101         final RendererContext rdrCtx = rdrCtxProvider.acquire();
  1089         final RendererContext rdrCtx = RDR_CTX_PROVIDER.acquire();
  1102         if (doMonitors) {
  1090         if (DO_MONITORS) {
  1103             RendererContext.stats.mon_pre_getAATileGenerator.start();
  1091             rdrCtx.stats.mon_pre_getAATileGenerator.start();
  1104         }
  1092         }
  1105         return rdrCtx;
  1093         return rdrCtx;
  1106     }
  1094     }
  1107 
  1095 
  1108     /**
  1096     /**
  1110      * @param rdrCtx RendererContext instance
  1098      * @param rdrCtx RendererContext instance
  1111      */
  1099      */
  1112     static void returnRendererContext(final RendererContext rdrCtx) {
  1100     static void returnRendererContext(final RendererContext rdrCtx) {
  1113         rdrCtx.dispose();
  1101         rdrCtx.dispose();
  1114 
  1102 
  1115         if (doMonitors) {
  1103         if (DO_MONITORS) {
  1116             RendererContext.stats.mon_pre_getAATileGenerator.stop();
  1104             rdrCtx.stats.mon_pre_getAATileGenerator.stop();
  1117         }
  1105         }
  1118         rdrCtxProvider.release(rdrCtx);
  1106         RDR_CTX_PROVIDER.release(rdrCtx);
  1119     }
  1107     }
  1120 }
  1108 }