|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Import-time pagination cache for reflow (#79). More...
Go to the source code of this file.
Enumerations | |
| enum | reflow_cache_id_t : uint32_t { k_reflow_cache_magic = 0x52464331U , k_reflow_cache_version = 2U } |
| On-wire format identity for a serialised pagination cache. More... | |
| enum | reflow_cache_layout_t : size_t { k_reflow_cache_header_bytes = 52U , k_reflow_cache_glyph_bytes = 20U , k_reflow_cache_page_bytes = 8U } |
| Byte sizes of the serialised header and per-record payloads. More... | |
Functions | |
| ra8_err_t | reflow_cache_size (const reflow_t *engine, size_t *out_bytes) |
| Report the exact serialised size of an engine's current layout. | |
| ra8_err_t | reflow_cache_serialize (const reflow_t *engine, const uint8_t *content, size_t content_len, uint8_t *out_buf, size_t out_cap, size_t *out_len) |
| Serialise the laid-out pages of engine into a keyed byte blob. | |
| ra8_err_t | reflow_cache_load (reflow_t *engine, const uint8_t *content, size_t content_len, const uint8_t *buf, size_t len) |
| Validate a cache blob and, if it matches, restore the layout. | |
Import-time pagination cache for reflow (#79).
Laying out a chapter (reflow_layout_chapter()) is the expensive step in the e-reader open path: it tokenizes the XHTML, measures every glyph through stb_truetype, and runs the greedy line-break / page-break engine. For a given book that result never changes unless the viewport, font, colours, font blob or chapter bytes change – so it is wasteful to repeat it every time the book is opened.
This module serialises the laid-out result – the flat glyphs[] array and the pages[] index ranges, which is all the renderer needs (render is a flat glyph walk) – into a small, self-describing byte blob, keyed by everything that would invalidate the layout:
The blob is storage-agnostic: the application persists it however it already stores data (e.g. a file on the microSD via ra8_fs_write_file() / ra8_fs_open() + ra8_fs_read()), so this module pulls in no filesystem dependency. The intended flow:
reflow_cache_load() validates the blob's key against the engine's current viewport / font / colours and the supplied content; on any mismatch it returns k_ra8_err_invalid_state so the caller re-lays-out. A body checksum guards against a corrupt blob.
The blob is device-local: it is written and read back by the same firmware build (same struct layout, same endianness), but the on-wire form is still explicit little-endian per field – so the checksum is deterministic (no padding bytes) and a future format change is caught by the version field rather than silently mis-parsed.
[Ring 4 / Reflow] {World: NS}
Definition in file reflow_cache.h.
| enum reflow_cache_id_t : uint32_t |
On-wire format identity for a serialised pagination cache.
k_reflow_cache_magic is the first 4 bytes of every blob (stored little-endian). k_reflow_cache_version is bumped whenever the serialised layout changes; a load of a different version is treated as stale (re-layout) rather than mis-parsed.
| Enumerator | |
|---|---|
| k_reflow_cache_magic | Blob magic ('R''F''C''1'). |
| k_reflow_cache_version | Serialised format version. |
Definition at line 88 of file reflow_cache.h.
| enum reflow_cache_layout_t : size_t |
Byte sizes of the serialised header and per-record payloads.
The blob is header + glyph_count * glyph_bytes + page_count * page_bytes. A glyph serialises its 7 meaningful fields (x, y, cp, colour, font_px, style, reserved = 4+4+4+4+2+1+1); reserved carries the 1-based <a> link id used by hyperlink navigation, so it must round-trip (it is layout state, not padding). A page serialises its two uint32_t index fields.
| Enumerator | |
|---|---|
| k_reflow_cache_header_bytes | Fixed header size, bytes. |
| k_reflow_cache_glyph_bytes | Serialised bytes per glyph. |
| k_reflow_cache_page_bytes | Serialised bytes per page. |
Definition at line 105 of file reflow_cache.h.
|
nodiscard |
Validate a cache blob and, if it matches, restore the layout.
Parses the blob header, then validates – in order – the magic, the format version, the record counts (against the engine's static pools and the blob length), the invalidation key (viewport / font / colours / font hash / content hash) and the body checksum. Only when all pass are the glyphs[] and pages[] arrays copied back into engine and engine->xhtml_buf / xhtml_len repointed at content (so a later reflow_set_font_size() can still re-flow). On any mismatch the engine is left untouched and the caller should re-lay-out.
| [in,out] | engine | Engine initialised with the same viewport / font / colours the blob was made with (the load validates this). |
| [in] | content | Chapter bytes (hashed and compared to the blob's content hash). May be NULL only when content_len == 0. |
| [in] | content_len | Length of content, bytes. |
| [in] | buf | Serialised blob. |
| [in] | len | Length of buf, bytes. |
| k_ra8_ok | Loaded; glyphs / pages restored. |
| k_ra8_err_null_ptr | engine or buf is NULL. |
| k_ra8_err_not_initialized | engine->in_use == 0. |
| k_ra8_err_invalid_arg | content NULL with content_len>0. |
| k_ra8_err_not_found | Magic mismatch (not a cache blob). |
| k_ra8_err_invalid_state | Version or key mismatch – the layout is stale; re-lay-out and re-serialise. |
| k_ra8_err_invalid_size | Truncated blob or counts exceed pools. |
| k_ra8_err_checksum_mismatch | Body checksum failed (corrupt blob). |
Definition at line 716 of file reflow_cache.c.
References priv_cache_key_t::body_checksum, priv_cache_key_t::glyph_count, reflow_t::glyph_count, reflow_t::glyphs, internal_cache_precheck(), internal_fnv1a(), internal_get_glyph(), internal_get_page(), internal_key_matches(), internal_parse_header(), k_ra8_err_checksum_mismatch, k_ra8_err_invalid_state, k_ra8_err_null_ptr, k_ra8_ok, k_reflow_cache_header_bytes, priv_cache_key_t::page_count, reflow_t::page_count, reflow_t::pages, reflow_t::xhtml_buf, and reflow_t::xhtml_len.
Referenced by internal_pc_invalidate_check_or_halt(), and internal_pc_reload_check_or_halt().
|
nodiscard |
Serialise the laid-out pages of engine into a keyed byte blob.
Writes the header (magic, version, the invalidation key, glyph / page counts and a body checksum) followed by the flat glyphs[] array and the pages[] index ranges, each field little-endian. The key captures the engine's viewport, font size, colours, the font blob (length + FNV-1a hash) and the supplied content (length + FNV-1a hash) so a later reflow_cache_load() can detect any change that would invalidate the layout.
| [in] | engine | Laid-out engine handle. |
| [in] | content | Chapter bytes the layout was produced from (hashed into the key). May be NULL only when content_len == 0. |
| [in] | content_len | Length of content, bytes. |
| [out] | out_buf | Destination buffer. |
| [in] | out_cap | Capacity of out_buf, bytes. |
| [out] | out_len | Receives the number of bytes written. |
| k_ra8_ok | Serialised; *out_len bytes written. |
| k_ra8_err_null_ptr | engine, out_buf or out_len NULL. |
| k_ra8_err_not_initialized | engine->in_use == 0. |
| k_ra8_err_invalid_arg | content NULL with content_len > 0. |
| k_ra8_err_invalid_size | out_cap smaller than the blob size. |
Definition at line 679 of file reflow_cache.c.
References reflow_t::glyph_count, reflow_t::glyphs, internal_blob_size(), internal_cache_precheck(), internal_fnv1a(), internal_put_glyph(), internal_put_header(), internal_put_page(), internal_put_u32(), k_priv_checksum_off, k_ra8_err_invalid_size, k_ra8_err_null_ptr, k_ra8_ok, k_reflow_cache_header_bytes, reflow_t::page_count, and reflow_t::pages.
Referenced by internal_pc_live_layout_or_halt(), and internal_pc_reload_check_or_halt().
Report the exact serialised size of an engine's current layout.
Lets the caller size (or bounds-check) the destination buffer before calling reflow_cache_serialize(). The value is k_reflow_cache_header_bytes + engine->glyph_count * k_reflow_cache_glyph_bytes + engine->page_count * k_reflow_cache_page_bytes.
| [in] | engine | Initialised engine (a chapter need not be laid out yet; an empty layout serialises to just the header). |
| [out] | out_bytes | Receives the required buffer size in bytes. |
| k_ra8_ok | Size reported. |
| k_ra8_err_null_ptr | engine or out_bytes is NULL. |
| k_ra8_err_not_initialized | engine->in_use == 0. |
Definition at line 622 of file reflow_cache.c.
References reflow_t::glyph_count, reflow_t::in_use, internal_blob_size(), k_ra8_err_not_initialized, k_ra8_err_null_ptr, k_ra8_ok, and reflow_t::page_count.