Renders one Scene group on the GPU. Geometry is uploaded once; pan/zoom is a transform-uniform update and recolor/visibility is a palette/flags texture update — neither touches the geometry buffers. Appends are O(new): the geometry buffers grow by capacity-doubling (GrowBuffer) and the color/flags textures grow with partial uploads (or a recreate when their texel dimensions change).
Build a column-major 3x3 matrix mapping reference pixel coordinates (origin top-left, y down, the space d3 projections / geoPath produce) through a d3-zoom transform and into WebGL clip space [-1, 1] (origin center, y up).
Texel dimensions for a per-drawable side-table of count entries. A single row up to maxWidth, then wrapping into rows. drawableId -> texel is therefore (id % width, floor(id / width)); the shader recovers width via textureSize().
Read a rendered framebuffer back to a PNG data URL. WebGL readback is bottom-left origin, so rows are flipped to top-left for the image. Browser only (uses a 2D canvas to encode). Render into framebuffer before calling.