How the renderer works
What the render path does, how it is implemented, how it compares to tangram-ng, and why it differs where it does.
Split so a reader — human or agent — can open one page and get a whole subsystem. Every page states its scope at the top and links out rather than repeating.
Pick your page
| You are working on | Read |
|---|---|
| anything at all, first time | Frame & threads |
| frame order, threads, what runs where, redraw requests | Frame & threads |
| which tiles are chosen, LOD, fetching, decoding (MVT and MLT), caches | Tiles & LOD |
| the GL draw path, style layers, draw counts, shaders | GL vector-tile renderer |
| 3D terrain: elevation data, surfaces, the ground pass | 3D terrain |
| bridges and tunnels: chords, decks, the opt-in switch, what is still wrong | 3D bridges |
| z-fighting, see-through, content sinking into the ground | Depth model |
| labels: placement, flicker, glyph sharpness, anchoring onto terrain | Labels |
| hillshade, contour lines, contour labels, hypsometric tint | Hillshade & contours |
| sun, shadows, sky, fog | Lighting, sky & fog |
CompositeVectorTileLayer, style-driven slots | Composite layer |
| markers, popups, app-drawn lines/polygons, picking | Vector elements |
| navigation maneuver arrows on a route | Maneuver arrows |
| sun/moon/stars/aircraft placed in the sky | Celestial objects |
| full-screen effects, the relief look, layers drawn above them | Post-processing |
| making it faster, or measuring anything | Performance |
| "why don't we just do what tangram does?" | vs tangram-ng |
| which graphics API we target, ES 3.0, Metal, ANGLE, new platforms | Graphics API migration |
The dated measurement history is a separate lab notebook: Performance log. These pages are the current design; that one is what was tried.
One frame
Detail in Frame & threads. The PROF sections of a -PprofileRender build map onto
these boxes one-for-one.
Two rules that shaped the render code
1. tangram-ng is the reference implementation, and we copy it.
Where it does something differently, we adopt its way rather than designing an alternative. Its
constants are copied, not derived — every constant this project derived instead turned out wrong
(failure catalogue in
Depth model). Each mechanism is
ported whole: half of their depth model was measurably worse than none of it, three times over.
When comparing, read their scene files (res/scenes/*.yaml), not only their shaders — the
shader defaults are overridden there.
2. The RTT drape is being deleted and is deliberately not documented.
The old path baked flat 2D content into per-tile render-target textures and textured the terrain
with them. It still exists behind TerrainOptions.DrapeFillsEnabled and --es drape true in the
demo, but the shared ground (3D terrain) replaced it. Do not build on it, and do
not extend these pages to cover it.
Where the render code lives
| Path | What |
|---|---|
all/native/renderers/ | frame orchestration (MapRenderer), per-kind renderers, TileRenderer (the bridge into vt) |
all/native/renderers/workers/ | CullWorker, VTLabelPlacementWorker, BillboardPlacementWorker |
all/native/layers/ | TileLayer, VectorTileLayer, RasterTileLayer, HillshadeRasterTileLayer, CompositeVectorTileLayer |
all/native/terrain/ | ElevationManager, ElevationTileGrid, TerrainTileTransformer |
all/native/datasources/ | tile sources, including the on-the-fly ContourTileDataSource |
libs-massif/vt/ | the GL renderer: GLTileRenderer, TileSurfaceBuilder, Label, LabelCuller, shaders |
libs-massif/mapnikvt, cartocss | tile decoding and style evaluation |
vt has no logger — probe it with __android_log_print(4, "massif", …), and throttle a probe
shared by several renderer instances with a prime modulus.