[HN Gopher] Improving texture atlas allocation in WebRender
___________________________________________________________________
Improving texture atlas allocation in WebRender
Author : todsacerdoti
Score : 67 points
Date : 2021-02-04 13:16 UTC (9 hours ago)
(HTM) web link (nical.github.io)
(TXT) w3m dump (nical.github.io)
| aappleby wrote:
| I wrote the texture atlas implementation for Google Maps and it's
| basically the same as the "simple shelf allocator" mentioned here
| with a few twists (grid-snapped allocation, tunable allocation
| granularity, resizable atlases).
|
| You can peek behind the scenes of maps.google.com using WebGL
| Inspector or similar, it's kinda fun to watch.
| aappleby wrote:
| Oh and it does zero dynamic allocations except during atlas
| resize, which was very helpful in older builds of V8.
| Jasper_ wrote:
| I wrote a basic allocator for runtime lightmap packing (a
| _very_ different problem than dynamic image packing tbf), and a
| simple skyline got me very good results, for about 50 lines of
| code:
|
| https://github.com/magcius/noclip.website/blob/master/src/So...
|
| Compared to shelf, I think it did really well on the input data
| I had. I didn't even use the Halo Reach tricks for removing
| border padding when packing subpixel lightmaps!
| mooman219 wrote:
| The skyline algorithm is definitely very pleasant to work
| with and has some impressive results! Adding additional
| heuristics on top of it is also very straightforward which is
| great.
| Const-me wrote:
| When I needed the same thing, I took well-known implementation
| https://github.com/memononen/fontstash/blob/203fec2eb6a8905a...
| And ported from C to C++: https://github.com/Const-
| me/nanovg/blob/master/src/FontStash...
|
| Font atlas is required to be dynamic because Unicode has too many
| different codepoints. Statically allocated bitmap fonts no longer
| work in practice. Based on the pictures in the article, it works
| better than what WebRender is doing.
|
| The performance is good even on Raspberry Pi. This library
| https://github.com/Const-me/Vrmac uses 3 of them for 2D graphics:
| RGBA for sprites, another RGBA for ClearType fonts, and grayscale
| one for non-ClearType fonts. Here's the only pixel shader that
| implements all 2D rendering, including text:
| https://github.com/Const-me/Vrmac/blob/master/Vrmac/Draw/Sha...
|
| > a batch can only reference a fixed set of resources (such as
| GPU buffers and textures)
|
| Technically that's true, but not practically. There's GPU
| resource type called "texture array". It's possible to append new
| layers into an array without moving data across PCIe and back.
| Jasper_ wrote:
| Texture arrays aren't available on GLES 2.0, which I believe
| WebRender targets.
|
| > It's possible to append new layers into an array without
| moving data across PCIe and back.
|
| ? As far as I know, texture layer dimensions have to be
| specified up-front. Unless, I suppose, you're OpenGL and the
| driver lies to you about that with mutable textures, but it's
| really creating a new texture under and doing a full copy for
| you behind the scenes.
| Const-me wrote:
| > which I believe WebRender targets
|
| OpenGL 3.0 and OpenGL ES 3.0:
| https://pcwalton.github.io/slides/201808-webrender/
|
| They both support texture arrays.
|
| > texture layer dimensions have to be specified up-front
|
| Indeed, but it's possible to create another larger one, and
| copy layers between arrays within GPU.
|
| It's the same idea as std::vector on CPUs, most heaps can't
| resize memory either, they instead allocate new blocks and
| copy.
|
| There're two wins with texture arrays.
|
| 1. Removes area limitation. 2D textures are often limited to
| rather small size, like 2k^2 pixels. Same limitation applies
| to arrays, but with multiple layers their total area is only
| limited by VRAM size. That 2D library I've linked above
| renders arbitrarily complex 2D graphics with only 2 draw
| calls, regardless on how many sprites or font glyphs are used
| in the scene. Two because front-to-back opaque followed by
| back-to-front translucent.
|
| 2. These packing algorithms often scale worse than linearly
| with available area or count of sprites on the atlas. Using
| multiple layers of the array takes care of that, new sprites
| are only packed into the last layer, and layer size is never
| too large.
___________________________________________________________________
(page generated 2021-02-04 23:01 UTC)