ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_glyph_atlas.h File Reference

Fixed-RAM-budget glyph cache with LRU eviction (Layer 3, #147). More...

#include <stdint.h>
#include "ra8_err.h"
#include "ra8_keycache.h"
Include dependency graph for ra8_glyph_atlas.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ra8_glyph_key_t
 Identifies one rendered glyph. More...
struct  ra8_glyph_dims_t
 Per-cell user descriptor: the rendered glyph dimensions. More...
struct  ra8_glyph_t
 A pinned view of a cached glyph bitmap returned by ra8_glyph_atlas_get. More...
struct  ra8_glyph_atlas_cfg_t
 Caller-supplied storage + renderer for ra8_glyph_atlas_init. More...
struct  ra8_glyph_atlas_t
 Glyph-cache state (caller-owned; treat as private). More...

Typedefs

typedef ra8_err_t(* ra8_glyph_render_fn) (void *ctx, const ra8_glyph_key_t *key, uint8_t *cell, uint32_t cell_bytes, uint16_t *out_w, uint16_t *out_h)
 Rasterise a glyph into a cache cell (render-on-miss DIP seam).

Functions

ra8_err_t ra8_glyph_atlas_init (ra8_glyph_atlas_t *atlas, const ra8_glyph_atlas_cfg_t *cfg)
 Initialise a glyph atlas over caller-supplied storage.
ra8_err_t ra8_glyph_atlas_get (ra8_glyph_atlas_t *atlas, const ra8_glyph_key_t *key, ra8_glyph_t *out_glyph)
 Get (and pin) the rendered glyph for key.
ra8_err_t ra8_glyph_atlas_put (ra8_glyph_atlas_t *atlas, const uint8_t *bitmap)
 Release one pin on a glyph previously returned by ra8_glyph_atlas_get.
ra8_err_t ra8_glyph_atlas_stats (const ra8_glyph_atlas_t *atlas, uint32_t *out_hits, uint32_t *out_misses, uint32_t *out_evictions)
 Report the atlas hit / miss / eviction counters.

Detailed Description

Fixed-RAM-budget glyph cache with LRU eviction (Layer 3, #147).

Tag
[Ring 2 / Core] {World: NS}

The original ask behind the #147 memory hierarchy: a glyph cache with a fixed RAM budget so the text renderer never re-rasterises a glyph it drew recently, while resident glyph memory stays bounded regardless of how many glyphs a book touches. A glyph is keyed by (face, pixel size, glyph id, render mode), and the cache returns a pinned view of the rendered bitmap; a miss renders the glyph into a free/evicted cell through a caller-supplied renderer (the FreeType/STB rasteriser in production, a stub in tests).

This is a thin typed facade over the reusable ::ra8_keycache (key bytes + cell bytes + render-on-miss + pin/unpin): the glyph key is the cache key, the glyph bitmap is the cell payload, and the rendered width/height ride in the per-cell user descriptor (ra8_glyph_dims_t). The image-tile cache (::ra8_tile_cache) is the second facade over the same machinery. Eviction is LRU with pinned-frame skip: the current page's glyphs are pinned while on screen, so a page-turn cannot evict a glyph still being drawn. (Glyph reuse has strong per-page locality, so plain LRU suffices here – the scan-resistant SLRU lives in the ::ra8_vmem page cache where linear file floods happen.) Cells are fixed-size, sized to the largest glyph bitmap the budget allows; a glyph larger than a cell is rejected at render time.

Zero allocation (NASA P10 Rule 3): the caller provides the cell storage, the key storage, the per-cell dimension descriptors, the per-cell link metadata, and the hash buckets, carved once from a tier ::ra8_arena / ::ra8_slab at init (hot tier = SRAM/DTCM).

Note
Not thread-safe; the renderer is single-threaded.
Since
0.1.0

Definition in file ra8_glyph_atlas.h.

Typedef Documentation

◆ ra8_glyph_render_fn

typedef ra8_err_t(* ra8_glyph_render_fn) (void *ctx, const ra8_glyph_key_t *key, uint8_t *cell, uint32_t cell_bytes, uint16_t *out_w, uint16_t *out_h)

Rasterise a glyph into a cache cell (render-on-miss DIP seam).

Parameters
[in]ctxOpaque renderer context (render_ctx from the config).
[in]keyThe glyph to render.
[out]cellDestination bitmap buffer (cell_bytes writable).
[in]cell_bytesCell capacity in bytes.
[out]out_wRendered glyph width in pixels.
[out]out_hRendered glyph height in pixels.
Returns
ra8_err_t k_ra8_ok on success (with out_w*out_h <= cell_bytes); any error aborts the get with that code.
Since
0.1.0

Definition at line 125 of file ra8_glyph_atlas.h.

Function Documentation

◆ ra8_glyph_atlas_get()

ra8_err_t ra8_glyph_atlas_get ( ra8_glyph_atlas_t * atlas,
const ra8_glyph_key_t * key,
ra8_glyph_t * out_glyph )
nodiscard

Get (and pin) the rendered glyph for key.

On a hit the cell is moved to the MRU and pinned. On a miss an unpinned LRU victim is evicted, the glyph is rendered into the cell, inserted, and pinned. The returned bitmap stays valid until ra8_glyph_atlas_put.

Parameters
[in]atlasInitialised atlas.
[in]keyGlyph to fetch.
[out]out_glyphReceives the pinned glyph view.
Returns
ra8_err_t Error code.
Return values
k_ra8_okGlyph resident and pinned; *out_glyph set.
k_ra8_err_null_ptratlas, key, or out_glyph was NULL.
k_ra8_err_no_memEvery cell is pinned (cannot evict for the miss).
k_ra8_err_*The renderer failed (returned verbatim).
Precondition
atlas was populated by ra8_glyph_atlas_init.
The caller will ra8_glyph_atlas_put the returned glyph.
Postcondition
On success the cell's pin count increased by one.
On any non-ok return no new pin is held.
Note
Not thread-safe.
Since
0.1.0

Definition at line 103 of file ra8_glyph_atlas.c.

References ra8_keycache_view_t::data, ra8_glyph_dims_t::h, k_ra8_ok, ra8_glyph_atlas_t::kc, RA8_CHECK_NULL_PTR, ra8_keycache_get(), s_tag, ra8_keycache_view_t::user, and ra8_glyph_dims_t::w.

Referenced by internal_glyph_render_cached(), and internal_submit_access().

◆ ra8_glyph_atlas_init()

ra8_err_t ra8_glyph_atlas_init ( ra8_glyph_atlas_t * atlas,
const ra8_glyph_atlas_cfg_t * cfg )
nodiscard

Initialise a glyph atlas over caller-supplied storage.

Parameters
[out]atlasAtlas state to populate (zero-initialised by the caller).
[in]cfgStorage + renderer configuration.
Returns
ra8_err_t Error code.
Return values
k_ra8_okAtlas ready; all cells cold.
k_ra8_err_null_ptratlas, cfg, or a required cfg pointer NULL.
k_ra8_err_invalid_sizecell_count, cell_bytes, or bucket_count 0.
Precondition
cfg's arrays cover their sizes and out-live the atlas.
cfg->render is non-NULL.
Postcondition
On success the atlas is empty and buckets are cleared.
On any non-ok return atlas is left unbound.
Note
Not thread-safe.
Since
0.1.0

Definition at line 78 of file ra8_glyph_atlas.c.

References ra8_glyph_atlas_cfg_t::bucket_count, ra8_keycache_cfg_t::bucket_count, ra8_glyph_atlas_cfg_t::buckets, ra8_keycache_cfg_t::buckets, ra8_glyph_atlas_cfg_t::cell_bytes, ra8_keycache_cfg_t::cell_bytes, ra8_glyph_atlas_cfg_t::cell_count, ra8_keycache_cfg_t::cell_count, ra8_glyph_atlas_cfg_t::cell_mem, ra8_keycache_cfg_t::cell_mem, ra8_glyph_atlas_cfg_t::dims, internal_glyph_render(), ra8_glyph_atlas_t::kc, ra8_keycache_cfg_t::key_bytes, ra8_keycache_cfg_t::key_mem, ra8_glyph_atlas_cfg_t::keys, memset(), ra8_glyph_atlas_cfg_t::meta, ra8_keycache_cfg_t::meta, RA8_CHECK_NULL_PTR, ra8_keycache_init(), ra8_glyph_atlas_cfg_t::render, ra8_glyph_atlas_t::render, ra8_keycache_cfg_t::render, ra8_glyph_atlas_cfg_t::render_ctx, ra8_glyph_atlas_t::render_ctx, ra8_keycache_cfg_t::render_ctx, s_tag, ra8_keycache_cfg_t::user_bytes, and ra8_keycache_cfg_t::user_mem.

Referenced by internal_run_budget(), and reflow_set_glyph_atlas().

◆ ra8_glyph_atlas_put()

ra8_err_t ra8_glyph_atlas_put ( ra8_glyph_atlas_t * atlas,
const uint8_t * bitmap )
nodiscard

Release one pin on a glyph previously returned by ra8_glyph_atlas_get.

Parameters
[in]atlasInitialised atlas.
[in]bitmapThe bitmap pointer from a returned ra8_glyph_t.
Returns
ra8_err_t Error code.
Return values
k_ra8_okPin released.
k_ra8_err_null_ptratlas or bitmap was NULL.
k_ra8_err_invalid_argbitmap is not a cell of this atlas, or the cell was not pinned.
Precondition
bitmap came from ra8_glyph_atlas_get on this atlas and is still pinned.
atlas was populated by ra8_glyph_atlas_init.
Postcondition
On success the cell's pin count decreased by one.
On any non-ok return no state changed.
Note
Not thread-safe.
Since
0.1.0

Definition at line 118 of file ra8_glyph_atlas.c.

References ra8_glyph_atlas_t::kc, RA8_CHECK_NULL_PTR, ra8_keycache_put(), and s_tag.

Referenced by internal_glyph_render_cached(), and internal_submit_access().

◆ ra8_glyph_atlas_stats()

ra8_err_t ra8_glyph_atlas_stats ( const ra8_glyph_atlas_t * atlas,
uint32_t * out_hits,
uint32_t * out_misses,
uint32_t * out_evictions )
nodiscard

Report the atlas hit / miss / eviction counters.

Parameters
[in]atlasInitialised atlas.
[out]out_hitsHits so far (may be NULL).
[out]out_missesMisses so far (may be NULL).
[out]out_evictionsEvictions so far (may be NULL).
Returns
ra8_err_t Error code.
Return values
k_ra8_okCounters reported.
k_ra8_err_null_ptratlas was NULL.
k_ra8_err_invalid_stateThe atlas was not initialised.
Precondition
atlas was populated by ra8_glyph_atlas_init.
At least one output pointer is non-NULL to be useful.
Postcondition
On success the requested counters are written.
No atlas state is mutated.
Note
Thread-safe with respect to a quiescent atlas (pure read).
Since
0.1.0

Definition at line 125 of file ra8_glyph_atlas.c.

References ra8_keycache_cfg_t::cell_mem, ra8_keycache_t::cfg, k_ra8_err_invalid_state, ra8_glyph_atlas_t::kc, RA8_CHECK_NULL_PTR, ra8_keycache_stats(), and s_tag.

Referenced by internal_run_budget().