-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Decisions #1
Comments
My uninformed gut reactions:
|
More benchmarks with actual tiles, but only drawing them as plain lines. Seems like Skia is a lot faster at that.
|
Switching to the high quality line renderer as per #2, results looks like this. Seems like Skia is at least 3x faster rendering high quality lines. Of course, as @yhahn pointed out, the real measure is text rendering and placement.
|
Really interesting results! |
@springmeyer @kkaefer are "high quality lines" in this case the same line drawing as what mapnik does with agg by default? |
Yes. The fast line rasterizer that agg provides is not the default in Mapnik. |
Cool, very good to know. I did attempt to use the fast line rasterizer but did not notice any speed boost at the time (also line drawing may have been a much smaller portion of our resource usage at the time). |
yes, when I first discovered, benchmarked, and added the fast/outline based agg switch to mapnik, it showed clear benefit in isolated benchmarks with only line rendering of lots of lines (I used processed_p). But, yeah, line rendering is rarely (yet) the top bottleneck. |
@kkaefer - wow, interesting! Just to verify - Skia tests are using software based renderer (no sneaky quartz or opengl) ? |
it looks like we should benchmark streetlevel rendering. The current benchmark comparing skia to agg line rendering at z0 ends up with lots of verticies overlapping in pixel space. So we may be seeing that skia is faster at throwing away coincident verticies than agg and not necessary that the actual rendering is as faster as it seems. I did a quick test with: diff --git a/src/agg_image.cpp b/src/agg_image.cpp
index 9d765a4..c9443f7 100644
--- a/src/agg_image.cpp
+++ b/src/agg_image.cpp
@@ -43,6 +43,7 @@ void Image::render(const Line &style, agg::path_storage& path) {
// Slow
polygon_rasterizer.reset();
agg::conv_stroke<agg::path_storage> stroke(path);
+ stroke.generator().shorten(2);
stroke.width(style.width());
polygon_rasterizer.add_path(stroke);
polygon_renderer.color(to_color(style.color())); which shortens line rendering and gives a speedup from |
see also mapnik/mapnik#869 |
The benchmark is z0 through z14 |
@kkaefer - had a chance to play with llmr. If stroke > 1 I get
This tells me that skia is only good at stroking lines with width <= 1 - I guess their's 'hairline' algorithm is showing off here. ?? |
Good point. I've seen similar speed behavior when using HTML5 canvas rendering (which uses Skia in Chrome). |
Using `setCustomWebGLDrawCallback` for custom-webgl layers
Skia or Agg?
There are sample apps for both in the repository. Speedwise, Skia has a slight edge (~8%) on my machine with the current build settings (I haven't investigated possible ways of tuning it), but it's very narrow. The binaries using the Skia renderer, however, are a lot larger; the stripped binaries are 1283 KB vs. 158 KB.
Skia has includes text rendering support, so we don't have to mess around with freetype and is under active development in contrast to Agg. However, that might also mean that rendering results produced by Skia are more likely to change.
Shared renderer
Currently, the renderer (Agg/Skia) is statically linked into the binary (or the
.so
files we would produce in an actual setup). This gives us a lot of renderer stability (e.g. future updates to Skia wouldn't break our existing maps), but duplicates the renderer's code for every single map. We could use the renderer as a shared library, so we'd only have one single instance of the renderer loaded into memory. Sharing a renderer also allows us benefit from bug fixes and speed improvements across all of our maps and not just those that were uploaded after the fact.I think we /should/ share the renderer across maps and potentially risk slightly broken maps. I assume that the only thing that might change about the renderer are minor visual things like antialiasing, miter calculation, or pixel grid alignments. We'd still compile all of our placement algorithms and vertex handling code into every single compiled map.
Portability
When compiling maps into shared objects (
.so
files), they aren't portable anymore and tied to the system's architecture and standard library. We could probably still share compiled maps on our infrastructure given that it's pretty homogenous, but we would likely run into trouble when upgrading the operating system or anything else on our machines. In that case, we'd have to recompile the maps, but to maintain backwards-compatibility, we'd use the llmr state on the day the user created/uploaded the map. This means, we'd have to maintain legacy software and potentially port our own software to new platforms every couple of months or years. This is less of an issue if we use a shared renderer, but it still /is/ an issue.Lua bindings
Rather than producing a separate
.so
file for every compiled map, we could also look into creating Lua bindings for Skia or Agg and then use Lua rather than actual compiled code. The advantage is that we don't have to generate/compile C/C++ code for every map and we'd likely run into fewer legacy maintenance issues when having our algorithms in Lua. When using LuaJIT, we should get a pretty decent performance close to native code as LuaJIT compiles the Lua file (which includes all the vertex processing + placement algorithms) into native bytecode on the fly.The text was updated successfully, but these errors were encountered: