001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.osm.visitor.paint; 003 004import java.io.PrintStream; 005import java.util.List; 006import java.util.function.Supplier; 007 008import org.openstreetmap.josm.Main; 009import org.openstreetmap.josm.data.osm.visitor.paint.StyledMapRenderer.StyleRecord; 010import org.openstreetmap.josm.gui.mappaint.mapcss.Selector; 011import org.openstreetmap.josm.tools.Utils; 012 013/** 014 * This class is notified of the various stages of a render pass. 015 * 016 * @author Michael Zangl 017 * @since 10697 018 */ 019public class RenderBenchmarkCollector { 020 /** 021 * Notified when the renderer method starts preparing the data 022 * @param circum The current circum of the view. 023 */ 024 public void renderStart(double circum) { 025 // nop 026 } 027 028 /** 029 * Notified when the renderer method starts sorting the styles 030 * @return <code>true</code> if the renderer should continue to render 031 */ 032 public boolean renderSort() { 033 // nop 034 return true; 035 } 036 037 /** 038 * Notified when the renderer method starts drawing 039 * @param allStyleElems All the elements that are painted. 040 * @return <code>true</code> if the renderer should continue to render 041 */ 042 public boolean renderDraw(List<StyleRecord> allStyleElems) { 043 // nop 044 return true; 045 } 046 047 /** 048 * Notified when the render method is done. 049 */ 050 public void renderDone() { 051 // nop 052 } 053 054 /** 055 * A benchmark implementation that captures the times 056 * @author Michael Zangl 057 */ 058 public static class CapturingBenchmark extends RenderBenchmarkCollector { 059 protected long timeStart; 060 protected long timeGenerateDone; 061 protected long timeSortingDone; 062 protected long timeFinished; 063 064 @Override 065 public void renderStart(double circum) { 066 timeStart = System.currentTimeMillis(); 067 super.renderStart(circum); 068 } 069 070 @Override 071 public boolean renderSort() { 072 timeGenerateDone = System.currentTimeMillis(); 073 return super.renderSort(); 074 } 075 076 @Override 077 public boolean renderDraw(List<StyleRecord> allStyleElems) { 078 timeSortingDone = System.currentTimeMillis(); 079 return super.renderDraw(allStyleElems); 080 } 081 082 /** 083 * Get the time needed for generating the styles 084 * @return The time in ms 085 */ 086 public long getGenerateTime() { 087 return timeGenerateDone - timeStart; 088 } 089 090 /** 091 * Get the time needed for computing the draw order 092 * @return The time in ms 093 */ 094 public long getSortTime() { 095 return timeSortingDone - timeGenerateDone; 096 } 097 098 @Override 099 public void renderDone() { 100 timeFinished = System.currentTimeMillis(); 101 super.renderDone(); 102 } 103 104 /** 105 * Get the draw time 106 * @return The time in ms 107 */ 108 public long getDrawTime() { 109 return timeFinished - timeGenerateDone; 110 } 111 } 112 113 /** 114 * A special version of the benchmark class that logs the output to stderr. 115 * @author Michael Zangl 116 */ 117 public static class LoggingBenchmark extends RenderBenchmarkCollector.CapturingBenchmark { 118 private final PrintStream outStream = System.err; 119 private double circum; 120 121 @Override 122 public void renderStart(double circum) { 123 this.circum = circum; 124 super.renderStart(circum); 125 outStream.print("BENCHMARK: rendering "); 126 } 127 128 @Override 129 public boolean renderDraw(List<StyleRecord> allStyleElems) { 130 boolean res = super.renderDraw(allStyleElems); 131 outStream.print("phase 1 (calculate styles): " + Utils.getDurationString(timeSortingDone - timeStart)); 132 return res; 133 } 134 135 @Override 136 public void renderDone() { 137 super.renderDone(); 138 outStream.println("; phase 2 (draw): " + Utils.getDurationString(timeFinished - timeGenerateDone) + 139 "; total: " + Utils.getDurationString(timeFinished - timeStart) + 140 " (scale: " + circum + " zoom level: " + Selector.GeneralSelector.scale2level(circum) + ')'); 141 } 142 } 143 144 /** 145 * A supplier that gets the default benchmark class. 146 * @return A supplier that returns a nop or a logging benchmark. 147 */ 148 public static Supplier<RenderBenchmarkCollector> defaultBenchmarkSupplier() { 149 return () -> Main.isTraceEnabled() || Main.pref.getBoolean("mappaint.render.benchmark", false) 150 ? new LoggingBenchmark() : new RenderBenchmarkCollector(); 151 } 152}