1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.java2d.marlin; 27 28 import java.security.AccessController; 29 import java.security.PrivilegedAction; 30 import java.util.Timer; 31 import java.util.TimerTask; 32 import java.util.concurrent.ConcurrentLinkedQueue; 33 import static sun.java2d.marlin.MarlinUtils.logInfo; 34 import sun.java2d.marlin.stats.Histogram; 35 import sun.java2d.marlin.stats.Monitor; 36 import sun.java2d.marlin.stats.StatLong; 37 import sun.misc.ThreadGroupUtils; 38 39 /** 40 * This class gathers global rendering statistics for debugging purposes only 41 */ 42 public final class RendererStats implements MarlinConst { 43 44 // singleton 45 private static volatile RendererStats singleton = null; 46 getInstance()47 static RendererStats getInstance() { 48 if (singleton == null) { 49 singleton = new RendererStats(); 50 } 51 return singleton; 52 } 53 dumpStats()54 public static void dumpStats() { 55 if (singleton != null) { 56 singleton.dump(); 57 } 58 } 59 60 /* RendererContext collection as hard references 61 (only used for debugging purposes) */ 62 final ConcurrentLinkedQueue<RendererContext> allContexts 63 = new ConcurrentLinkedQueue<RendererContext>(); 64 // stats 65 final StatLong stat_cache_rowAA 66 = new StatLong("cache.rowAA"); 67 final StatLong stat_cache_rowAAChunk 68 = new StatLong("cache.rowAAChunk"); 69 final StatLong stat_cache_tiles 70 = new StatLong("cache.tiles"); 71 final StatLong stat_rdr_poly_stack_curves 72 = new StatLong("renderer.poly.stack.curves"); 73 final StatLong stat_rdr_poly_stack_types 74 = new StatLong("renderer.poly.stack.types"); 75 final StatLong stat_rdr_addLine 76 = new StatLong("renderer.addLine"); 77 final StatLong stat_rdr_addLine_skip 78 = new StatLong("renderer.addLine.skip"); 79 final StatLong stat_rdr_curveBreak 80 = new StatLong("renderer.curveBreakIntoLinesAndAdd"); 81 final StatLong stat_rdr_curveBreak_dec 82 = new StatLong("renderer.curveBreakIntoLinesAndAdd.dec"); 83 final StatLong stat_rdr_curveBreak_inc 84 = new StatLong("renderer.curveBreakIntoLinesAndAdd.inc"); 85 final StatLong stat_rdr_quadBreak 86 = new StatLong("renderer.quadBreakIntoLinesAndAdd"); 87 final StatLong stat_rdr_quadBreak_dec 88 = new StatLong("renderer.quadBreakIntoLinesAndAdd.dec"); 89 final StatLong stat_rdr_edges 90 = new StatLong("renderer.edges"); 91 final StatLong stat_rdr_edges_count 92 = new StatLong("renderer.edges.count"); 93 final StatLong stat_rdr_edges_resizes 94 = new StatLong("renderer.edges.resize"); 95 final StatLong stat_rdr_activeEdges 96 = new StatLong("renderer.activeEdges"); 97 final StatLong stat_rdr_activeEdges_updates 98 = new StatLong("renderer.activeEdges.updates"); 99 final StatLong stat_rdr_activeEdges_adds 100 = new StatLong("renderer.activeEdges.adds"); 101 final StatLong stat_rdr_activeEdges_adds_high 102 = new StatLong("renderer.activeEdges.adds_high"); 103 final StatLong stat_rdr_crossings_updates 104 = new StatLong("renderer.crossings.updates"); 105 final StatLong stat_rdr_crossings_sorts 106 = new StatLong("renderer.crossings.sorts"); 107 final StatLong stat_rdr_crossings_bsearch 108 = new StatLong("renderer.crossings.bsearch"); 109 final StatLong stat_rdr_crossings_msorts 110 = new StatLong("renderer.crossings.msorts"); 111 // growable arrays 112 final StatLong stat_array_dasher_dasher 113 = new StatLong("array.dasher.dasher.d_float"); 114 final StatLong stat_array_dasher_firstSegmentsBuffer 115 = new StatLong("array.dasher.firstSegmentsBuffer.d_float"); 116 final StatLong stat_array_stroker_polystack_curves 117 = new StatLong("array.stroker.polystack.curves.d_float"); 118 final StatLong stat_array_stroker_polystack_curveTypes 119 = new StatLong("array.stroker.polystack.curveTypes.d_byte"); 120 final StatLong stat_array_marlincache_rowAAChunk 121 = new StatLong("array.marlincache.rowAAChunk.d_byte"); 122 final StatLong stat_array_marlincache_touchedTile 123 = new StatLong("array.marlincache.touchedTile.int"); 124 final StatLong stat_array_renderer_alphaline 125 = new StatLong("array.renderer.alphaline.int"); 126 final StatLong stat_array_renderer_crossings 127 = new StatLong("array.renderer.crossings.int"); 128 final StatLong stat_array_renderer_aux_crossings 129 = new StatLong("array.renderer.aux_crossings.int"); 130 final StatLong stat_array_renderer_edgeBuckets 131 = new StatLong("array.renderer.edgeBuckets.int"); 132 final StatLong stat_array_renderer_edgeBucketCounts 133 = new StatLong("array.renderer.edgeBucketCounts.int"); 134 final StatLong stat_array_renderer_edgePtrs 135 = new StatLong("array.renderer.edgePtrs.int"); 136 final StatLong stat_array_renderer_aux_edgePtrs 137 = new StatLong("array.renderer.aux_edgePtrs.int"); 138 // histograms 139 final Histogram hist_rdr_crossings 140 = new Histogram("renderer.crossings"); 141 final Histogram hist_rdr_crossings_ratio 142 = new Histogram("renderer.crossings.ratio"); 143 final Histogram hist_rdr_crossings_adds 144 = new Histogram("renderer.crossings.adds"); 145 final Histogram hist_rdr_crossings_msorts 146 = new Histogram("renderer.crossings.msorts"); 147 final Histogram hist_rdr_crossings_msorts_adds 148 = new Histogram("renderer.crossings.msorts.adds"); 149 final Histogram hist_tile_generator_alpha 150 = new Histogram("tile_generator.alpha"); 151 final Histogram hist_tile_generator_encoding 152 = new Histogram("tile_generator.encoding"); 153 final Histogram hist_tile_generator_encoding_dist 154 = new Histogram("tile_generator.encoding.dist"); 155 final Histogram hist_tile_generator_encoding_ratio 156 = new Histogram("tile_generator.encoding.ratio"); 157 final Histogram hist_tile_generator_encoding_runLen 158 = new Histogram("tile_generator.encoding.runLen"); 159 // all stats 160 final StatLong[] statistics = new StatLong[]{ 161 stat_cache_rowAA, 162 stat_cache_rowAAChunk, 163 stat_cache_tiles, 164 stat_rdr_poly_stack_types, 165 stat_rdr_poly_stack_curves, 166 stat_rdr_addLine, 167 stat_rdr_addLine_skip, 168 stat_rdr_curveBreak, 169 stat_rdr_curveBreak_dec, 170 stat_rdr_curveBreak_inc, 171 stat_rdr_quadBreak, 172 stat_rdr_quadBreak_dec, 173 stat_rdr_edges, 174 stat_rdr_edges_count, 175 stat_rdr_edges_resizes, 176 stat_rdr_activeEdges, 177 stat_rdr_activeEdges_updates, 178 stat_rdr_activeEdges_adds, 179 stat_rdr_activeEdges_adds_high, 180 stat_rdr_crossings_updates, 181 stat_rdr_crossings_sorts, 182 stat_rdr_crossings_bsearch, 183 stat_rdr_crossings_msorts, 184 hist_rdr_crossings, 185 hist_rdr_crossings_ratio, 186 hist_rdr_crossings_adds, 187 hist_rdr_crossings_msorts, 188 hist_rdr_crossings_msorts_adds, 189 hist_tile_generator_alpha, 190 hist_tile_generator_encoding, 191 hist_tile_generator_encoding_dist, 192 hist_tile_generator_encoding_ratio, 193 hist_tile_generator_encoding_runLen, 194 stat_array_dasher_dasher, 195 stat_array_dasher_firstSegmentsBuffer, 196 stat_array_stroker_polystack_curves, 197 stat_array_stroker_polystack_curveTypes, 198 stat_array_marlincache_rowAAChunk, 199 stat_array_marlincache_touchedTile, 200 stat_array_renderer_alphaline, 201 stat_array_renderer_crossings, 202 stat_array_renderer_aux_crossings, 203 stat_array_renderer_edgeBuckets, 204 stat_array_renderer_edgeBucketCounts, 205 stat_array_renderer_edgePtrs, 206 stat_array_renderer_aux_edgePtrs 207 }; 208 // monitors 209 final Monitor mon_pre_getAATileGenerator 210 = new Monitor("MarlinRenderingEngine.getAATileGenerator()"); 211 final Monitor mon_npi_currentSegment 212 = new Monitor("NormalizingPathIterator.currentSegment()"); 213 final Monitor mon_rdr_addLine 214 = new Monitor("Renderer.addLine()"); 215 final Monitor mon_rdr_endRendering 216 = new Monitor("Renderer.endRendering()"); 217 final Monitor mon_rdr_endRendering_Y 218 = new Monitor("Renderer._endRendering(Y)"); 219 final Monitor mon_rdr_copyAARow 220 = new Monitor("Renderer.copyAARow()"); 221 final Monitor mon_pipe_renderTiles 222 = new Monitor("AAShapePipe.renderTiles()"); 223 final Monitor mon_ptg_getAlpha 224 = new Monitor("MarlinTileGenerator.getAlpha()"); 225 final Monitor mon_debug 226 = new Monitor("DEBUG()"); 227 // all monitors 228 final Monitor[] monitors = new Monitor[]{ 229 mon_pre_getAATileGenerator, 230 mon_npi_currentSegment, 231 mon_rdr_addLine, 232 mon_rdr_endRendering, 233 mon_rdr_endRendering_Y, 234 mon_rdr_copyAARow, 235 mon_pipe_renderTiles, 236 mon_ptg_getAlpha, 237 mon_debug 238 }; 239 RendererStats()240 private RendererStats() { 241 super(); 242 243 AccessController.doPrivileged( 244 (PrivilegedAction<Void>) () -> { 245 final Thread hook = new Thread( 246 ThreadGroupUtils.getRootThreadGroup(), 247 new Runnable() { 248 @Override 249 public void run() { 250 dump(); 251 } 252 }, 253 "MarlinStatsHook" 254 ); 255 hook.setContextClassLoader(null); 256 Runtime.getRuntime().addShutdownHook(hook); 257 258 if (useDumpThread) { 259 final Timer statTimer = new Timer("RendererStats"); 260 statTimer.scheduleAtFixedRate(new TimerTask() { 261 @Override 262 public void run() { 263 dump(); 264 } 265 }, statDump, statDump); 266 } 267 return null; 268 } 269 ); 270 } 271 dump()272 void dump() { 273 if (doStats) { 274 ArrayCache.dumpStats(); 275 } 276 final RendererContext[] all = allContexts.toArray( 277 new RendererContext[allContexts.size()]); 278 for (RendererContext rdrCtx : all) { 279 logInfo("RendererContext: " + rdrCtx.name); 280 281 if (doMonitors) { 282 for (Monitor monitor : monitors) { 283 if (monitor.count != 0) { 284 logInfo(monitor.toString()); 285 } 286 } 287 // As getAATileGenerator percents: 288 final long total = mon_pre_getAATileGenerator.sum; 289 if (total != 0L) { 290 for (Monitor monitor : monitors) { 291 logInfo(monitor.name + " : " 292 + ((100d * monitor.sum) / total) + " %"); 293 } 294 } 295 if (doFlushMonitors) { 296 for (Monitor m : monitors) { 297 m.reset(); 298 } 299 } 300 } 301 302 if (doStats) { 303 for (StatLong stat : statistics) { 304 if (stat.count != 0) { 305 logInfo(stat.toString()); 306 stat.reset(); 307 } 308 } 309 // IntArrayCaches stats: 310 final RendererContext.ArrayCachesHolder holder 311 = rdrCtx.getArrayCachesHolder(); 312 313 logInfo("Array caches for thread: " + rdrCtx.name); 314 315 for (IntArrayCache cache : holder.intArrayCaches) { 316 cache.dumpStats(); 317 } 318 319 logInfo("Dirty Array caches for thread: " + rdrCtx.name); 320 321 for (IntArrayCache cache : holder.dirtyIntArrayCaches) { 322 cache.dumpStats(); 323 } 324 for (FloatArrayCache cache : holder.dirtyFloatArrayCaches) { 325 cache.dumpStats(); 326 } 327 for (ByteArrayCache cache : holder.dirtyByteArrayCaches) { 328 cache.dumpStats(); 329 } 330 } 331 } 332 } 333 } 334