diff --git a/pom.xml b/pom.xml index a1bd811..219323b 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ org.marlin marlin jar - 0.9.4.6-Unsafe + 0.9.4.7-Unsafe Marlin software rasterizer https://github.com/bourgesl/marlin-renderer diff --git a/src/main/java/sun/java2d/marlin/BBoxAATileGenerator.java b/src/main/java/sun/java2d/marlin/BBoxAATileGenerator.java new file mode 100644 index 0000000..e029d61 --- /dev/null +++ b/src/main/java/sun/java2d/marlin/BBoxAATileGenerator.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, JetBrains s.r.o.. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.java2d.marlin; + +import sun.java2d.pipe.AATileGenerator; + +class BBoxAATileGenerator implements AATileGenerator, MarlinConst { + + protected static final boolean DISABLE_BLEND = false; + + protected final Renderer renderer; + protected final MarlinCache cache; + + // per-thread renderer stats + final RendererStats rdrStats; + + BBoxAATileGenerator(final RendererStats stats, final Renderer r, + final MarlinCache cache) + { + this.rdrStats = stats; + this.renderer = r; + this.cache = cache; + } + + /** + * Disposes this tile generator: + * clean up before reusing this instance + */ + @Override + public void dispose() { + if (DO_MONITORS) { + // called from AAShapePipe.renderTiles() (render tiles end): + rdrStats.mon_pipe_renderTiles.stop(); + } + // dispose renderer and recycle the RendererContext instance: + renderer.dispose(); + } + + public final void getBbox(int[] bbox) { + bbox[0] = cache.bboxX0; + bbox[1] = cache.bboxY0; + bbox[2] = cache.bboxX1; + bbox[3] = cache.bboxY1; + } + + /** + * Gets the width of the tiles that the generator batches output into. + * @return the width of the standard alpha tile + */ + @Override + public final int getTileWidth() { + if (DO_MONITORS) { + // called from AAShapePipe.renderTiles() (render tiles start): + rdrStats.mon_pipe_renderTiles.start(); + } + return TILE_W; + } + + /** + * Gets the height of the tiles that the generator batches output into. + * @return the height of the standard alpha tile + */ + @Override + public final int getTileHeight() { + return TILE_H; + } + + /** + * Gets the typical alpha value that will characterize the current + * tile. + * The answer may be 0x00 to indicate that the current tile has + * no coverage in any of its pixels, or it may be 0xff to indicate + * that the current tile is completely covered by the path, or any + * other value to indicate non-trivial coverage cases. + * @return 0x00 for no coverage, 0xff for total coverage, or any other + * value for partial coverage of the tile + */ + @Override + public int getTypicalAlpha() { + if (DISABLE_BLEND) { + // always return empty tiles to disable blending operations + return 0x00; + } + + // Note: if we have a filled rectangle that doesn't end on a tile + // border, we could still return 0xff, even though al!=maxTileAlphaSum + // This is because if we return 0xff, our users will fill a rectangle + // starting at x,y that has width = Math.min(TILE_SIZE, bboxX1-x), + // and height min(TILE_SIZE,bboxY1-y), which is what should happen. + // However, to support this, we would have to use 2 Math.min's + // and 2 multiplications per tile, instead of just 2 multiplications + // to compute maxTileAlphaSum. The savings offered would probably + // not be worth it, considering how rare this case is. + // Note: I have not tested this, so in the future if it is determined + // that it is worth it, it should be implemented. Perhaps this method's + // interface should be changed to take arguments the width and height + // of the current tile. This would eliminate the 2 Math.min calls that + // would be needed here, since our caller needs to compute these 2 + // values anyway. + // this default implementation returns FULL tiles: + final int alpha = 0xff; + if (DO_STATS) { + rdrStats.hist_tile_generator_alpha.add(alpha); + } + return alpha; + } + + /** + * Skips the current tile and moves on to the next tile. + * Either this method, or the getAlpha() method should be called + * once per tile, but not both. + */ + @Override + public void nextTile() { + // this default implementation does nothing + } + + /** + * Gets the alpha coverage values for the current tile. + * Either this method, or the nextTile() method should be called + * once per tile, but not both. + */ + @Override + public void getAlpha(final byte[] tile, final int offset, + final int rowstride) + { + // this default implementation does nothing + } +} diff --git a/src/main/java/sun/java2d/marlin/DMarlinRenderingEngine.java b/src/main/java/sun/java2d/marlin/DMarlinRenderingEngine.java index a42e474..02daae9 100644 --- a/src/main/java/sun/java2d/marlin/DMarlinRenderingEngine.java +++ b/src/main/java/sun/java2d/marlin/DMarlinRenderingEngine.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -909,7 +909,7 @@ public AATileGenerator getAATileGenerator(Shape s, boolean normalize, int[] bbox) { - MarlinTileGenerator ptg = null; + BBoxAATileGenerator ptg = null; Renderer r = null; final RendererContext rdrCtx = getRendererContext(); @@ -983,11 +983,10 @@ public AATileGenerator getAATileGenerator(Shape s, strokeTo(rdrCtx, s, _at, bs, thin, norm, true, r); } - if (r.endRendering()) { - ptg = rdrCtx.ptg.init(); + if ((ptg = r.endRendering()) != null) { ptg.getBbox(bbox); // note: do not returnRendererContext(rdrCtx) - // as it will be called later by MarlinTileGenerator.dispose() + // as it will be called later by BBoxAATileGenerator.dispose() r = null; } } finally { @@ -1032,7 +1031,7 @@ public AATileGenerator getAATileGenerator(double x, double y, ldx1 = ldy1 = ldx2 = ldy2 = 0.0d; } - MarlinTileGenerator ptg = null; + BBoxAATileGenerator ptg = null; Renderer r = null; final RendererContext rdrCtx = getRendererContext(); @@ -1062,11 +1061,10 @@ public AATileGenerator getAATileGenerator(double x, double y, } r.pathDone(); - if (r.endRendering()) { - ptg = rdrCtx.ptg.init(); + if ((ptg = r.endRendering()) != null) { ptg.getBbox(bbox); // note: do not returnRendererContext(rdrCtx) - // as it will be called later by MarlinTileGenerator.dispose() + // as it will be called later by BBoxAATileGenerator.dispose() r = null; } } finally { diff --git a/src/main/java/sun/java2d/marlin/MarlinCache.java b/src/main/java/sun/java2d/marlin/MarlinCache.java index 1dc3d46..7ae075a 100644 --- a/src/main/java/sun/java2d/marlin/MarlinCache.java +++ b/src/main/java/sun/java2d/marlin/MarlinCache.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -120,13 +120,17 @@ public final class MarlinCache implements MarlinConst { tileMax = Integer.MIN_VALUE; } - void init(int minx, int miny, int maxx, int maxy) - { + void initBBox(int minx, int miny, int maxx, int maxy) { // assert maxy >= miny && maxx >= minx; bboxX0 = minx; bboxY0 = miny; bboxX1 = maxx; bboxY1 = maxy; + } + + void init(int minx, int miny, int maxx, int maxy) + { + initBBox(minx, miny, maxx, maxy); final int width = (maxx - minx); diff --git a/src/main/java/sun/java2d/marlin/MarlinTileGenerator.java b/src/main/java/sun/java2d/marlin/MarlinTileGenerator.java index 270ba2c..adcc5e0 100644 --- a/src/main/java/sun/java2d/marlin/MarlinTileGenerator.java +++ b/src/main/java/sun/java2d/marlin/MarlinTileGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,9 +29,7 @@ import sun.java2d.pipe.AATileGenerator; import sun.misc.Unsafe; -final class MarlinTileGenerator implements AATileGenerator, MarlinConst { - - private static final boolean DISABLE_BLEND = false; +final class MarlinTileGenerator extends BBoxAATileGenerator { private static final int MAX_TILE_ALPHA_SUM = TILE_W * TILE_H * MAX_AA_ALPHA; @@ -52,19 +50,12 @@ final class MarlinTileGenerator implements AATileGenerator, MarlinConst { } } - private final Renderer renderer; - private final MarlinCache cache; private int x, y; - // per-thread renderer stats - final RendererStats rdrStats; - MarlinTileGenerator(final RendererStats stats, final Renderer r, final MarlinCache cache) { - this.rdrStats = stats; - this.renderer = r; - this.cache = cache; + super(stats, r, cache); } MarlinTileGenerator init() { @@ -80,43 +71,10 @@ MarlinTileGenerator init() { */ @Override public void dispose() { - if (DO_MONITORS) { - // called from AAShapePipe.renderTiles() (render tiles end): - rdrStats.mon_pipe_renderTiles.stop(); - } // dispose cache: cache.dispose(); // dispose renderer and recycle the RendererContext instance: - renderer.dispose(); - } - - void getBbox(int[] bbox) { - bbox[0] = cache.bboxX0; - bbox[1] = cache.bboxY0; - bbox[2] = cache.bboxX1; - bbox[3] = cache.bboxY1; - } - - /** - * Gets the width of the tiles that the generator batches output into. - * @return the width of the standard alpha tile - */ - @Override - public int getTileWidth() { - if (DO_MONITORS) { - // called from AAShapePipe.renderTiles() (render tiles start): - rdrStats.mon_pipe_renderTiles.start(); - } - return TILE_W; - } - - /** - * Gets the height of the tiles that the generator batches output into. - * @return the height of the standard alpha tile - */ - @Override - public int getTileHeight() { - return TILE_H; + super.dispose(); } /** diff --git a/src/main/java/sun/java2d/marlin/Renderer.java b/src/main/java/sun/java2d/marlin/Renderer.java index 24ec0b6..56fa857 100644 --- a/src/main/java/sun/java2d/marlin/Renderer.java +++ b/src/main/java/sun/java2d/marlin/Renderer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,9 @@ final class Renderer implements DPathConsumer2D, MarlinConst { + static final boolean TRACE_SLOPE_0 = DO_STATS && false; + static final boolean TRACE_RECT = DO_STATS && false; + static final boolean DISABLE_RENDER = MarlinProperties.isSkipRenderer(); static final boolean ENABLE_BLOCK_FLAGS = MarlinProperties.isUseTileFlags(); @@ -136,6 +139,7 @@ final class Renderer implements DPathConsumer2D, MarlinConst { // sublist in the segment lists (the portion of the list that contains // all the segments that cross the next scan line). private int edgeCount; + private int edgeVertCount; private int[] edgePtrs; // auxiliary storage for edge pointers (merge sort) private int[] aux_edgePtrs; @@ -366,22 +370,58 @@ private void addLine(double x1, double y1, double x2, double y2) { edgeMaxY = lastCrossing; } - final double slope = (x1 - x2) / (y1 - y2); + if (DO_STATS) { + rdrCtx.stats.stat_rdr_addLine_slope_length.add( + (lastCrossing - firstCrossing + SUBPIXEL_MASK_Y) >> SUBPIXEL_LG_POSITIONS_Y + ); + } + if (TRACE_SLOPE_0 && (x1 != x2)) { + // TODO: check same end point x (more precisely using integer maths) + final int firstX = FloatMath.ceil_int(x1 - 0.5); + final int lastX = FloatMath.ceil_int(x2 - 0.5); + if (firstX == lastX) { + rdrCtx.stats.stat_rdr_addLine_slope_small.add( + (lastCrossing - firstCrossing + SUBPIXEL_MASK_Y) >> SUBPIXEL_LG_POSITIONS_Y + ); + // TODO: force case: (slope == 0.0) => use purely vertical edge + } + } + + final double slope; + + if (x1 == x2) { + slope = 0.0; + edgeVertCount++; + if (DO_STATS) { + rdrCtx.stats.stat_rdr_addLine_slope_0.add( + (lastCrossing - firstCrossing + SUBPIXEL_MASK_Y) >> SUBPIXEL_LG_POSITIONS_Y + ); + } - if (slope >= 0.0d) { // <==> x1 < x2 if (x1 < edgeMinX) { edgeMinX = x1; } - if (x2 > edgeMaxX) { - edgeMaxX = x2; - } - } else { - if (x2 < edgeMinX) { - edgeMinX = x2; - } if (x1 > edgeMaxX) { edgeMaxX = x1; } + } else { + slope = (x1 - x2) / (y1 - y2); + + if (slope >= 0.0d) { // <==> x1 < x2 + if (x1 < edgeMinX) { + edgeMinX = x1; + } + if (x2 > edgeMaxX) { + edgeMaxX = x2; + } + } else { + if (x2 < edgeMinX) { + edgeMinX = x2; + } + if (x1 > edgeMaxX) { + edgeMaxX = x1; + } + } } // local variables for performance: @@ -595,6 +635,7 @@ Renderer init(final int pix_boundsX, final int pix_boundsY, // reset used mark: edgeCount = 0; + edgeVertCount = 0; activeEdgeMaxUsed = 0; edges.used = 0; @@ -1430,12 +1471,12 @@ private void _endRendering(final int ymin, final int ymax) { } } - boolean endRendering() { - if (DO_MONITORS) { - rdrCtx.stats.mon_rdr_endRendering.start(); - } + BBoxAATileGenerator endRendering() { if (edgeMinY == Integer.MAX_VALUE) { - return false; // undefined edges bounds + if (DO_STATS) { + rdrCtx.stats.stat_rdr_shape_skip.add(1); + } + return null; // undefined edges bounds } // bounds as half-open intervals @@ -1458,7 +1499,13 @@ boolean endRendering() { // test clipping for shapes out of bounds if ((spminX >= spmaxX) || (spminY >= spmaxY)) { - return false; + if (DO_STATS) { + rdrCtx.stats.stat_rdr_shape_skip.add(1); + } + return null; + } + if (DO_MONITORS) { + rdrCtx.stats.mon_rdr_endRendering.start(); } // half open intervals @@ -1471,20 +1518,48 @@ boolean endRendering() { // exclusive: final int pmaxY = (spmaxY + SUBPIXEL_MASK_Y) >> SUBPIXEL_LG_POSITIONS_Y; - // store BBox to answer ptg.getBBox(): - this.cache.init(pminX, pminY, pmaxX, pmaxY); + // bbox area in pixels: + if (DO_STATS) { + rdrCtx.stats.stat_rdr_iter.add(spmaxY - spminY); + rdrCtx.stats.stat_rdr_shape_area.add(((long)(pmaxX - pminX)) * (pmaxY - pminY)); + } - // Heuristics for using block flags: - if (ENABLE_BLOCK_FLAGS) { - enableBlkFlags = this.cache.useRLE; - prevUseBlkFlags = enableBlkFlags && !ENABLE_BLOCK_FLAGS_HEURISTICS; + if (edgeVertCount != 0) { + final int totalEdgesCount = edges.used / SIZEOF_EDGE_BYTES; - if (enableBlkFlags) { - // ensure blockFlags array is large enough: - // note: +2 to ensure enough space left at end - final int blkLen = ((pmaxX - pminX) >> BLOCK_SIZE_LG) + 2; - if (blkLen > INITIAL_ARRAY) { - blkFlags = blkFlags_ref.getArray(blkLen); + // check flat ? + if (totalEdgesCount == edgeVertCount) { + // all edges are constant (vert or horiz): + if (DO_STATS) { + rdrCtx.stats.stat_rdr_edges_constant.add(totalEdgesCount); + rdrCtx.stats.stat_rdr_shape_area_constant.add(((long)(pmaxX - pminX)) * (pmaxY - pminY)); + } + + // check rect ? + if (totalEdgesCount == 2) { + if (TRACE_RECT) { + MarlinUtils.logInfo("sp rect = [" + spminX + " ... " + spmaxX + + "[ [" + spminY + " ... " + spmaxY + "["); + } + + final int subpixelMask = (spminX & SUBPIXEL_MASK_X) | (spmaxX & SUBPIXEL_MASK_X) + | (spminY & SUBPIXEL_MASK_Y) | (spmaxY & SUBPIXEL_MASK_Y); + + if (subpixelMask == 0) { + // rectangle aligned on pixel grid: + if (TRACE_RECT) { + MarlinUtils.logInfo("FULL RECT: pXY = [" + pminX + " ... " + pmaxX + + "[ [" + pminY + " ... " + pmaxY + "["); + } + if (DO_STATS) { + rdrCtx.stats.stat_rdr_iter_skip.add(spmaxY - spminY); + } + // store BBox to answer ptg.getBBox(): + this.cache.initBBox(pminX, pminY, pmaxX, pmaxY); + + // skip renderer entirely using BBoxAATileGenerator: + return rdrCtx.ftg; + } } } } @@ -1503,10 +1578,28 @@ boolean endRendering() { if (DO_LOG_BOUNDS) { MarlinUtils.logInfo("pXY = [" + pminX + " ... " + pmaxX - + "[ [" + pminY + " ... " + pmaxY + "["); + + "[ [" + pminY + " ... " + pmaxY + "["); MarlinUtils.logInfo("bbox_spXY = [" + bbox_spminX + " ... " - + bbox_spmaxX + "[ [" + bbox_spminY + " ... " - + bbox_spmaxY + "["); + + bbox_spmaxX + "[ [" + bbox_spminY + " ... " + + bbox_spmaxY + "["); + } + + // store BBox to answer ptg.getBBox(): + this.cache.init(pminX, pminY, pmaxX, pmaxY); + + // Heuristics for using block flags: + if (ENABLE_BLOCK_FLAGS) { + enableBlkFlags = this.cache.useRLE; + prevUseBlkFlags = enableBlkFlags && !ENABLE_BLOCK_FLAGS_HEURISTICS; + + if (enableBlkFlags) { + // ensure blockFlags array is large enough: + // note: +2 to ensure enough space left at end + final int blkLen = ((pmaxX - pminX) >> BLOCK_SIZE_LG) + 2; + if (blkLen > INITIAL_ARRAY) { + blkFlags = blkFlags_ref.getArray(blkLen); + } + } } // Prepare alpha line: @@ -1524,7 +1617,7 @@ boolean endRendering() { // process first tile line: endRendering(pminY); - return true; + return rdrCtx.ptg.init(); } private int bbox_spminX, bbox_spmaxX, bbox_spminY, bbox_spmaxY; diff --git a/src/main/java/sun/java2d/marlin/RendererContext.java b/src/main/java/sun/java2d/marlin/RendererContext.java index d599c7d..69f9768 100644 --- a/src/main/java/sun/java2d/marlin/RendererContext.java +++ b/src/main/java/sun/java2d/marlin/RendererContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,6 +75,7 @@ static RendererContext createContext() { final PathSimplifier pathSimplifier = new PathSimplifier(); final Dasher dasher; final MarlinTileGenerator ptg; + final BBoxAATileGenerator ftg; final MarlinCache cache; // flag indicating the shape is stroked (1) or filled (0) int stroking = 0; @@ -149,6 +150,8 @@ static RendererContext createContext() { // Renderer: cache = new MarlinCache(this); renderer = new Renderer(this); // needs MarlinCache from rdrCtx.cache + + ftg = new BBoxAATileGenerator(stats, renderer, cache); // full tiles ptg = new MarlinTileGenerator(stats, renderer, cache); stroker = new Stroker(this); diff --git a/src/main/java/sun/java2d/marlin/RendererStats.java b/src/main/java/sun/java2d/marlin/RendererStats.java index 81e0111..ad01ad9 100644 --- a/src/main/java/sun/java2d/marlin/RendererStats.java +++ b/src/main/java/sun/java2d/marlin/RendererStats.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,6 +78,12 @@ public static ArraySortDataCollection getADC() { = new StatLong("renderer.addLine"); final StatLong stat_rdr_addLine_skip = new StatLong("renderer.addLine.skip"); + final StatLong stat_rdr_addLine_slope_length + = new StatLong("renderer.addLine.slope.len"); + final StatLong stat_rdr_addLine_slope_0 + = new StatLong("renderer.addLine.slope.zero"); + final StatLong stat_rdr_addLine_slope_small + = new StatLong("renderer.addLine.slope.small"); final StatLong stat_rdr_curveBreak = new StatLong("renderer.curveBreakIntoLinesAndAdd"); final StatLong stat_rdr_curveBreak_dec @@ -88,6 +94,14 @@ public static ArraySortDataCollection getADC() { = new StatLong("renderer.quadBreakIntoLinesAndAdd"); final StatLong stat_rdr_quadBreak_dec = new StatLong("renderer.quadBreakIntoLinesAndAdd.dec"); + final StatLong stat_rdr_shape_skip + = new StatLong("renderer.shape.skip"); + final StatLong stat_rdr_shape_area + = new StatLong("renderer.shape.area"); + final StatLong stat_rdr_shape_area_constant + = new StatLong("renderer.shape.area.constant"); + final StatLong stat_rdr_edges_constant + = new StatLong("renderer.edges.constant"); final StatLong stat_rdr_edges = new StatLong("renderer.edges"); final StatLong stat_rdr_edges_count @@ -112,6 +126,10 @@ public static ArraySortDataCollection getADC() { = new StatLong("renderer.crossings.msorts"); final StatLong stat_rdr_crossings_dpqs = new StatLong("renderer.crossings.dpqs"); + final StatLong stat_rdr_iter + = new StatLong("renderer.iter"); + final StatLong stat_rdr_iter_skip + = new StatLong("renderer.iter.skip"); final StatLong stat_str_polystack_curves = new StatLong("stroker.polystack.curves"); final StatLong stat_str_polystack_types @@ -191,11 +209,18 @@ public static ArraySortDataCollection getADC() { stat_cache_tiles, stat_rdr_addLine, stat_rdr_addLine_skip, + stat_rdr_addLine_slope_length, + stat_rdr_addLine_slope_0, + stat_rdr_addLine_slope_small, stat_rdr_curveBreak, stat_rdr_curveBreak_dec, stat_rdr_curveBreak_inc, stat_rdr_quadBreak, stat_rdr_quadBreak_dec, + stat_rdr_shape_skip, + stat_rdr_shape_area, + stat_rdr_shape_area_constant, + stat_rdr_edges_constant, stat_rdr_edges, stat_rdr_edges_count, stat_rdr_edges_resizes, @@ -208,6 +233,8 @@ public static ArraySortDataCollection getADC() { stat_rdr_crossings_bsearch, stat_rdr_crossings_msorts, stat_rdr_crossings_dpqs, + stat_rdr_iter, + stat_rdr_iter_skip, stat_str_polystack_types, stat_str_polystack_curves, stat_cpd_polystack_curves, @@ -400,6 +427,7 @@ public void run() { statTimer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { + logInfo("--- RendererStats dump at: " + new java.util.Date() + " ---"); dump(); } }, DUMP_INTERVAL, DUMP_INTERVAL);