Skip to content
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

Closed
kkaefer opened this issue Mar 8, 2013 · 14 comments
Closed

Decisions #1

kkaefer opened this issue Mar 8, 2013 · 14 comments

Comments

@kkaefer
Copy link
Contributor

kkaefer commented Mar 8, 2013

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.

@yhahn
Copy link
Member

yhahn commented Mar 8, 2013

My uninformed gut reactions:

  • Skia or Agg -- I think text rendering speed will be one of the more important datapoints here.
  • Shared renderer -- +1 agree. We don't need to bundle the core renderer with every map.
  • Portability vs Interpreted => Compiled -- y, this is clearly a chief concern and I think why a non-compiled format that is still portable/distributable would be quite good.

@kkaefer
Copy link
Contributor Author

kkaefer commented Mar 9, 2013

More benchmarks with actual tiles, but only drawing them as plain lines. Seems like Skia is a lot faster at that.

zoom levelAggSkiaDifference
0-0-02745.019 ms3048.882 ms90.03%
1-0-02469.488 ms2626.302 ms94.03%
2-0-11898.048 ms1653.761 ms114.77%
3-1-3 998.061 ms 739.782 ms134.91%
4-2-6 573.249 ms 354.471 ms161.71%
5-5-121205.543 ms 930.958 ms129.49%
6-10-244097.467 ms3740.938 ms109.53%
7-20-496884.159 ms5495.197 ms125.27%
8-41-985266.461 ms3344.382 ms157.47%
9-81-1975416.614 ms3081.683 ms175.76%
10-163-3954765.640 ms2790.811 ms170.76%
11-327-7913400.932 ms1727.686 ms196.84%
12-654-15837725.448 ms4260.209 ms181.33%
13-1310-31668910.527 ms4734.037 ms188.22%
14-2621-63327804.700 ms3143.617 ms248.27%

@kkaefer
Copy link
Contributor Author

kkaefer commented Mar 10, 2013

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.

zoom levelAggSkiaDifference
0-0-09332.235 ms3057.743 ms305.20%
1-0-08602.239 ms2633.135 ms326.69%
2-0-15192.457 ms1642.069 ms316.21%
3-1-32312.432 ms 760.329 ms304.13%
4-2-61079.123 ms 360.008 ms299.74%
5-5-122867.320 ms 922.914 ms310.68%
6-10-2412211.374 ms3695.121 ms330.47%
7-20-4918664.093 ms5530.179 ms337.49%
8-41-9811490.280 ms3348.413 ms343.15%
9-81-19710129.848 ms3285.112 ms308.35%
10-163-3958629.352 ms2756.154 ms313.09%
11-327-7915672.084 ms1718.770 ms330.00%
12-654-158313613.490 ms4416.656 ms308.23%
13-1310-316615043.996 ms4714.640 ms319.09%
14-2621-633211781.588 ms3129.761 ms376.43%

@springmeyer
Copy link
Contributor

Really interesting results!

@yhahn
Copy link
Member

yhahn commented Mar 10, 2013

@springmeyer @kkaefer are "high quality lines" in this case the same line drawing as what mapnik does with agg by default?

@springmeyer
Copy link
Contributor

Yes. The fast line rasterizer that agg provides is not the default in Mapnik.

@yhahn
Copy link
Member

yhahn commented Mar 10, 2013

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).

@springmeyer
Copy link
Contributor

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.

@artemp
Copy link

artemp commented Mar 11, 2013

@kkaefer - wow, interesting! Just to verify - Skia tests are using software based renderer (no sneaky quartz or opengl) ?

@springmeyer
Copy link
Contributor

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 10500 ms to 7880 ms for agg without a big visual difference. There is also the agg approximation scale.

@springmeyer
Copy link
Contributor

see also mapnik/mapnik#869

@kkaefer
Copy link
Contributor Author

kkaefer commented Mar 14, 2013

The benchmark is z0 through z14

@artemp
Copy link

artemp commented Mar 19, 2013

@kkaefer - had a chance to play with llmr. If stroke > 1 I get

line.set_width(2);
./llmr-skia tiles/tile0.data  
skia: 16941.882 ms

/llmr-agg tiles/tile0.data  
agg: 9550.725 ms

This tells me that skia is only good at stroking lines with width <= 1 - I guess their's 'hairline' algorithm is showing off here. ??

@kkaefer
Copy link
Contributor Author

kkaefer commented Mar 19, 2013

Good point. I've seen similar speed behavior when using HTML5 canvas rendering (which uses Skia in Chrome).

@kkaefer kkaefer closed this as completed Sep 9, 2013
lucaswoj pushed a commit that referenced this issue Jan 11, 2017
jpilet pushed a commit to JpmGuides/mapbox-gl-js that referenced this issue Feb 27, 2018
Using `setCustomWebGLDrawCallback` for custom-webgl layers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants