Path: blob/master/src/java.desktop/share/classes/sun/java2d/marlin/RendererStats.java
41159 views
/*1* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.java2d.marlin;2627import java.security.AccessController;28import java.security.PrivilegedAction;29import java.util.Timer;30import java.util.TimerTask;31import java.util.concurrent.ConcurrentLinkedQueue;32import jdk.internal.ref.CleanerFactory;33import sun.java2d.marlin.ArrayCacheConst.CacheStats;34import static sun.java2d.marlin.MarlinUtils.logInfo;35import sun.java2d.marlin.stats.Histogram;36import sun.java2d.marlin.stats.Monitor;37import sun.java2d.marlin.stats.StatLong;3839/**40* This class gathers global rendering statistics for debugging purposes only41*/42public final class RendererStats implements MarlinConst {4344static RendererStats createInstance(final Object parent, final String name)45{46final RendererStats stats = new RendererStats(name);4748// Keep a strong reference to dump it later:49RendererStatsHolder.getInstance().add(parent, stats);5051return stats;52}5354public static void dumpStats() {55RendererStatsHolder.dumpStats();56}5758// context name (debugging purposes)59final String name;60// stats61final StatLong stat_cache_rowAA62= new StatLong("cache.rowAA");63final StatLong stat_cache_rowAAChunk64= new StatLong("cache.rowAAChunk");65final StatLong stat_cache_tiles66= new StatLong("cache.tiles");67final StatLong stat_rdr_addLine68= new StatLong("renderer.addLine");69final StatLong stat_rdr_addLine_skip70= new StatLong("renderer.addLine.skip");71final StatLong stat_rdr_curveBreak72= new StatLong("renderer.curveBreakIntoLinesAndAdd");73final StatLong stat_rdr_curveBreak_dec74= new StatLong("renderer.curveBreakIntoLinesAndAdd.dec");75final StatLong stat_rdr_curveBreak_inc76= new StatLong("renderer.curveBreakIntoLinesAndAdd.inc");77final StatLong stat_rdr_quadBreak78= new StatLong("renderer.quadBreakIntoLinesAndAdd");79final StatLong stat_rdr_quadBreak_dec80= new StatLong("renderer.quadBreakIntoLinesAndAdd.dec");81final StatLong stat_rdr_edges82= new StatLong("renderer.edges");83final StatLong stat_rdr_edges_count84= new StatLong("renderer.edges.count");85final StatLong stat_rdr_edges_resizes86= new StatLong("renderer.edges.resize");87final StatLong stat_rdr_activeEdges88= new StatLong("renderer.activeEdges");89final StatLong stat_rdr_activeEdges_updates90= new StatLong("renderer.activeEdges.updates");91final StatLong stat_rdr_activeEdges_adds92= new StatLong("renderer.activeEdges.adds");93final StatLong stat_rdr_activeEdges_adds_high94= new StatLong("renderer.activeEdges.adds_high");95final StatLong stat_rdr_crossings_updates96= new StatLong("renderer.crossings.updates");97final StatLong stat_rdr_crossings_sorts98= new StatLong("renderer.crossings.sorts");99final StatLong stat_rdr_crossings_bsearch100= new StatLong("renderer.crossings.bsearch");101final StatLong stat_rdr_crossings_msorts102= new StatLong("renderer.crossings.msorts");103final StatLong stat_str_polystack_curves104= new StatLong("stroker.polystack.curves");105final StatLong stat_str_polystack_types106= new StatLong("stroker.polystack.types");107final StatLong stat_cpd_polystack_curves108= new StatLong("closedPathDetector.polystack.curves");109final StatLong stat_cpd_polystack_types110= new StatLong("closedPathDetector.polystack.types");111final StatLong stat_pcf_idxstack_indices112= new StatLong("pathClipFilter.stack.indices");113// growable arrays114final StatLong stat_array_dasher_dasher115= new StatLong("array.dasher.dasher.d_float");116final StatLong stat_array_dasher_firstSegmentsBuffer117= new StatLong("array.dasher.firstSegmentsBuffer.d_float");118final StatLong stat_array_marlincache_rowAAChunk119= new StatLong("array.marlincache.rowAAChunk.resize");120final StatLong stat_array_marlincache_touchedTile121= new StatLong("array.marlincache.touchedTile.int");122final StatLong stat_array_renderer_alphaline123= new StatLong("array.renderer.alphaline.int");124final StatLong stat_array_renderer_crossings125= new StatLong("array.renderer.crossings.int");126final StatLong stat_array_renderer_aux_crossings127= new StatLong("array.renderer.aux_crossings.int");128final StatLong stat_array_renderer_edgeBuckets129= new StatLong("array.renderer.edgeBuckets.int");130final StatLong stat_array_renderer_edgeBucketCounts131= new StatLong("array.renderer.edgeBucketCounts.int");132final StatLong stat_array_renderer_edgePtrs133= new StatLong("array.renderer.edgePtrs.int");134final StatLong stat_array_renderer_aux_edgePtrs135= new StatLong("array.renderer.aux_edgePtrs.int");136final StatLong stat_array_str_polystack_curves137= new StatLong("array.stroker.polystack.curves.d_float");138final StatLong stat_array_str_polystack_types139= new StatLong("array.stroker.polystack.curveTypes.d_byte");140final StatLong stat_array_cpd_polystack_curves141= new StatLong("array.closedPathDetector.polystack.curves.d_float");142final StatLong stat_array_cpd_polystack_types143= new StatLong("array.closedPathDetector.polystack.curveTypes.d_byte");144final StatLong stat_array_pcf_idxstack_indices145= new StatLong("array.pathClipFilter.stack.indices.d_int");146// histograms147final Histogram hist_rdr_edges_count148= new Histogram("renderer.edges.count");149final Histogram hist_rdr_crossings150= new Histogram("renderer.crossings");151final Histogram hist_rdr_crossings_ratio152= new Histogram("renderer.crossings.ratio");153final Histogram hist_rdr_crossings_adds154= new Histogram("renderer.crossings.adds");155final Histogram hist_rdr_crossings_msorts156= new Histogram("renderer.crossings.msorts");157final Histogram hist_rdr_crossings_msorts_adds158= new Histogram("renderer.crossings.msorts.adds");159final Histogram hist_str_polystack_curves160= new Histogram("stroker.polystack.curves");161final Histogram hist_tile_generator_alpha162= new Histogram("tile_generator.alpha");163final Histogram hist_tile_generator_encoding164= new Histogram("tile_generator.encoding");165final Histogram hist_tile_generator_encoding_dist166= new Histogram("tile_generator.encoding.dist");167final Histogram hist_tile_generator_encoding_ratio168= new Histogram("tile_generator.encoding.ratio");169final Histogram hist_tile_generator_encoding_runLen170= new Histogram("tile_generator.encoding.runLen");171final Histogram hist_cpd_polystack_curves172= new Histogram("closedPathDetector.polystack.curves");173final Histogram hist_pcf_idxstack_indices174= new Histogram("pathClipFilter.stack.indices");175// all stats176final StatLong[] statistics = new StatLong[]{177stat_cache_rowAA,178stat_cache_rowAAChunk,179stat_cache_tiles,180stat_rdr_addLine,181stat_rdr_addLine_skip,182stat_rdr_curveBreak,183stat_rdr_curveBreak_dec,184stat_rdr_curveBreak_inc,185stat_rdr_quadBreak,186stat_rdr_quadBreak_dec,187stat_rdr_edges,188stat_rdr_edges_count,189stat_rdr_edges_resizes,190stat_rdr_activeEdges,191stat_rdr_activeEdges_updates,192stat_rdr_activeEdges_adds,193stat_rdr_activeEdges_adds_high,194stat_rdr_crossings_updates,195stat_rdr_crossings_sorts,196stat_rdr_crossings_bsearch,197stat_rdr_crossings_msorts,198stat_str_polystack_types,199stat_str_polystack_curves,200stat_cpd_polystack_curves,201stat_cpd_polystack_types,202stat_pcf_idxstack_indices,203hist_rdr_edges_count,204hist_rdr_crossings,205hist_rdr_crossings_ratio,206hist_rdr_crossings_adds,207hist_rdr_crossings_msorts,208hist_rdr_crossings_msorts_adds,209hist_tile_generator_alpha,210hist_tile_generator_encoding,211hist_tile_generator_encoding_dist,212hist_tile_generator_encoding_ratio,213hist_tile_generator_encoding_runLen,214hist_str_polystack_curves,215hist_cpd_polystack_curves,216hist_pcf_idxstack_indices,217stat_array_dasher_dasher,218stat_array_dasher_firstSegmentsBuffer,219stat_array_marlincache_rowAAChunk,220stat_array_marlincache_touchedTile,221stat_array_renderer_alphaline,222stat_array_renderer_crossings,223stat_array_renderer_aux_crossings,224stat_array_renderer_edgeBuckets,225stat_array_renderer_edgeBucketCounts,226stat_array_renderer_edgePtrs,227stat_array_renderer_aux_edgePtrs,228stat_array_str_polystack_curves,229stat_array_str_polystack_types,230stat_array_cpd_polystack_curves,231stat_array_cpd_polystack_types,232stat_array_pcf_idxstack_indices233};234// monitors235final Monitor mon_pre_getAATileGenerator236= new Monitor("MarlinRenderingEngine.getAATileGenerator()");237final Monitor mon_rdr_addLine238= new Monitor("Renderer.addLine()");239final Monitor mon_rdr_endRendering240= new Monitor("Renderer.endRendering()");241final Monitor mon_rdr_endRendering_Y242= new Monitor("Renderer._endRendering(Y)");243final Monitor mon_rdr_copyAARow244= new Monitor("Renderer.copyAARow()");245final Monitor mon_pipe_renderTiles246= new Monitor("AAShapePipe.renderTiles()");247final Monitor mon_ptg_getAlpha248= new Monitor("MarlinTileGenerator.getAlpha()");249final Monitor mon_debug250= new Monitor("DEBUG()");251// all monitors252final Monitor[] monitors = new Monitor[]{253mon_pre_getAATileGenerator,254mon_rdr_addLine,255mon_rdr_endRendering,256mon_rdr_endRendering_Y,257mon_rdr_copyAARow,258mon_pipe_renderTiles,259mon_ptg_getAlpha,260mon_debug261};262// offheap stats263long totalOffHeapInitial = 0L;264// live accumulator265long totalOffHeap = 0L;266long totalOffHeapMax = 0L;267// cache stats268CacheStats[] cacheStats = null;269270private RendererStats(final String name) {271this.name = name;272}273274void dump() {275logInfo("RendererContext: " + name);276277if (DO_MONITORS) {278for (Monitor monitor : monitors) {279if (monitor.count != 0) {280logInfo(monitor.toString());281}282}283// As getAATileGenerator percents:284final long total = mon_pre_getAATileGenerator.sum;285if (total != 0L) {286for (Monitor monitor : monitors) {287logInfo(monitor.name + " : "288+ ((100d * monitor.sum) / total) + " %");289}290}291if (DO_FLUSH_MONITORS) {292for (Monitor m : monitors) {293m.reset();294}295}296}297298if (DO_STATS) {299for (StatLong stat : statistics) {300if (stat.count != 0) {301logInfo(stat.toString());302if (DO_FLUSH_STATS) {303stat.reset();304}305}306}307308logInfo("OffHeap footprint: initial: " + totalOffHeapInitial309+ " bytes - max: " + totalOffHeapMax + " bytes");310if (DO_FLUSH_STATS) {311totalOffHeapMax = 0L;312}313314logInfo("Array caches for RendererContext: " + name);315316long totalInitialBytes = totalOffHeapInitial;317long totalCacheBytes = 0L;318319if (cacheStats != null) {320for (CacheStats stat : cacheStats) {321totalCacheBytes += stat.dumpStats();322totalInitialBytes += stat.getTotalInitialBytes();323if (DO_FLUSH_STATS) {324stat.reset();325}326}327}328logInfo("Heap footprint: initial: " + totalInitialBytes329+ " bytes - cache: " + totalCacheBytes + " bytes");330}331}332333static final class RendererStatsHolder {334335// singleton336private static volatile RendererStatsHolder SINGLETON = null;337338static synchronized RendererStatsHolder getInstance() {339if (SINGLETON == null) {340SINGLETON = new RendererStatsHolder();341}342return SINGLETON;343}344345static void dumpStats() {346if (SINGLETON != null) {347SINGLETON.dump();348}349}350351/* RendererStats collection as hard references352(only used for debugging purposes) */353private final ConcurrentLinkedQueue<RendererStats> allStats354= new ConcurrentLinkedQueue<RendererStats>();355356@SuppressWarnings("removal")357private RendererStatsHolder() {358AccessController.doPrivileged(359(PrivilegedAction<Void>) () -> {360final Thread hook = new Thread(361MarlinUtils.getRootThreadGroup(),362new Runnable() {363@Override364public void run() {365dump();366}367},368"MarlinStatsHook"369);370hook.setContextClassLoader(null);371Runtime.getRuntime().addShutdownHook(hook);372373if (USE_DUMP_THREAD) {374final Timer statTimer = new Timer("RendererStats");375statTimer.scheduleAtFixedRate(new TimerTask() {376@Override377public void run() {378dump();379}380}, DUMP_INTERVAL, DUMP_INTERVAL);381}382return null;383}384);385}386387void add(final Object parent, final RendererStats stats) {388allStats.add(stats);389390// Register a cleaning function to ensure removing dead entries:391CleanerFactory.cleaner().register(parent, () -> remove(stats));392}393394void remove(final RendererStats stats) {395stats.dump(); // dump anyway396allStats.remove(stats);397}398399void dump() {400for (RendererStats stats : allStats) {401stats.dump();402}403}404}405}406407408