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

Tap-to-zoom demo scene: page sampler, viewports, chrome, self-check. More...

#include "ez_scene.h"
#include <stddef.h>
#include <stdint.h>
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_gfx.h"
#include "ra8_tile_cache.h"
#include "ra8_ui.h"
#include "zoom.h"
#include "zoom_tiles.h"
Include dependency graph for ez_scene.c:

Go to the source code of this file.

Enumerations

enum  ez_tone_t : uint32_t {
  k_ez_bg_lo = 140U ,
  k_ez_grad_shift = 4U ,
  k_ez_grad_mask = 63U ,
  k_ez_grad_wrap = 127U ,
  k_ez_ink = 24U ,
  k_ez_rule_mask = 31U ,
  k_ez_rule_thick = 3U ,
  k_ez_word_shift = 5U ,
  k_ez_word_mask = 7U ,
  k_ez_word_blank = 7U
}
 Gray8 tones and the shift/mask geometry of the procedural page. More...
enum  ez_chrome_t : uint32_t {
  k_ez_col_bar = 0x00222222U ,
  k_ez_col_ind = 0x00DDDDDDU ,
  k_ez_col_dim = 0x00555555U ,
  k_ez_col_lens = 0x00000000U
}
 Chrome colours, in the 0x00RRGGBB space ra8_gfx down-converts from. More...
enum  ez_fnv_t : uint32_t {
  k_ez_fnv_offset = 2166136261U ,
  k_ez_fnv_prime = 16777619U
}
 FNV-1a-32 parameters. More...
enum  ez_selftest_step_t : uint16_t {
  k_ez_st_focus_x = 700U ,
  k_ez_st_focus_y = 400U ,
  k_ez_st_scale = 2U ,
  k_ez_st_t0 = 0U
}
 The scripted self-check's fixed inputs. More...

Functions

uint8_t ez_page_sample (uint32_t x, uint32_t y)
 Sample the procedural full-resolution page at one pixel.
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.
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.
ra8_ui_rect_t ez_content_rect (int32_t fb_w, int32_t fb_h)
 The content rectangle: the panel less the status bar.
static ra8_ui_rect_t ez_lens_rect (ra8_ui_rect_t content)
 The loupe box: a square centred in the content rectangle.
static zoom_scratch_t ez_scratch_of (const ez_scene_cfg_t *cfg)
 Build the shared composite-scratch descriptor from a configuration.
static ra8_err_t ez_cfg_scratch_ok (const ez_scene_cfg_t *cfg)
 Validate the three composite-scratch pointers.
static ra8_err_t ez_cfg_ptrs_ok (const ez_scene_cfg_t *cfg)
 Validate the borrowed storage a scene configuration must carry.
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_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_init (ez_scene_t *s, const ez_scene_cfg_t *cfg)
 Wire the tile cache, the tiled source and both viewports.
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 bool ez_apply_pan (ez_scene_t *s, ez_zone_t zone, uint32_t now_ms)
 Apply a pan zone to the page viewport.
bool ez_scene_tap (ez_scene_t *s, int32_t x, int32_t y, uint32_t now_ms)
 Apply a tap to the scene.
static ra8_err_t ez_draw_status (const ez_scene_t *s)
 Paint the status bar and its block zoom indicator.
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.
ra8_err_t ez_scene_render (ez_scene_t *s)
 Repaint the content area, the loupe (when open) and the status bar.
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.
ra8_err_t ez_scene_present (ez_scene_t *s, ez_present_t *out)
 Take the pending flush plan for whichever view changed.
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.
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_render_and_hash (ez_scene_t *s, uint32_t *out_hash)
 Render the scene and hash the framebuffer it produced.
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.
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.
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 ra8_err_t ez_selftest_stages (ez_scene_t *s, ez_selftest_t *out)
 Run the four scripted self-check stages in order.
ra8_err_t ez_scene_selftest (ez_scene_t *s, ez_selftest_t *out)
 Drive the scene through the scripted boot self-check.

Variables

static const char *const s_tag = "ereader_zoom"
 Component tag for RA8_CHECK_* log lines.

Detailed Description

Tap-to-zoom demo scene: page sampler, viewports, chrome, self-check.

Tag
[Ring 7 / App] {World: NS}

Implements ez_scene.h. Every pixel this file puts on the panel comes from integer arithmetic – the procedural page sampler, the zoom composite, and filled rectangles for the chrome – so the framebuffer hash it reports is the same number on the unit-test host, in ra8_emulator, and on silicon.

Since
0.1.0

Definition in file ez_scene.c.

Enumeration Type Documentation

◆ ez_chrome_t

enum ez_chrome_t : uint32_t

Chrome colours, in the 0x00RRGGBB space ra8_gfx down-converts from.

Grey levels on the panel's 16-level palette (multiples of 17 replicated across the three channels) so the chrome never dithers.

Invariant
Every value is an opaque 0x00RRGGBB triple.
Example:
(void)ra8_gfx_rect(0, 0, w, k_ez_status_h, (uint32_t)k_ez_col_bar, true);
@ k_ez_col_bar
Status-bar fill.
Definition ez_scene.c:113
@ k_ez_status_h
Status bar height, pixels.
Definition ez_scene.h:95
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.
See also
ez_draw_chrome
Since
0.1.0
Enumerator
k_ez_col_bar 

Status-bar fill.

k_ez_col_ind 

Lit zoom-indicator block.

k_ez_col_dim 

Unlit zoom-indicator block.

k_ez_col_lens 

Loupe border.

Definition at line 112 of file ez_scene.c.

◆ ez_fnv_t

enum ez_fnv_t : uint32_t

FNV-1a-32 parameters.

The standard 32-bit offset basis and prime; named so the hash is not two unexplained constants in the middle of a loop.

Invariant
k_ez_fnv_prime is the 32-bit FNV prime, 16777619.
Example:
uint32_t h = (uint32_t)k_ez_fnv_offset;
@ k_ez_fnv_offset
FNV-1a-32 offset basis.
Definition ez_scene.c:133
See also
ez_fnv1a
Since
0.1.0
Enumerator
k_ez_fnv_offset 

FNV-1a-32 offset basis.

k_ez_fnv_prime 

FNV-1a-32 prime.

Definition at line 132 of file ez_scene.c.

◆ ez_selftest_step_t

enum ez_selftest_step_t : uint16_t

The scripted self-check's fixed inputs.

Held as named constants so the app, the host twin and hil.conf cannot drift on "which pan, which focus point": the sequence is part of the golden, not an incidental of whoever wrote the test.

Invariant
k_ez_st_focus_x / _y lie inside the content rectangle.
Example:
@ k_ez_st_focus_y
Panel row the 2x step keeps fixed.
Definition ez_scene.c:153
@ k_ez_st_scale
Magnification the 2x step selects.
Definition ez_scene.c:154
@ k_ez_st_focus_x
Panel column the 2x step keeps fixed.
Definition ez_scene.c:152
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.
Definition zoom.c:556
See also
ez_scene_selftest
Since
0.1.0
Enumerator
k_ez_st_focus_x 

Panel column the 2x step keeps fixed.

k_ez_st_focus_y 

Panel row the 2x step keeps fixed.

k_ez_st_scale 

Magnification the 2x step selects.

k_ez_st_t0 

Timestamp handed to every step (ms).

Definition at line 151 of file ez_scene.c.

◆ ez_tone_t

enum ez_tone_t : uint32_t

Gray8 tones and the shift/mask geometry of the procedural page.

The background is a triangle wave whose full cycle is (1 << k_ez_grad_shift) * (k_ez_grad_wrap + 1) = 2048 px along the diagonal – a 64-level swing across roughly a screen, which a 16-level panel would band visibly without the blue-noise dither, and which is exactly what the demo is showing. A triangle rather than a sawtooth because a sawtooth's wrap is a genuine tone discontinuity in the source and would be mistaken for the artefact. The rules are 3 px tall on a 32 px pitch with one blank run in eight, so at 1:1 they read as texture and at 4x as structure.

Invariant
k_ez_bg_lo + k_ez_grad_mask <= 255.
k_ez_grad_wrap == (2 * k_ez_grad_mask) + 1.
Example:
const uint32_t phase = ((x >> k_ez_grad_shift) + (y >> k_ez_grad_shift)) & k_ez_grad_wrap;
@ k_ez_grad_shift
Pixels per gradient step (1 << shift).
Definition ez_scene.c:88
@ k_ez_grad_wrap
Triangle-wave period - 1 (2 * span + 1).
Definition ez_scene.c:90
See also
ez_page_sample
Since
0.1.0
Enumerator
k_ez_bg_lo 

Darkest background tone.

k_ez_grad_shift 

Pixels per gradient step (1 << shift).

k_ez_grad_mask 

Gradient span above k_ez_bg_lo.

k_ez_grad_wrap 

Triangle-wave period - 1 (2 * span + 1).

k_ez_ink 

Rule (text) tone.

k_ez_rule_mask 

Rule pitch - 1, rows.

k_ez_rule_thick 

Rule thickness, rows.

k_ez_word_shift 

Word run length (1 << shift), columns.

k_ez_word_mask 

Words per group - 1 (one blank per group).

k_ez_word_blank 

Group index left blank (the inter-word gap).

Definition at line 86 of file ez_scene.c.

Function Documentation

◆ ez_apply_pan()

bool ez_apply_pan ( ez_scene_t * s,
ez_zone_t zone,
uint32_t now_ms )
static

Apply a pan zone to the page viewport.

Parameters
[in,out]sInitialised scene.
[in]zoneA pan zone (any other zone is a no-op).
[in]now_msCurrent millisecond timestamp.
Returns
Whether the page anchor moved.
Return values
trueThe page panned; a redraw is due.
falseThe pan clamped against an edge, or the zone was not a pan.
Precondition
s was initialised by ez_scene_init.
now_ms comes from a monotonic millisecond source.
Postcondition
A true return leaves the page view owing a flush.
The read-ahead is only issued for a pan that actually moved.
Note
Not thread-safe.
Since
0.1.0

Definition at line 496 of file ez_scene.c.

References ez_scene_prefetch(), k_ez_zone_pan_down, k_ez_zone_pan_left, k_ez_zone_pan_right, k_ez_zone_pan_up, k_ra8_ok, k_zoom_pan_down, k_zoom_pan_left, k_zoom_pan_none, k_zoom_pan_right, k_zoom_pan_up, ez_scene_t::page, ra8_ui_rect_t::x, ra8_ui_rect_t::y, zoom_view_pan_dir(), and zoom_view_window().

Referenced by ez_scene_tap().

◆ ez_bind_page()

ra8_err_t ez_bind_page ( ez_scene_t * s,
const ez_scene_cfg_t * cfg )
static

Wire the tile cache over the borrowed storage and bind it as a source.

Split out of ez_scene_init so that function reads as "validate, lay out, bind the page, open the views". The tile grid is derived by zoom_tile_src_init from the page extent rather than passed in, so it cannot disagree with the geometry it is meant to cover.

Parameters
[in,out]sScene whose layout is already computed.
[in]cfgValidated configuration supplying the cache storage.
Returns
ra8_err_t Error code.
Return values
k_ra8_oks->src is a bound, magnifiable page.
k_ra8_err_*Propagated from the tile cache or the tiled adapter.
Precondition
cfg passed ez_cfg_ptrs_ok.
Every borrowed buffer outlives the scene.
Postcondition
On k_ra8_ok the cache is empty and every cell is cold.
On any error s holds no usable source.
Note
Not thread-safe.
Since
0.1.0

Definition at line 403 of file ez_scene.c.

References ez_scene_cfg_t::buckets, ez_scene_t::cache, ez_scene_cfg_t::cell_mem, ez_scene_cfg_t::dims, ez_tile_decode(), k_ez_buckets, k_ez_cell_bytes, k_ez_cells, k_ez_image_id, k_ez_page_h, k_ez_page_w, k_ez_tile_edge, ez_scene_cfg_t::keys, ez_scene_cfg_t::meta, RA8_RETURN_ON_ERROR, ra8_tile_cache_init(), s_tag, ez_scene_t::src, ez_scene_t::tiles, zoom_tile_src_bind(), and zoom_tile_src_init().

Referenced by ez_scene_init().

◆ ez_cfg_ptrs_ok()

ra8_err_t ez_cfg_ptrs_ok ( const ez_scene_cfg_t * cfg)
static

Validate the borrowed storage a scene configuration must carry.

Parameters
[in]cfgCandidate configuration (already known non-NULL).
Returns
ra8_err_t Error code.
Return values
k_ra8_okEvery pointer is present.
k_ra8_err_null_ptrOne is missing; the log line names it.
Precondition
cfg is non-NULL.
Nothing in cfg has been published into a scene yet.
Postcondition
No state is modified.
On k_ra8_ok all eight storage pointers are non-NULL.
Note
Not thread-safe (logs).
Since
0.1.0

Definition at line 329 of file ez_scene.c.

References ez_scene_cfg_t::buckets, ez_scene_cfg_t::cell_mem, ez_scene_cfg_t::dims, ez_cfg_scratch_ok(), ez_scene_cfg_t::fb, ez_scene_cfg_t::keys, ez_scene_cfg_t::meta, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by ez_scene_init().

◆ ez_cfg_scratch_ok()

ra8_err_t ez_cfg_scratch_ok ( const ez_scene_cfg_t * cfg)
static

Validate the three composite-scratch pointers.

The second half of ez_cfg_ptrs_ok, split only so each stays inside the project's function-size bar – every RA8_CHECK_NULL_PTR is several statements once expanded, so eight of them in one function is over the ceiling on their own.

Parameters
[in]cfgCandidate configuration (already known non-NULL).
Returns
ra8_err_t Error code.
Return values
k_ra8_okAll three scratch pointers are present.
k_ra8_err_null_ptrOne is missing; the log line names it.
Precondition
cfg is non-NULL.
The cache-storage half has already passed.
Postcondition
No state is modified.
On k_ra8_ok the composite can be bound to both viewports.
Note
Not thread-safe (logs).
Since
0.1.0

Definition at line 308 of file ez_scene.c.

References k_ra8_ok, ez_scene_cfg_t::packed, RA8_CHECK_NULL_PTR, ez_scene_cfg_t::row, s_tag, and ez_scene_cfg_t::strip.

Referenced by ez_cfg_ptrs_ok().

◆ ez_choose_plan()

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

Pick the flush rectangle from the two views' drained plans.

The page wins when it owes anything, because the loupe is drawn over page pixels and a page repaint therefore damages the lens box too. Only when the page owes nothing does a loupe-only change get to ask for the small rectangle – which is the partial-update case the demo exists to show.

Parameters
[in]sInitialised scene.
[in]page_planThe page view's drained plan.
[in]lens_planThe loupe's drained plan.
[out]outReceives the scene-level plan.
Returns
Nothing.
Precondition
Both plans were just drained by zoom_view_present.
out addresses writable storage.
Postcondition
out->present is false when neither view owed anything.
When out->present is true, out->rect is the smallest correct flush.
Note
Not thread-safe.
Since
0.1.0

Definition at line 655 of file ez_scene.c.

References ez_scene_t::content, ez_lens_rect(), k_zoom_refresh_quality, ez_scene_t::lens_on, ez_present_t::present, zoom_present_t::present, ez_present_t::quality, ez_present_t::rect, and zoom_present_t::refresh.

Referenced by ez_scene_present().

◆ ez_content_rect()

ra8_ui_rect_t ez_content_rect ( int32_t fb_w,
int32_t fb_h )
nodiscard

The content rectangle: the panel less the status bar.

Parameters
[in]fb_wFramebuffer width, pixels.
[in]fb_hFramebuffer height, pixels.
Returns
The content rectangle in framebuffer coordinates.
Return values
{0, k_ez_status_h, fb_w, fb_h - k_ez_status_h}Always.
Precondition
fb_h exceeds k_ez_status_h.
fb_w is positive.
Postcondition
The result's height is positive.
No state is modified (pure function).
Note
Pure; thread-safe.
See also
ez_scene_init
Since
0.1.0

Definition at line 232 of file ez_scene.c.

References k_ez_status_h.

Referenced by ez_scene_init(), and main().

◆ ez_draw_lens_chrome()

ra8_err_t ez_draw_lens_chrome ( ra8_ui_rect_t lens)
static

Paint the loupe's border so the lens reads as a lens, not a seam.

Parameters
[in]lensThe lens rectangle.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe border is painted.
k_ra8_err_*Propagated from ra8_gfx_rect.
Precondition
ra8_gfx_init has bound the framebuffer.
lens lies inside the framebuffer.
Postcondition
Only the k_ez_lens_border-thick frame of lens is written.
The magnified pixels inside the frame are left untouched.
Note
Not thread-safe; writes the ra8_gfx framebuffer binding.
Since
0.1.0

Definition at line 609 of file ez_scene.c.

References ra8_ui_rect_t::h, k_ez_col_lens, k_ez_lens_border, k_ra8_ok, ra8_gfx_rect(), RA8_RETURN_ON_ERROR, s_tag, ra8_ui_rect_t::w, ra8_ui_rect_t::x, and ra8_ui_rect_t::y.

Referenced by ez_scene_render().

◆ ez_draw_status()

ra8_err_t ez_draw_status ( const ez_scene_t * s)
static

Paint the status bar and its block zoom indicator.

Parameters
[in]sInitialised scene.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe bar is painted.
k_ra8_err_*Propagated from ra8_gfx_rect.
Precondition
ra8_gfx_init has bound the framebuffer.
s was initialised by ez_scene_init.
Postcondition
The bar shows one lit block per magnification step of the page view.
No pixel outside the status bar is written.
Note
Not thread-safe; writes the ra8_gfx framebuffer binding. Deliberately glyph-free so the framebuffer hash stays toolchain-independent.
Since
0.1.0

Definition at line 573 of file ez_scene.c.

References ez_scene_t::fb_w, k_ez_col_bar, k_ez_col_dim, k_ez_col_ind, k_ez_ind_block, k_ez_ind_gap, k_ez_page_scale_max, k_ez_status_h, k_ra8_ok, ez_scene_t::page, ra8_gfx_rect(), RA8_RETURN_ON_ERROR, s_tag, and zoom_view_t::scale.

Referenced by ez_scene_render().

◆ ez_fill_tile()

void ez_fill_tile ( uint8_t * cell,
uint32_t org_x,
uint32_t org_y )
static

Write one whole tile's pixels from the procedural page sampler.

Split out of ez_tile_decode so the decode entry point is its five precondition checks and nothing else. The offset is computed in size_t because a tile index times the tile edge is a pointer offset, and doing that arithmetic in 32 bits before the implicit widening is how a large image silently wraps.

Parameters
[out]cellDestination cell, at least k_ez_cell_bytes writable bytes.
[in]org_xTile origin column in page pixels.
[in]org_yTile origin row in page pixels.
Returns
Nothing.
Precondition
cell addresses at least k_ez_cell_bytes writable bytes.
The tile origin lies inside the page.
Postcondition
Every byte of the tile holds its sampled page value.
Nothing outside the tile is written.
Note
Not thread-safe (writes cell); otherwise pure.
Since
0.1.0

Definition at line 194 of file ez_scene.c.

References ez_page_sample(), and k_ez_tile_edge.

Referenced by ez_tile_decode().

◆ ez_fnv1a()

uint32_t ez_fnv1a ( const void * buf,
uint32_t len )
nodiscard

FNV-1a-32 over a byte range (the framebuffer hash).

Parameters
[in]bufBytes to hash (NULL hashes nothing).
[in]lenByte count.
Returns
The FNV-1a-32 digest.
Return values
2166136261buf is NULL or len is 0 (the FNV offset basis).
digestOtherwise, the hash of the range.
Precondition
buf addresses at least len readable bytes.
The range is deterministic (integer-rendered pixels only).
Postcondition
No state is modified (pure function).
The result depends only on the bytes, not on their address.
Note
Pure; thread-safe.
See also
ez_scene_selftest
Since
0.1.0

Definition at line 712 of file ez_scene.c.

References k_ez_fnv_offset, and k_ez_fnv_prime.

Referenced by ez_render_and_hash().

◆ ez_lens_rect()

ra8_ui_rect_t ez_lens_rect ( ra8_ui_rect_t content)
static

The loupe box: a square centred in the content rectangle.

Parameters
[in]contentThe content rectangle.
Returns
The lens rectangle in framebuffer coordinates.
Return values
centred squareAlways k_ez_lens_edge on a side.
Precondition
content is at least k_ez_lens_edge on both axes.
content is the rectangle the page view paints.
Postcondition
The result lies wholly inside content.
No state is modified (pure function).
Note
Pure; thread-safe.
Since
0.1.0

Definition at line 255 of file ez_scene.c.

References ra8_ui_rect_t::h, k_ez_lens_edge, ra8_ui_rect_t::w, ra8_ui_rect_t::x, and ra8_ui_rect_t::y.

Referenced by ez_choose_plan(), ez_open_views(), ez_scene_render(), and ez_zone_hit().

◆ ez_open_views()

ra8_err_t ez_open_views ( ez_scene_t * s,
const ez_scene_cfg_t * cfg )
static

Open both viewports over the bound page source.

Parameters
[in,out]sScene whose cache and source are already wired.
[in]cfgScene configuration (for the scratch buffers).
Returns
ra8_err_t Error code.
Return values
k_ra8_okBoth views are open and owe a quality flush.
k_ra8_err_*Propagated from zoom_view_open.
Precondition
s->src is bound and s->content is set.
The scratch buffers outlive the scene.
Postcondition
On k_ra8_ok the page view covers s->content and the loupe sits inside it.
On any error neither view is left half-open.
Note
Not thread-safe.
Since
0.1.0

Definition at line 354 of file ez_scene.c.

References ez_scene_t::content, ez_lens_rect(), ez_scratch_of(), k_ez_lens_scale_max, k_ez_lens_scale_min, k_ez_page_scale_max, k_zoom_policy_responsive, k_zoom_scale_min, ez_scene_t::lens, ez_scene_t::page, RA8_RETURN_ON_ERROR, s_tag, ez_scene_t::src, and zoom_view_open().

Referenced by ez_scene_init().

◆ ez_page_sample()

uint8_t ez_page_sample ( uint32_t x,
uint32_t y )
nodiscard

Sample the procedural full-resolution page at one pixel.

A page of "text": a repeating smooth gradient (which only a dither can render on a 16-level panel without banding) overlaid with 3 px rules broken into word-like runs (which only full-resolution magnification can resolve). Every operation is a shift or a mask, so decoding a 256x256 tile is cheap enough to stay inside the emulator's boot budget.

Parameters
[in]xSource column, < k_ez_page_w.
[in]ySource row, < k_ez_page_h.
Returns
The gray8 sample.
Return values
inkThe pixel falls on an inked rule (a dark constant).
backgroundOtherwise, the gradient value at (x, y).
Precondition
x and y are inside the page (the caller is the tile decoder).
No global state is consulted.
Postcondition
The result is a valid gray8 value.
No state is modified (pure function).
Note
Pure; thread-safe.
See also
ez_tile_decode
Since
0.1.0

Definition at line 158 of file ez_scene.c.

References k_ez_bg_lo, k_ez_grad_mask, k_ez_grad_shift, k_ez_grad_wrap, k_ez_ink, k_ez_rule_mask, k_ez_rule_thick, k_ez_word_blank, k_ez_word_mask, and k_ez_word_shift.

Referenced by ez_fill_tile().

◆ ez_render_and_hash()

ra8_err_t ez_render_and_hash ( ez_scene_t * s,
uint32_t * out_hash )
static

Render the scene and hash the framebuffer it produced.

Parameters
[in,out]sInitialised scene.
[out]out_hashReceives the FNV-1a-32 of the whole framebuffer.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe frame was painted and hashed.
k_ra8_err_*Propagated from ez_scene_render or ra8_gfx.
Precondition
ra8_gfx_init has bound the framebuffer.
out_hash is writable.
Postcondition
On k_ra8_ok the framebuffer holds the rendered frame.
The pending flush is consumed, so the next step starts clean.
Note
Not thread-safe.
Since
0.1.0

Definition at line 740 of file ez_scene.c.

References ez_fnv1a(), ez_scene_present(), ez_scene_render(), ez_scene_t::fb, ez_scene_t::fb_bytes, k_ra8_ok, RA8_RETURN_ON_ERROR, and s_tag.

Referenced by ez_selftest_lens(), ez_selftest_pan(), ez_selftest_stages(), and ez_selftest_zoom().

◆ ez_scene_init()

ra8_err_t ez_scene_init ( ez_scene_t * s,
const ez_scene_cfg_t * cfg )
nodiscard

Wire the tile cache, the tiled source and both viewports.

Parameters
[out]sScene to populate.
[in]cfgBorrowed storage and framebuffer geometry.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe scene is ready to render.
k_ra8_err_null_ptrs, cfg, or a required storage pointer is NULL.
k_ra8_err_invalid_argThe framebuffer is too small for the layout.
k_ra8_err_*Propagated from the cache or the zoom engine.
Precondition
Every pointer in cfg outlives the scene.
ra8_gfx_init has bound the same framebuffer the scene will paint.
Postcondition
On k_ra8_ok both views are open and owe a quality flush.
On any error the scene is not left half-built (lens_on is false).
Note
Not thread-safe.
See also
ez_scene_render
Since
0.1.0

Definition at line 430 of file ez_scene.c.

References ez_scene_t::content, ez_bind_page(), ez_cfg_ptrs_ok(), ez_content_rect(), ez_open_views(), ez_scene_cfg_t::fb, ez_scene_t::fb, ez_scene_cfg_t::fb_bytes, ez_scene_t::fb_bytes, ez_scene_cfg_t::fb_h, ez_scene_t::fb_h, ez_scene_cfg_t::fb_w, ez_scene_t::fb_w, k_ez_lens_edge, k_ez_status_h, k_ra8_err_invalid_arg, ez_scene_t::lens_on, RA8_CHECK_NULL_PTR, ra8_log_error, RA8_RETURN_ON_ERROR, and s_tag.

Referenced by ez_setup_scene().

◆ ez_scene_prefetch()

ra8_err_t ez_scene_prefetch ( ez_scene_t * s,
zoom_pan_t dir,
uint16_t * out_warmed )
nodiscard

Warm the tiles one pan step ahead of the page viewport.

Parameters
[in,out]sInitialised scene.
[in]dirDirection of travel.
[out]out_warmedTiles warmed (may be NULL).
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe read-ahead sweep ran.
k_ra8_err_null_ptrs is NULL.
k_ra8_err_*Propagated from zoom_tiles_prefetch.
Precondition
s was initialised by ez_scene_init.
The caller is in an idle window (read-ahead is not free).
Postcondition
No on-screen tile is evicted (k_ez_prefetch_max is the spare margin).
*out_warmed (when given) is at most k_ez_prefetch_max.
Note
Not thread-safe.
See also
zoom_tiles_prefetch
Since
0.1.0

Definition at line 705 of file ez_scene.c.

References zoom_tile_src_t::cache, k_ez_prefetch_max, ez_scene_t::page, RA8_CHECK_NULL_PTR, s_tag, ez_scene_t::tiles, and zoom_tiles_prefetch().

Referenced by ez_apply_pan(), and ez_selftest_pan().

◆ ez_scene_present()

ra8_err_t ez_scene_present ( ez_scene_t * s,
ez_present_t * out )
nodiscard

Take the pending flush plan for whichever view changed.

A page change dirties the whole content rectangle; a loupe-only change dirties only the lens box, which is the partial-update case this demo exists to show. A view that owes nothing contributes nothing, so an idle reader never refreshes the panel.

Parameters
[in,out]sInitialised scene.
[out]outReceives the plan; out->present is false when none is owed.
Returns
ra8_err_t Error code.
Return values
k_ra8_okout holds the plan.
k_ra8_err_null_ptrs or out is NULL.
k_ra8_err_*Propagated from zoom_view_present.
Precondition
The framebuffer already holds the pixels this plan describes.
s was initialised by ez_scene_init.
Postcondition
Neither view still owes the flush this call reported.
A second immediate call reports present == false.
Note
Not thread-safe.
See also
ez_scene_render
Since
0.1.0

Definition at line 677 of file ez_scene.c.

References ez_choose_plan(), k_ra8_ok, ez_scene_t::lens, ez_scene_t::page, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, s_tag, and zoom_view_present().

Referenced by ez_redraw(), and ez_render_and_hash().

◆ ez_scene_render()

ra8_err_t ez_scene_render ( ez_scene_t * s)
nodiscard

Repaint the content area, the loupe (when open) and the status bar.

Parameters
[in,out]sInitialised scene.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe framebuffer holds the current scene.
k_ra8_err_null_ptrs is NULL.
k_ra8_err_*Propagated from zoom_view_render or ra8_gfx.
Precondition
ra8_gfx_init has bound the framebuffer.
s was initialised by ez_scene_init.
Postcondition
On k_ra8_ok every pixel of the panel has been written.
The ra8_gfx clip rectangle is reset to the whole framebuffer.
Note
Not thread-safe; writes the single ra8_gfx framebuffer binding.
See also
ez_scene_present
Since
0.1.0

Definition at line 624 of file ez_scene.c.

References ez_scene_t::content, ez_draw_lens_chrome(), ez_draw_status(), ez_lens_rect(), ez_scene_t::lens, ez_scene_t::lens_on, ez_scene_t::page, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, zoom_source_t::read, s_tag, ez_scene_t::src, and zoom_view_render().

Referenced by ez_redraw(), and ez_render_and_hash().

◆ ez_scene_selftest()

ra8_err_t ez_scene_selftest ( ez_scene_t * s,
ez_selftest_t * out )
nodiscard

Drive the scene through the scripted boot self-check.

Four states – opening 1:1, one right-pan step, 2x about a fixed panel point, and the 4x loupe – each rendered and hashed. This is the app's golden: apps/board/stand_alone/ereader/tests/src/test_app_ereader_zoom.c calls this same function over a host framebuffer and asserts the identical numbers, and hil.conf pins them for the headless emulator gate.

Parameters
[in,out]sInitialised scene (left in the loupe state on return).
[out]outReceives the four hashes and the cache counters.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe sequence ran and out is populated.
k_ra8_err_null_ptrs or out is NULL.
k_ra8_err_*Propagated from a render or a viewport call.
Precondition
ra8_gfx_init has bound the framebuffer the hashes cover.
s was freshly initialised (the counters start from zero).
Postcondition
On k_ra8_ok the framebuffer holds the final (loupe) state.
On k_ra8_ok every counter in out reflects the whole sequence.
Note
Not thread-safe.
See also
ez_fnv1a
Since
0.1.0

Definition at line 861 of file ez_scene.c.

References ez_scene_t::cache, ez_selftest_t::evictions, ez_selftest_stages(), ez_selftest_t::hits, ez_selftest_t::misses, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, ra8_tile_cache_stats(), and s_tag.

Referenced by main().

◆ ez_scene_tap()

bool ez_scene_tap ( ez_scene_t * s,
int32_t x,
int32_t y,
uint32_t now_ms )
nodiscard

Apply a tap to the scene.

Parameters
[in,out]sInitialised scene.
[in]xFramebuffer column of the tap.
[in]yFramebuffer row of the tap.
[in]now_msCurrent millisecond timestamp.
Returns
Whether anything changed and a redraw is due.
Return values
trueThe scene changed; re-render and present.
falseThe tap hit nothing, or clamped to no movement.
Precondition
s was initialised by ez_scene_init (NULL answers false).
now_ms comes from a monotonic millisecond source.
Postcondition
A true return leaves at least one view owing a flush.
A false return leaves the scene byte-identical.
Note
Not thread-safe.
See also
ez_zone_hit
Since
0.1.0

Definition at line 531 of file ez_scene.c.

References ez_apply_pan(), ez_zone_hit(), k_ez_lens_scale_max, k_ez_lens_scale_min, k_ez_page_scale_max, k_ez_zone_lens, k_ez_zone_toggle, k_ez_zone_zoom, k_ra8_ok, k_zoom_scale_min, ez_scene_t::lens, ez_scene_t::lens_on, ez_scene_t::page, zoom_view_t::scale, zoom_scale_cycle(), zoom_view_invalidate(), and zoom_view_set_scale().

Referenced by ez_poll_touch().

◆ ez_scene_tick()

bool ez_scene_tick ( ez_scene_t * s,
uint32_t now_ms )

Advance both views' settle timers; report whether a repaint is due.

Parameters
[in,out]sInitialised scene.
[in]now_msCurrent millisecond timestamp.
Returns
Whether a full-quality repaint just became due.
Return values
trueRe-render and present.
falseNothing to do this tick.
Precondition
s was initialised by ez_scene_init (NULL answers false).
now_ms comes from a monotonic millisecond source.
Postcondition
A true return leaves a view owing a quality flush.
A false return leaves the scene unmodified.
Note
Not thread-safe.
See also
zoom_view_tick
Since
0.1.0

Definition at line 689 of file ez_scene.c.

References ez_scene_t::lens, ez_scene_t::lens_on, ez_scene_t::page, and zoom_view_tick().

Referenced by main().

◆ ez_scratch_of()

zoom_scratch_t ez_scratch_of ( const ez_scene_cfg_t * cfg)
static

Build the shared composite-scratch descriptor from a configuration.

Parameters
[in]cfgScene configuration holding the three borrowed buffers.
Returns
The scratch descriptor both viewports use.
Return values
descriptorAlways; validation happens in zoom_view_open().
Precondition
Every scratch pointer in cfg is non-NULL.
The buffers outlive the scene.
Postcondition
The descriptor's capacities match the ez_scratch_t enum.
No state is modified.
Note
Pure; thread-safe.
Since
0.1.0

Definition at line 278 of file ez_scene.c.

References k_ez_packed_bytes, k_ez_row_bytes, k_ez_strip_bytes, ez_scene_cfg_t::packed, ez_scene_cfg_t::row, and ez_scene_cfg_t::strip.

Referenced by ez_open_views().

◆ ez_selftest_lens()

ra8_err_t ez_selftest_lens ( ez_scene_t * s,
ez_selftest_t * out )
static

Self-check stage 4: open the loupe over the magnified page.

Both views are invalidated explicitly. Opening the loupe moves no anchor and changes no scale, so neither view would otherwise know its pixels had been damaged – the seam this stage also regression- tests.

Parameters
[in,out]sInitialised scene.
[out]outReceives crc_lens.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe stage ran and the hash is set.
k_ra8_err_*Propagated from the viewport or the render.
Precondition
Stage 3 has already run.
ra8_gfx_init has bound the framebuffer the hash covers.
Postcondition
The loupe is open and drawn.
Both views owe nothing (the render drained their plans).
Note
Not thread-safe.
Since
0.1.0

Definition at line 823 of file ez_scene.c.

References ez_selftest_t::crc_lens, ez_render_and_hash(), k_ez_st_t0, ez_scene_t::lens, ez_scene_t::lens_on, ez_scene_t::page, RA8_RETURN_ON_ERROR, s_tag, and zoom_view_invalidate().

Referenced by ez_selftest_stages().

◆ ez_selftest_pan()

ra8_err_t ez_selftest_pan ( ez_scene_t * s,
ez_selftest_t * out )
static

Self-check stage 2: one right-pan step at 1:1, with read-ahead.

The pan is a full discrete step rather than a nudge, so it is the case the tile cache is sized for: the newly exposed column decodes and nothing still on screen is evicted.

Parameters
[in,out]sInitialised scene.
[out]outReceives crc_pan and warmed.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe stage ran and both fields are set.
k_ra8_err_*Propagated from the viewport, the prefetch or the render.
Precondition
Stage 1 has already rendered the opening view.
ra8_gfx_init has bound the framebuffer the hash covers.
Postcondition
The page viewport has advanced by one step.
out->warmed is at most k_ez_prefetch_max.
Note
Not thread-safe.
Since
0.1.0

Definition at line 766 of file ez_scene.c.

References ez_selftest_t::crc_pan, ez_render_and_hash(), ez_scene_prefetch(), k_ez_st_t0, k_zoom_pan_right, ez_scene_t::page, RA8_RETURN_ON_ERROR, s_tag, ez_selftest_t::warmed, and zoom_view_pan_dir().

Referenced by ez_selftest_stages().

◆ ez_selftest_stages()

ra8_err_t ez_selftest_stages ( ez_scene_t * s,
ez_selftest_t * out )
static

Run the four scripted self-check stages in order.

The order IS the golden: each stage starts from the state the last one left, so re-ordering them changes every hash after the first. Split from ez_scene_selftest so that entry point is its argument checks, this call, and the counter read.

Parameters
[in,out]sFreshly initialised scene.
[out]outReceives all four hashes and the prefetch count.
Returns
ra8_err_t Error code.
Return values
k_ra8_okAll four stages rendered and hashed.
k_ra8_err_*The first failing stage's code, verbatim.
Precondition
ra8_gfx_init has bound the framebuffer the hashes cover.
s was freshly initialised, so the cache counters start at zero.
Postcondition
On k_ra8_ok the framebuffer holds the final (loupe) state.
On failure the earlier stages' hashes are still valid.
Note
Not thread-safe.
Since
0.1.0

Definition at line 853 of file ez_scene.c.

References ez_selftest_t::crc_1x, ez_render_and_hash(), ez_selftest_lens(), ez_selftest_pan(), ez_selftest_zoom(), RA8_RETURN_ON_ERROR, and s_tag.

Referenced by ez_scene_selftest().

◆ ez_selftest_zoom()

ra8_err_t ez_selftest_zoom ( ez_scene_t * s,
ez_selftest_t * out )
static

Self-check stage 3: 2x about a fixed panel point.

The focus point is a named constant, not an incidental of whoever wrote the test, because the resulting hash is part of the golden.

Parameters
[in,out]sInitialised scene.
[out]outReceives crc_2x.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe stage ran and the hash is set.
k_ra8_err_*Propagated from the viewport or the render.
Precondition
Stage 2 has already run.
ra8_gfx_init has bound the framebuffer the hash covers.
Postcondition
The page view is at k_ez_st_scale.
The point at (k_ez_st_focus_x, k_ez_st_focus_y) is unmoved.
Note
Not thread-safe.
Since
0.1.0

Definition at line 793 of file ez_scene.c.

References ez_selftest_t::crc_2x, ez_render_and_hash(), k_ez_st_focus_x, k_ez_st_focus_y, k_ez_st_scale, k_ez_st_t0, ez_scene_t::page, RA8_RETURN_ON_ERROR, s_tag, and zoom_view_set_scale().

Referenced by ez_selftest_stages().

◆ ez_tile_decode()

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

ra8_tile_decode_fn that materialises one page tile from the sampler.

The decode-on-miss seam. A real reader inflates a JOF tile here; the demo computes it, which keeps the app free of a multi-megabyte baked fixture while exercising the identical cache, eviction and residency behaviour.

Parameters
[in]ctxUnused (the page is a pure function).
[in]keyThe tile being decoded.
[out]cellDestination cell, cell_bytes writable bytes.
[in]cell_bytesCapacity of cell.
[out]out_wReceives the decoded tile width.
[out]out_hReceives the decoded tile height.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe tile was written.
k_ra8_err_null_ptrkey, cell, out_w or out_h is NULL.
k_ra8_err_out_of_rangeThe key names a tile outside the page.
k_ra8_err_no_memcell_bytes is smaller than one tile.
Precondition
cell addresses at least cell_bytes writable bytes.
The cache was configured with cell_bytes >= k_ez_cell_bytes.
Postcondition
On k_ra8_ok *out_w == *out_h == k_ez_tile_edge.
On any error nothing is written past the failing check.
Note
Not thread-safe (writes cell); otherwise pure.
See also
ez_page_sample
Since
0.1.0

Definition at line 204 of file ez_scene.c.

References ez_fill_tile(), k_ez_cell_bytes, k_ez_page_h, k_ez_page_w, k_ez_tile_edge, k_ra8_err_no_mem, k_ra8_err_out_of_range, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_error, s_tag, ra8_tile_key_t::tile_x, and ra8_tile_key_t::tile_y.

Referenced by ez_bind_page().

◆ ez_zone_hit()

ez_zone_t ez_zone_hit ( const ez_scene_t * s,
int32_t x,
int32_t y )
nodiscard

Classify a tap by the zone it lands in.

Parameters
[in]sInitialised scene.
[in]xFramebuffer column of the tap.
[in]yFramebuffer row of the tap.
Returns
The zone under the point.
Return values
k_ez_zone_noneThe point is outside every zone.
a zoneOtherwise, the zone that owns the point.
Precondition
s was initialised by ez_scene_init (NULL answers none).
The coordinates are framebuffer pixels, not page-local.
Postcondition
No state is modified (pure query).
The loupe zone is only returned while the loupe is open.
Note
Pure with respect to s; thread-safe.
See also
ez_scene_tap
Since
0.1.0

Definition at line 451 of file ez_scene.c.

References ez_scene_t::content, ez_lens_rect(), ra8_ui_rect_t::h, k_ez_edge_band, k_ez_status_h, k_ez_zone_lens, k_ez_zone_none, k_ez_zone_pan_down, k_ez_zone_pan_left, k_ez_zone_pan_right, k_ez_zone_pan_up, k_ez_zone_toggle, k_ez_zone_zoom, ez_scene_t::lens_on, ra8_ui_rect_contains(), ra8_ui_rect_t::w, ra8_ui_rect_t::x, and ra8_ui_rect_t::y.

Referenced by ez_scene_tap().

Variable Documentation

◆ s_tag

const char* const s_tag = "ereader_zoom"
static

Component tag for RA8_CHECK_* log lines.

Definition at line 33 of file ez_scene.c.