33static const char*
const s_tag =
"ereader_zoom";
47 "tile cache is smaller than the 1:1 viewport tile demand: re-derive k_ez_cells "
48 "from the panel + tile geometry so a single-step pan cannot thrash (#338)");
50 "resident tile arena exceeds its SDRAM budget");
52 "page width must tile exactly: the demo asserts a full-tile geometry");
54 "page height must tile exactly: the demo asserts a full-tile geometry");
61 "packed scratch cannot hold one dithered strip of the widest viewport");
63 "the loupe must be narrower than the shared composite row buffer");
86typedef enum : uint32_t {
112typedef enum : uint32_t {
132typedef enum : uint32_t {
151typedef enum : uint16_t {
165 const uint32_t band =
170 if (on_rule && inked) {
173 return (uint8_t)((uint32_t)
k_ez_bg_lo + band);
415 .decode_ctx =
nullptr,
426 "tiled source init");
522 if ((after.
x == before.
x) && (after.
y == before.
y)) {
582 const uint32_t colour =
591 "zoom indicator block");
715 if (buf ==
nullptr) {
718 const uint8_t* bytes = (
const uint8_t*)buf;
719 for (uint32_t i = 0U; i < len; ++i) {
720 hash ^= (uint32_t)bytes[i];
773 "selftest prefetch");
828 "selftest lens dirty");
831 "selftest page dirty");
ra8_ui_rect_t ez_content_rect(int32_t fb_w, int32_t fb_h)
The content rectangle: the panel less the status bar.
ez_tone_t
Gray8 tones and the shift/mask geometry of the procedural page.
@ k_ez_grad_mask
Gradient span above k_ez_bg_lo.
@ k_ez_word_mask
Words per group - 1 (one blank per group).
@ k_ez_rule_mask
Rule pitch - 1, rows.
@ k_ez_ink
Rule (text) tone.
@ k_ez_grad_shift
Pixels per gradient step (1 << shift).
@ k_ez_word_blank
Group index left blank (the inter-word gap).
@ k_ez_word_shift
Word run length (1 << shift), columns.
@ k_ez_rule_thick
Rule thickness, rows.
@ k_ez_bg_lo
Darkest background tone.
@ k_ez_grad_wrap
Triangle-wave period - 1 (2 * span + 1).
ez_zone_t ez_zone_hit(const ez_scene_t *s, int32_t x, int32_t y)
Classify a tap by the zone it lands in.
static ra8_err_t ez_selftest_stages(ez_scene_t *s, ez_selftest_t *out)
Run the four scripted self-check stages in order.
static ra8_err_t ez_selftest_zoom(ez_scene_t *s, ez_selftest_t *out)
Self-check stage 3: 2x about a fixed panel point.
ez_selftest_step_t
The scripted self-check's fixed inputs.
@ k_ez_st_focus_y
Panel row the 2x step keeps fixed.
@ k_ez_st_t0
Timestamp handed to every step (ms).
@ k_ez_st_scale
Magnification the 2x step selects.
@ k_ez_st_focus_x
Panel column the 2x step keeps fixed.
static ra8_err_t ez_draw_status(const ez_scene_t *s)
Paint the status bar and its block zoom indicator.
bool ez_scene_tick(ez_scene_t *s, uint32_t now_ms)
Advance both views' settle timers; report whether a repaint is due.
ra8_err_t ez_scene_prefetch(ez_scene_t *s, zoom_pan_t dir, uint16_t *out_warmed)
Warm the tiles one pan step ahead of the page viewport.
static void ez_choose_plan(const ez_scene_t *s, const zoom_present_t *page_plan, const zoom_present_t *lens_plan, ez_present_t *out)
Pick the flush rectangle from the two views' drained plans.
uint8_t ez_page_sample(uint32_t x, uint32_t y)
Sample the procedural full-resolution page at one pixel.
static ra8_err_t ez_open_views(ez_scene_t *s, const ez_scene_cfg_t *cfg)
Open both viewports over the bound page source.
static ra8_ui_rect_t ez_lens_rect(ra8_ui_rect_t content)
The loupe box: a square centred in the content rectangle.
static ra8_err_t ez_cfg_scratch_ok(const ez_scene_cfg_t *cfg)
Validate the three composite-scratch pointers.
ra8_err_t ez_tile_decode(void *ctx, const ra8_tile_key_t *key, uint8_t *cell, uint32_t cell_bytes, uint16_t *out_w, uint16_t *out_h)
ra8_tile_decode_fn that materialises one page tile from the sampler.
static ra8_err_t ez_bind_page(ez_scene_t *s, const ez_scene_cfg_t *cfg)
Wire the tile cache over the borrowed storage and bind it as a source.
ra8_err_t ez_scene_selftest(ez_scene_t *s, ez_selftest_t *out)
Drive the scene through the scripted boot self-check.
static ra8_err_t ez_draw_lens_chrome(ra8_ui_rect_t lens)
Paint the loupe's border so the lens reads as a lens, not a seam.
static ra8_err_t ez_render_and_hash(ez_scene_t *s, uint32_t *out_hash)
Render the scene and hash the framebuffer it produced.
ra8_err_t ez_scene_present(ez_scene_t *s, ez_present_t *out)
Take the pending flush plan for whichever view changed.
uint32_t ez_fnv1a(const void *buf, uint32_t len)
FNV-1a-32 over a byte range (the framebuffer hash).
static ra8_err_t ez_selftest_lens(ez_scene_t *s, ez_selftest_t *out)
Self-check stage 4: open the loupe over the magnified page.
static zoom_scratch_t ez_scratch_of(const ez_scene_cfg_t *cfg)
Build the shared composite-scratch descriptor from a configuration.
ra8_err_t ez_scene_render(ez_scene_t *s)
Repaint the content area, the loupe (when open) and the status bar.
static bool ez_apply_pan(ez_scene_t *s, ez_zone_t zone, uint32_t now_ms)
Apply a pan zone to the page viewport.
static void ez_fill_tile(uint8_t *cell, uint32_t org_x, uint32_t org_y)
Write one whole tile's pixels from the procedural page sampler.
static ra8_err_t ez_selftest_pan(ez_scene_t *s, ez_selftest_t *out)
Self-check stage 2: one right-pan step at 1:1, with read-ahead.
ez_chrome_t
Chrome colours, in the 0x00RRGGBB space ra8_gfx down-converts from.
@ k_ez_col_dim
Unlit zoom-indicator block.
@ k_ez_col_ind
Lit zoom-indicator block.
@ k_ez_col_bar
Status-bar fill.
@ k_ez_col_lens
Loupe border.
static ra8_err_t ez_cfg_ptrs_ok(const ez_scene_cfg_t *cfg)
Validate the borrowed storage a scene configuration must carry.
ez_fnv_t
FNV-1a-32 parameters.
@ k_ez_fnv_prime
FNV-1a-32 prime.
@ k_ez_fnv_offset
FNV-1a-32 offset basis.
ra8_err_t ez_scene_init(ez_scene_t *s, const ez_scene_cfg_t *cfg)
Wire the tile cache, the tiled source and both viewports.
bool ez_scene_tap(ez_scene_t *s, int32_t x, int32_t y, uint32_t now_ms)
Apply a tap to the scene.
Tap-to-zoom demo scene: tiled 12 MP page, zoom viewport, loupe (#478).
@ k_ez_page_scale_max
Page-view ladder ceiling.
@ k_ez_lens_scale_max
Loupe ladder ceiling.
@ k_ez_lens_scale_min
Loupe ladder floor.
ra8_err_t ez_tile_decode(void *ctx, const ra8_tile_key_t *key, uint8_t *cell, uint32_t cell_bytes, uint16_t *out_w, uint16_t *out_h)
ra8_tile_decode_fn that materialises one page tile from the sampler.
@ k_ez_page_w
Source page width, pixels.
@ k_ez_image_id
Tile-cache key image id for the page.
@ k_ez_tile_edge
Tile edge, pixels (gray8 => 64 KiB/tile).
@ k_ez_page_h
Source page height, pixels.
@ k_ez_row_bytes
One source row at the widest viewport.
@ k_ez_strip_bytes
gray8 destination strip (16 rows).
@ k_ez_packed_bytes
The strip packed to 4 bpp.
@ k_ez_lens_edge
Loupe box edge, pixels.
@ k_ez_status_h
Status bar height, pixels.
@ k_ez_ind_gap
Gap between indicator blocks, pixels.
@ k_ez_lens_border
Loupe chrome thickness, pixels.
@ k_ez_ind_block
Zoom-indicator block edge, pixels.
@ k_ez_edge_band
Pan tap-band depth at each edge.
ez_zone_t
Tap zones of the demo's discrete touch scheme.
@ k_ez_zone_none
Nothing under the tap.
@ k_ez_zone_lens
Inside the loupe: cycle its magnification.
@ k_ez_zone_pan_up
Top band: page travels up.
@ k_ez_zone_pan_left
Left band: page travels left.
@ k_ez_zone_toggle
Status bar: open / close the loupe.
@ k_ez_zone_zoom
Centre: cycle the page magnification.
@ k_ez_zone_pan_right
Right band: page travels right.
@ k_ez_zone_pan_down
Bottom band: page travels down.
@ k_ez_buckets
Cache hash buckets (>= cells).
@ k_ez_view_cols
1:1 tile columns a frame straddles, plus one.
@ k_ez_cell_budget_bytes
SDRAM the cache may claim.
@ k_ez_prefetch_max
Lead-edge tiles per pan.
@ k_ez_view_rows
1:1 tile rows a frame straddles, plus one.
@ k_ez_cell_bytes
One gray8 tile, bytes.
static const char * s_tag
Logging / check tag.
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
@ k_ra8_err_out_of_range
Sensor or peripheral output out of valid range.
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Software 2D graphics primitives layered on top of a caller-ownedframebuffer (DRW / D/AVE 2D / GLCDC r...
ra8_err_t ra8_gfx_rect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color, bool filled)
Draw an axis-aligned rectangle.
#define ra8_log_error(tag, message)
RA8 log error.
Fixed-RAM-budget image-tile cache with LRU eviction (Layer 3b, #147).
ra8_err_t ra8_tile_cache_stats(const ra8_tile_cache_t *tc, uint32_t *out_hits, uint32_t *out_misses, uint32_t *out_evictions)
Report the cache hit / miss / eviction counters.
ra8_err_t ra8_tile_cache_init(ra8_tile_cache_t *tc, const ra8_tile_cache_cfg_t *cfg)
Initialise a tile cache over caller-supplied storage.
Bounded UI interaction core: hit-testing, screen stack, paging.
bool ra8_ui_rect_contains(const ra8_ui_rect_t *r, int32_t px, int32_t py)
Test whether a point lies inside a rectangle.
What the scene asks the panel to flush, and how well.
ra8_ui_rect_t rect
Panel rectangle to flush.
bool quality
True: full 16-level GC16.
bool present
False: nothing changed; do not flush.
Everything ez_scene_init needs: storage and framebuffer geometry.
ra8_tile_key_t * keys
k_ez_cells key entries.
int32_t fb_h
Framebuffer height, pixels.
uint8_t * packed
k_ez_packed_bytes packed strip.
int32_t * buckets
k_ez_buckets hash-bucket heads.
int32_t fb_w
Framebuffer width, pixels.
uint8_t * cell_mem
k_ez_cells * k_ez_cell_bytes bytes.
uint32_t fb_bytes
Framebuffer size, bytes.
uint8_t * row
k_ez_row_bytes composite row.
ra8_tile_dims_t * dims
k_ez_cells dimension entries.
ra8_keycache_cell_t * meta
k_ez_cells link-metadata entries.
void * fb
Framebuffer base (hashed by the golden).
uint8_t * strip
k_ez_strip_bytes composite strip.
The whole demo: one tiled page, one zoom viewport, one loupe.
ra8_ui_rect_t content
The content rectangle (page.dst).
zoom_view_t lens
Loupe over the same page, magnified more.
ra8_tile_cache_t cache
Page cache (decode-on-miss = the sampler).
zoom_tile_src_t tiles
Tiled-source binding over that cache.
bool lens_on
The loupe is open.
zoom_source_t src
The page as a zoom source.
int32_t fb_h
Framebuffer height, pixels.
zoom_view_t page
Full-content zoom viewport.
const void * fb
Framebuffer base, for the golden hash.
int32_t fb_w
Framebuffer width, pixels.
uint32_t fb_bytes
Framebuffer size, bytes.
Deterministic boot self-check results (the app's golden numbers).
uint32_t misses
Tile-cache misses (decodes).
uint32_t crc_1x
Hash after the opening 1:1 render.
uint32_t crc_pan
Hash after one right-pan step at 1:1.
uint32_t evictions
Tile-cache evictions.
uint32_t crc_2x
Hash after zooming to 2x at a fixed point.
uint32_t crc_lens
Hash after opening the 4x loupe.
uint16_t warmed
Tiles warmed by the pan read-ahead.
uint32_t hits
Tile-cache hits over the whole sequence.
Caller-supplied storage + decoder for ra8_tile_cache_init.
Identifies one decoded image tile.
uint16_t tile_y
Tile row index (in tile units).
uint16_t tile_x
Tile column index (in tile units).
Axis-aligned rectangle in framebuffer pixel coordinates.
int32_t w
Width (pixels, >= 0).
int32_t h
Height (pixels, >= 0).
int32_t x
Left edge (pixels).
int32_t y
Top edge (pixels).
What the reader must flush, and with which waveform.
zoom_refresh_t refresh
Waveform class for that flush.
bool present
False: nothing changed, do not flush at all.
Caller-owned composite buffers – the module's entire memory footprint.
zoom_read_fn read
gray8 sub-rectangle reader (never NULL once bound).
ra8_tile_cache_t * cache
Borrowed, initialised tile cache.
Everything zoom_view_open needs; nothing it does not.
uint8_t scale
Current integer magnification.
Tap-to-zoom image viewer: viewport state machine + tiled magnifying render (#478).
@ k_zoom_policy_responsive
Fast during a burst, quality once settled.
ra8_err_t zoom_view_invalidate(zoom_view_t *v, uint32_t now_ms)
Declare the viewport's pixels stale for a reason the engine cannot see.
@ k_zoom_scale_min
1:1 – one source pixel per panel pixel.
ra8_err_t zoom_view_pan_dir(zoom_view_t *v, zoom_pan_t dir, uint32_t now_ms)
Pan by a discrete step in one direction (the tap-band interaction).
bool zoom_view_tick(zoom_view_t *v, uint32_t now_ms)
Advance the settle timer; promote a bi-level view to full quality.
ra8_err_t zoom_view_window(const zoom_view_t *v, ra8_ui_rect_t *out)
The source rectangle currently visible, in source pixels.
ra8_err_t zoom_view_present(zoom_view_t *v, zoom_present_t *out)
Take the pending flush plan, clearing it.
uint8_t zoom_scale_cycle(uint8_t scale, uint8_t min, uint8_t max)
Next magnification on the doubling ladder, wrapping back to the minimum.
ra8_err_t zoom_view_render(zoom_view_t *v)
Composite the visible window into the bound ra8_gfx framebuffer.
ra8_err_t zoom_view_open(zoom_view_t *v, const zoom_view_cfg_t *cfg)
Open a viewport onto a source, centred on a source-pixel focus.
@ k_zoom_refresh_quality
Settled: panel GC16 (all 16 levels, slow).
zoom_pan_t
Discrete pan direction for tap-band navigation.
@ k_zoom_pan_right
Viewport travels toward +x.
@ k_zoom_pan_left
Viewport travels toward -x.
@ k_zoom_pan_none
No movement.
@ k_zoom_pan_down
Viewport travels toward +y.
@ k_zoom_pan_up
Viewport travels toward -y.
ra8_err_t zoom_view_set_scale(zoom_view_t *v, uint8_t scale, int32_t focus_x, int32_t focus_y, uint32_t now_ms)
Set the magnification, keeping a panel point fixed under the finger.
Bind a tiled gray8 atlas behind an ra8_tile_cache as a zoom source (#478).
ra8_err_t zoom_tiles_prefetch(zoom_tile_src_t *ts, const zoom_view_t *v, zoom_pan_t dir, uint16_t max_tiles, uint16_t *out_warmed)
Warm the tiles one pan step beyond what a view currently shows.
ra8_err_t zoom_tile_src_bind(zoom_tile_src_t *ts, zoom_source_t *out)
Present a bound tiled image to the zoom engine as a zoom_source_t.
ra8_err_t zoom_tile_src_init(zoom_tile_src_t *ts, ra8_tile_cache_t *cache, uint32_t image_id, uint32_t width, uint32_t height, uint16_t tile_w, uint16_t tile_h)
Bind a tiled image and its cache, deriving the tile grid.