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