|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Paged (demand-fetched) accessor mode for book over ra8_vmem (#163). More...
#include <stddef.h>#include <stdint.h>#include "book.h"#include "ra8_err.h"#include "ra8_vmem.h"Go to the source code of this file.
Data Structures | |
| struct | book_src_t |
| A book data source: resident (zero-copy) or paged (demand-fetched). More... | |
Functions | |
| ra8_err_t | book_src_resident (book_src_t *out, const void *base, uint32_t size) |
| Bind a resident (already-inflated, fully resident) book as a source. | |
| ra8_err_t | book_src_paged (book_src_t *out, ra8_vmem_t *vm, uint32_t object_id, uint32_t frame_bytes, uint32_t size) |
| Bind a paged book source over an ::ra8_vmem cache + ::ra8_vsource object. | |
| ra8_err_t | book_src_read (const book_src_t *src, uint32_t off, void *dst, uint32_t len) |
| Copy a byte range out of a book source (resident memcpy or paged fault). | |
| ra8_err_t | book_src_image (const book_src_t *src, uint32_t idx, book_image_t *out_img) |
| Read one image descriptor out of a book source (resident or paged). | |
| ra8_err_t | book_src_image_rect (const book_src_t *src, const book_image_t *img, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t *out, uint32_t out_stride) |
| Read a sub-rectangle of a raster image (4bpp or 8bpp) as gray8, row by row. | |
| ra8_err_t | book_chapter_text_src (const book_src_t *src, uint32_t chapter_idx, char *out, size_t cap, size_t *out_len) |
| Extract one chapter's plain text from a book source (resident or paged). | |
| ra8_err_t | book_src_prefetch_chapter (const book_src_t *src, uint32_t chapter_idx) |
| Warm the cache frame holding a chapter's first content bytes, without pinning it (single-threaded read-ahead for the display-flush idle window). | |
Paged (demand-fetched) accessor mode for book over ra8_vmem (#163).
The default book accessors (book.h) are pure offset arithmetic over a fully-resident inflated blob – the right, zero-copy fast path for a book that fits the resident budget (and XIP-friendly). This sub-header adds the paged mode the #147/#162 memory hierarchy was built for: node / string / chapter lookups copy the needed bytes out of an ra8_vmem page cache on demand, so a GB-class EPUB / CBZ that does not fit RAM is read frame-by-frame with a bounded resident working set instead of a whole-blob inflate.
An book_src_t is the seam: it wraps either a resident blob base (zero-copy, identical to book.h) or an ra8_vmem cache fronting an ra8_vsource object (paged). Reads flow through book_src_read in both modes, and the DOM walkers (book_chapter_text_src) dispatch on the mode, so the reader uses one API and selects paged only when a book exceeds budget. The resident path is byte-for-byte identical to book_chapter_text(), so the ereader golden render stays unchanged for RAM-fitting books.
Definition in file book_paged.h.
|
nodiscard |
Extract one chapter's plain text from a book source (resident or paged).
The source-aware counterpart of book_chapter_text(): same output contract (whitespace-collapsed text runs, a newline at each block-level element, not NUL-terminated), but reads the DOM through src so a paged book is walked frame-by-frame. In resident mode it delegates to book_chapter_text() and is byte-for-byte identical; in paged mode it copies each visited node and string out on demand, pinning only what it is reading.
| [in] | src | Bound book source. |
| [in] | chapter_idx | Spine chapter index (< src->hdr.chapter_count). |
| [out] | out | Destination text buffer (non-NULL). |
| [in] | cap | Capacity of out in bytes. |
| [out] | out_len | Receives the text byte length written. |
| k_ra8_ok | Chapter text extracted. |
| k_ra8_err_null_ptr | src, out, or out_len was NULL. |
| k_ra8_err_invalid_arg | chapter_idx is out of range. |
| k_ra8_err_invalid_size | Output did not fit cap, or DOM nesting exceeded the bounded walk stack. |
| k_ra8_err_* | A page fault (paged mode only; returned verbatim). |
src was populated by book_src_resident() / book_src_paged(). chapter_idx is less than src->hdr.chapter_count. out content is unspecified.Definition at line 681 of file book_paged.c.
References book_src_t::base, book_chapter_text(), book_src_read(), book_header_t::chapter_count, book_header_t::chapter_off, book_src_t::hdr, internal_walk_text_paged(), k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_ok, book_header_t::node_count, RA8_CHECK_NULL_PTR, book_chapter_t::root_node, and s_tag_paged.
Referenced by sh_book_chapter_text().
|
nodiscard |
Read one image descriptor out of a book source (resident or paged).
The source-aware counterpart of the resident-only book_images() accessor: resolves image idx to its blob offset (hdr.image_off + idx * sizeof(book_image_t)) and copies the 24-byte descriptor out through book_src_read, so a paged book faults the descriptor's frame in on demand. The descriptor names the image geometry and its data_off into the image pool; feed it to book_src_image_rect to read pixels. This is the library-owned replacement for open-coding the image-table stride in a consumer.
| [in] | src | Bound book source. |
| [in] | idx | Image-table index (< src->hdr.image_count). |
| [out] | out_img | Receives the image descriptor. |
| k_ra8_ok | Descriptor copied into out_img. |
| k_ra8_err_null_ptr | src or out_img was NULL. |
| k_ra8_err_invalid_arg | idx is at or past src->hdr.image_count. |
| k_ra8_err_* | A page fault (paged mode only; returned verbatim). |
src was populated by book_src_resident() / book_src_paged(). out_img addresses writable storage for one book_image_t. out_img holds the descriptor at idx. out_img content is unspecified.Definition at line 314 of file book_paged.c.
References book_src_read(), book_src_t::hdr, book_header_t::image_count, book_header_t::image_off, k_ra8_err_invalid_arg, RA8_CHECK_NULL_PTR, and s_tag_paged.
Referenced by sh_gray4_image().
|
nodiscard |
Read a sub-rectangle of a raster image (4bpp or 8bpp) as gray8, row by row.
Owns the image-pool addressing contract so consumers do not. Both raster depths of a k_book_image_gray4 entry are served, selected by the descriptor's book_image_pixfmt_t, and both yield one gray8 byte per output pixel so the renderer sees a single depth:
The per-call read stays bounded by the rectangle regardless of the image width (book_src_read itself faults a paged source frame-by-frame), so the whole pool is never inflated. Rows are written at out_stride intervals, so out may be a window into a wider buffer.
| [in] | src | Bound book source. |
| [in] | img | Image descriptor from book_src_image (format must be k_book_image_gray4; pixel_format selects the gray4 vs gray8 unpack). |
| [in] | x | Sub-rect left edge in source pixels (x + w <= img->width). |
| [in] | y | Sub-rect top edge in source pixels (y + h <= img->height). |
| [in] | w | Sub-rect width in pixels (> 0, <= out_stride). |
| [in] | h | Sub-rect height in pixels (> 0). |
| [out] | out | Destination gray8 buffer (>= out_stride * h bytes). |
| [in] | out_stride | Bytes between successive output rows (>= w). |
| k_ra8_ok | The wxh window was read into out as gray8. |
| k_ra8_err_null_ptr | src, img, or out was NULL. |
| k_ra8_err_invalid_arg | img is not a raster (SVG), its pixel_format is neither gray4 nor gray8, or w == 0, h == 0, or out_stride < w. |
| k_ra8_err_out_of_range | The sub-rect leaves the image, or the pool span it addresses leaves the blob. |
| k_ra8_err_* | A page fault (paged mode only; returned verbatim). |
src was populated by book_src_resident() / book_src_paged(). out addresses at least out_stride * h writable bytes. out content is unspecified.Definition at line 325 of file book_paged.c.
References book_image_pixfmt(), book_image_t::format, book_image_t::height, internal_book_image_row(), internal_book_image_row_gray8(), k_book_image_gray4, k_book_pixfmt_gray4, k_book_pixfmt_gray8, k_ra8_err_invalid_arg, k_ra8_err_out_of_range, k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag_paged, and book_image_t::width.
Referenced by sh_gray4_fetch_row(), and sh_loupe_stage().
|
nodiscard |
Bind a paged book source over an ::ra8_vmem cache + ::ra8_vsource object.
The demand-fetch path for books that do not fit the resident budget. The caller has already registered the book's bytes as an ::ra8_vsource paged (or XIP) object and initialised vm with ra8_vsource_loader. This reads the 100-byte header through the cache into book_src_t::hdr so header fields never fault thereafter.
| [out] | out | Source to populate (caller-owned). |
| [in] | vm | Initialised page cache fronting the book object (non-NULL). |
| [in] | object_id | The book's ::ra8_vsource object id within vm's loader. |
| [in] | frame_bytes | vm's frame size in bytes (>= 2); used for slice math. |
| [in] | size | Blob length in bytes (> 0, == header total_size). |
| k_ra8_ok | Source bound in paged mode; header cached. |
| k_ra8_err_null_ptr | out or vm was NULL. |
| k_ra8_err_invalid_size | size was zero or frame_bytes was < 2. |
| k_ra8_err_* | A page fault while reading the header (verbatim). |
vm was initialised with the book registered at object_id. frame_bytes equals the frame size vm was configured with. out is left unbound.vm's pin/evict state is mutated by reads. Definition at line 61 of file book_paged.c.
References book_src_t::base, book_src_read(), book_src_t::frame_bytes, book_src_t::hdr, k_book_paged_min_frame, k_ra8_err_invalid_size, book_src_t::object_id, RA8_CHECK_NULL_PTR, s_tag_paged, book_src_t::size, and book_src_t::vm.
Referenced by sh_paged_bind().
|
nodiscard |
Warm the cache frame holding a chapter's first content bytes, without pinning it (single-threaded read-ahead for the display-flush idle window).
The reader-facing wrapper #207 wires into the flush-idle window: after rendering the current page and issuing the panel flush, warm the adjacent chapters (N+1 for forward reading, N-1 for a back-flip) so the next chapter-crossing page turn finds them resident. Resolves chapter_idx to the byte offset of its root DOM node – the first content range book_chapter_text_src reads for that chapter – and hands it to ra8_vmem_prefetch, which does a bounded get+put so the page ends resident but unpinned (SLRU/2Q probationary: a wrong read-ahead guess ages out before hot data, no prefetch backfire on a fast skim). Best-effort and transparent: warming only changes cache residency, never the bytes a later read returns, so rendered output is unchanged. Resident sources are already wholly in RAM and are rejected as a no-op.
| [in] | src | Bound (paged) book source. |
| [in] | chapter_idx | Spine chapter index to warm (< src->hdr.chapter_count). |
| k_ra8_ok | The chapter's root-node frame is resident, unpinned. |
| k_ra8_err_null_ptr | src was NULL. |
| k_ra8_err_invalid_state | src is resident (or unbound): nothing to page. |
| k_ra8_err_invalid_arg | chapter_idx is out of range. |
| k_ra8_err_* | A chapter-record read or the warm faulted (verbatim). |
src was populated by book_src_paged() (paged mode, src->vm != NULL). Definition at line 721 of file book_paged.c.
References book_src_read(), book_header_t::chapter_count, book_header_t::chapter_off, book_src_t::hdr, k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, book_header_t::node_off, book_src_t::object_id, RA8_CHECK_NULL_PTR, ra8_vmem_prefetch(), book_chapter_t::root_node, s_tag_paged, and book_src_t::vm.
Referenced by sh_reader_prefetch_adjacent().
|
nodiscard |
Copy a byte range out of a book source (resident memcpy or paged fault).
The single read primitive both modes share. Resident mode is a memcpy(dst, base + off, len). Paged mode walks the range frame by frame: ra8_vmem_get pins the frame holding the current offset, the overlapping slice is copied to dst, and ra8_vmem_put releases it before advancing – so at most one frame is pinned at a time and the resident working set stays bounded regardless of len.
| [in] | src | Bound book source. |
| [in] | off | Byte offset within the blob (off + len <= src->size). |
| [out] | dst | Destination buffer receiving len bytes (non-NULL). |
| [in] | len | Number of bytes to copy. |
| k_ra8_ok | Bytes copied into dst. |
| k_ra8_err_null_ptr | src or dst was NULL. |
| k_ra8_err_invalid_state | src is bound to neither mode. |
| k_ra8_err_out_of_range | off + len exceeds src->size. |
| k_ra8_err_* | A page fault (paged mode only; returned verbatim). |
src was populated by book_src_resident() / book_src_paged(). dst addresses at least len writable bytes. off. dst content is unspecified and no pin is held.Definition at line 141 of file book_paged.c.
References book_src_t::base, internal_book_src_read_paged(), k_ra8_err_invalid_state, k_ra8_err_out_of_range, k_ra8_ok, memcpy(), RA8_CHECK_NULL_PTR, s_tag_paged, book_src_t::size, and book_src_t::vm.
Referenced by book_chapter_text_src(), book_src_image(), book_src_paged(), book_src_prefetch_chapter(), internal_book_image_row(), internal_book_image_row_gray8(), internal_paged_emit_run(), internal_paged_node(), internal_paged_str_short(), sh_rabook_label(), and sh_src_string().
|
nodiscard |
Bind a resident (already-inflated, fully resident) book as a source.
The zero-copy fast path: book_src_t::base is set to base and reads become base + off, byte-for-byte identical to the book.h accessors. The header is copied into book_src_t::hdr.
| [out] | out | Source to populate (caller-owned). |
| [in] | base | Validated .rabook blob base (non-NULL), as from book_open(). |
| [in] | size | Blob length in bytes (> 0, == header total_size). |
| k_ra8_ok | Source bound in resident mode. |
| k_ra8_err_null_ptr | out or base was NULL. |
| k_ra8_err_invalid_size | size was zero. |
base was accepted by book_validate() / book_open(). out points at writable storage out-living the reads. out is left unbound.Definition at line 45 of file book_paged.c.
References book_src_t::base, book_src_t::frame_bytes, book_src_t::hdr, k_ra8_err_invalid_size, k_ra8_ok, memcpy(), book_src_t::object_id, RA8_CHECK_NULL_PTR, s_tag_paged, book_src_t::size, and book_src_t::vm.