26typedef enum :
size_t {
44 char temporary[] =
"/tmp/ra8-emu-present.XXXXXX";
45 const int fd = mkstemp(temporary);
50 const int unlink_result = unlink(temporary);
51 const int unlink_error = errno;
52 if ((unlink_result != 0) || (ftruncate(fd, (off_t)size) != 0)) {
53 *os_error = (unlink_result != 0) ? unlink_error : errno;
55 if (unlink_result != 0) {
56 (void)unlink(temporary);
92 size_t required_scratch,
93 size_t supplied_scratch,
97 .required_surface_bytes = surface,
98 .required_scratch_bytes = required_scratch,
99 .supplied_scratch_bytes = supplied_scratch,
100 .os_error = os_error};
118 if ((result ==
nullptr) || (right > (SIZE_MAX - left))) {
121 *result = left + right;
140 if ((result ==
nullptr) || ((left != 0U) && (right > (SIZE_MAX / left)))) {
143 *result = left * right;
179 if ((spec ==
nullptr) || (plan ==
nullptr) || (spec->
panel_width == 0U) ||
187 size_t composite_width = 0U;
194 size_t composite_pixels = 0U;
195 size_t surface_bytes = 0U;
206 size_t tile_pixels = 0U;
207 size_t tile_bytes = 0U;
208 size_t row_bytes = 0U;
214 size_t rotation_bytes = tile_bytes;
218 const size_t scratch_bytes = (row_bytes > rotation_bytes) ? row_bytes : rotation_bytes;
221 (composite_height > UINT16_MAX)) {
226 .display_width = display_width,
227 .display_height = display_height,
228 .composite_width = composite_width,
229 .composite_height = composite_height,
230 .surface_bytes = spec->
active ? surface_bytes : 0U,
231 .scratch_bytes = spec->
active ? scratch_bytes : 0U};
248 size_t supplied_scratch_bytes,
260 (((uintptr_t)scratch %
alignof(uint16_t)) != 0U)) {
267 supplied_scratch_bytes,
278 supplied_scratch_bytes,
291 .scratch = (uint16_t*)scratch,
299 supplied_scratch_bytes,
305 if (workspace ==
nullptr) {
308 const int fd = workspace->
fd;
310 return (fd < 0) || (close(fd) == 0);
318 if ((workspace ==
nullptr) || (workspace->
fd < 0) || (bytes ==
nullptr) ||
320 (offset > (
size_t)INT64_MAX)) {
331 if ((workspace ==
nullptr) || (workspace->
fd < 0) || (bytes ==
nullptr) ||
333 (offset > (
size_t)INT64_MAX)) {
347 if ((workspace ==
nullptr) || (width == 0U) || (height == 0U) ||
352 const size_t row_bytes = (size_t)width *
sizeof(uint16_t);
358 uint16_t*
const row = workspace->
scratch;
361 if (row ==
nullptr) {
364 for (uint16_t column = 0U; column < width; column++) {
367 for (uint16_t delta = 0U; delta < height; delta++) {
368 const size_t pixel_offset =
369 ((size_t)(y + delta) * (size_t)workspace->
composite_width) + (
size_t)x;
379 if ((workspace ==
nullptr) || (snapshot_fd ==
nullptr) || (workspace->
fd < 0) ||
390 for (
size_t offset = 0U; ok && (offset < workspace->
surface_bytes);) {
409 "maximum presentation scratch budget changed");
@ k_board_overlay_min_height_px
Minimum composite height.
@ k_board_overlay_sidebar_width_px
Pixels added right of panel.
Bounded raw-descriptor I/O seam for the RA8 emulator.
@ k_emu_io_ok
The complete operation succeeded.
emu_io_result_t priv_emu_io_pread_exact(int fd, void *buf, size_t count, off_t offset)
Read exactly count bytes at offset without changing the cursor.
emu_io_result_t priv_emu_io_pwrite_exact(int fd, const void *buf, size_t count, off_t offset)
Write exactly count bytes at offset without changing the cursor.
emu_presentation_result_t emu_presentation_requirements(const emu_presentation_spec_t *spec)
Compute exact raw-fd and scratch requirements without mutation.
bool emu_presentation_read(const emu_presentation_workspace_t *workspace, size_t offset, void *bytes, size_t count)
Read exact RGB565 bytes at a checked surface offset.
bool emu_presentation_write(emu_presentation_workspace_t *workspace, size_t offset, const void *bytes, size_t count)
Write exact RGB565 bytes at a checked surface offset.
static RA8_INTERNAL bool internal_multiply(size_t left, size_t right, size_t *result)
Checked size multiplication.
static RA8_INTERNAL emu_presentation_result_t internal_result(emu_presentation_status_t status, size_t surface, size_t required_scratch, size_t supplied_scratch, int os_error)
Construct a complete operation result.
static RA8_INTERNAL emu_presentation_status_t internal_plan(const emu_presentation_spec_t *spec, emu_presentation_plan_t *plan)
Compute all checked geometry and storage values.
bool emu_presentation_close(emu_presentation_workspace_t *workspace)
Close one owned presentation descriptor and invalidate the workspace.
static RA8_INTERNAL int internal_anonymous_fd(size_t size, int *os_error)
Create, unlink, and exactly size one anonymous temporary descriptor.
bool emu_presentation_snapshot(emu_presentation_workspace_t *workspace, int *snapshot_fd)
Create an immutable unlinked descriptor snapshot of one surface.
emu_presentation_result_t emu_presentation_open(const emu_presentation_spec_t *spec, void *scratch, size_t supplied_scratch_bytes, emu_presentation_workspace_t *workspace)
Create and bind one unlinked raw-fd presentation workspace.
presentation_invariant_t
Compile-time invariant values for presentation storage.
@ k_presentation_expected_scratch_bytes
Two maximum RGB565 tiles.
static RA8_INTERNAL bool internal_add(size_t left, size_t right, size_t *result)
Checked size addition.
bool emu_presentation_fill(void *context, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color)
Fill a checked RGB565 rectangle in a raw-fd surface.
static RA8_INTERNAL bool internal_rotation_valid(uint32_t rotation)
True for one supported clockwise rotation.
Bounded raw-descriptor presentation surface and scratch workspace.
emu_presentation_status_t
Presentation planning, creation, and transfer status.
@ k_emu_presentation_capacity
Caller scratch is smaller than required.
@ k_emu_presentation_overflow
A checked size/offset operation overflowed.
@ k_emu_presentation_invalid
Geometry, rotation, pointer, or fd invalid.
@ k_emu_presentation_ok
Operation completed exactly.
@ k_emu_presentation_io
Raw descriptor create/size/I/O failed.
@ k_emu_presentation_max_panel_px
Largest panel dimension.
@ k_emu_presentation_tile_px
Square rotation tile side.
@ k_emu_presentation_max_scratch_bytes
Exact maximum caller scratch: source plus rotated 64x64 RGB565 tiles.
Board-view presentation: frames, composition, input routing, panels.
@ k_rotate_0
Native orientation.
@ k_rotate_90
90 deg clockwise (-> portrait).
@ k_rotate_270
90 deg counter-clockwise.
@ k_rotate_180
Upside down.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
emu_io_status_t status
Semantic completion status.
Complete internal geometry and storage plan.
size_t panel_height
Native height.
size_t composite_width
Display plus sidebar.
size_t display_width
Rotation-adjusted width.
size_t composite_height
Display/sidebar maximum.
size_t panel_width
Native width.
size_t scratch_bytes
Exact tile/row scratch length.
size_t surface_bytes
Exact raw RGB565 surface length.
size_t display_height
Rotation-adjusted height.
Exact result of a requirements or workspace operation.
Inputs controlling exact presentation requirements.
size_t panel_height
Native firmware panel height.
size_t panel_width
Native firmware panel width.
uint32_t rotate_deg
Display rotation: 0, 90, 180, or 270 degrees.
bool active
A view, snapshot, record, or click needs pixels.
One independent owned surface plus non-owning bounded scratch.
uint16_t composite_width
Display plus sidebar width.
int fd
Owned unlinked descriptor, or -1.
uint16_t composite_height
Display/sidebar maximum height.
uint16_t * scratch
Borrowed RGB565 scratch, or nullptr.
size_t surface_bytes
Exact raw-fd RGB565 length.
size_t scratch_bytes
Exact bound scratch prefix.