// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.data.osm.visitor.paint;
import java.io.PrintStream;
import java.util.List;
import java.util.function.Supplier;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.data.osm.visitor.paint.StyledMapRenderer.StyleRecord;
import org.openstreetmap.josm.gui.mappaint.mapcss.Selector;
import org.openstreetmap.josm.tools.Utils;
/**
* This class is notified of the various stages of a render pass.
*
* @author Michael Zangl
* @since 10697
*/
public class RenderBenchmarkCollector {
/**
* Notified when the renderer method starts preparing the data
* @param circum The current circum of the view.
*/
public void renderStart(double circum) {
// nop
}
/**
* Notified when the renderer method starts sorting the styles
* @return <code>true</code> if the renderer should continue to render
*/
public boolean renderSort() {
// nop
return true;
}
/**
* Notified when the renderer method starts drawing
* @param allStyleElems All the elements that are painted. Unsorted
* @return <code>true</code> if the renderer should continue to render
*/
public boolean renderDraw(List<StyleRecord> allStyleElems) {
// nop
return true;
}
/**
* Notified when the render method is done.
*/
public void renderDone() {
// nop
}
/**
* A benchmark implementation that captures the times
* @author Michael Zangl
*/
public static class CapturingBenchmark extends RenderBenchmarkCollector {
protected long timeStart;
protected long timeGenerateDone;
protected long timeSortingDone;
protected long timeFinished;
@Override
public void renderStart(double circum) {
timeStart = System.currentTimeMillis();
super.renderStart(circum);
}
@Override
public boolean renderSort() {
timeGenerateDone = System.currentTimeMillis();
return super.renderSort();
}
@Override
public boolean renderDraw(List<StyleRecord> allStyleElems) {
timeSortingDone = System.currentTimeMillis();
return super.renderDraw(allStyleElems);
}
/**
* Get the time needed for generating the styles
* @return The time in ms
*/
public long getGenerateTime() {
return timeGenerateDone - timeStart;
}
/**
* Get the time needed for computing the draw order
* @return The time in ms
*/
public long getSortTime() {
return timeSortingDone - timeGenerateDone;
}
@Override
public void renderDone() {
timeFinished = System.currentTimeMillis();
super.renderDone();
}
/**
* Get the draw time
* @return The time in ms
*/
public long getDrawTime() {
return timeFinished - timeGenerateDone;
}
}
/**
* A special version of the benchmark class that logs the output to stderr.
* @author Michael Zangl
*/
public static class LoggingBenchmark extends RenderBenchmarkCollector.CapturingBenchmark {
private final PrintStream outStream = System.err;
private double circum;
@Override
public void renderStart(double circum) {
this.circum = circum;
super.renderStart(circum);
outStream.print("BENCHMARK: rendering ");
}
@Override
public boolean renderDraw(List<StyleRecord> allStyleElems) {
boolean res = super.renderDraw(allStyleElems);
outStream.print("phase 1 (calculate styles): " + Utils.getDurationString(timeSortingDone - timeStart));
return res;
}
@Override
public void renderDone() {
super.renderDone();
outStream.println("; phase 2 (draw): " + Utils.getDurationString(timeFinished - timeGenerateDone) +
"; total: " + Utils.getDurationString(timeFinished - timeStart) +
" (scale: " + circum + " zoom level: " + Selector.GeneralSelector.scale2level(circum) + ')');
}
}
/**
* A supplier that gets the default benchmark class.
* @return A supplier that returns a nop or a logging benchmark.
*/
public static Supplier<RenderBenchmarkCollector> defaultBenchmarkSupplier() {
return () -> Main.isTraceEnabled() || Main.pref.getBoolean("mappaint.render.benchmark", false)
? new LoggingBenchmark() : new RenderBenchmarkCollector();
}
}