|
rcbench
Servo and ESC test bench: panel, IOmcu and shared C
|
Screen rotation 180° in the flush: the UI draws its picture as it always does, and each flip copies what changed into the frame buffer the panel scans, turned, through a copy engine (on the ESP32-P4 the PPA, pixel-processing accelerator). More...
#include <stdatomic.h>#include <stdbool.h>#include <stdint.h>#include "gfx.h"#include "gfx_damage.h"Go to the source code of this file.
Data Structures | |
| struct | gfx_turn_ops_t |
| The copy engine. More... | |
| struct | gfx_turn_job_t |
| One block as the copy engine takes it: where it is read, where it lands turned, and the context the engine's done callback gets. More... | |
| struct | gfx_turn_engine_t |
| An engine that takes a job, ends it later in an interrupt that calls its done callback with the job's user_data, and is waited for: the PPA's shape. More... | |
| struct | gfx_turn_t |
| The rotation's state. More... | |
Macros | |
| #define | GFX_TURN_BUDGET_US 50000u |
| A flush's time for all its copies, us: 50ms. | |
| #define | GFX_TURN_FULL_FLIPS 2u |
| Flips that copy the whole picture after a switch, 2: one per frame buffer. | |
Enumerations | |
| enum | gfx_turn_copy_t { GFX_TURN_COPY_DONE = 0 , GFX_TURN_COPY_TIMEOUT , GFX_TURN_COPY_ERROR } |
| How one copy ended. More... | |
| enum | gfx_turn_fail_t { GFX_TURN_FAIL_NONE = 0 , GFX_TURN_FAIL_TIMEOUT , GFX_TURN_FAIL_ERROR , GFX_TURN_FAIL_ENGINE } |
| Why the flush fell back to NORMAL. More... | |
| enum | gfx_turn_show_t { GFX_TURN_SHOW_NORMAL = 0 , GFX_TURN_SHOW_TURNED , GFX_TURN_SHOW_FALLBACK } |
| What a flush leaves in the frame buffer. More... | |
Functions | |
| void | gfx_turn_init (gfx_turn_t *t, int width, int height) |
NORMAL, nothing failed, for a width x height picture; the shown flag NORMAL too. | |
| void | gfx_turn_request (gfx_turn_t *t, bool turned) |
| What the setting asks for; taken at the next gfx_turn_next(). | |
| void | gfx_turn_fail (gfx_turn_t *t, gfx_turn_fail_t why) |
| Fall back to NORMAL until the next start. | |
| bool | gfx_turn_drawing (const gfx_turn_t *t) |
| Whether the frame being drawn goes into a logical buffer. | |
| void | gfx_turn_begin (gfx_turn_t *t, const gfx_canvas_t *logical) |
Start a frame: drawing turned, the damage record bound to logical, empty and attached; NORMAL, no record attached. | |
| gfx_turn_show_t | gfx_turn_flush (gfx_turn_t *t, const gfx_color_t *logical, gfx_color_t *fb, const gfx_turn_ops_t *ops) |
End a frame: copy what it drew into fb, turned. | |
| bool | gfx_turn_presented (gfx_turn_t *t, gfx_turn_show_t show) |
| The frame of the last flush is on the glass: set the shown flag. | |
| void | gfx_turn_next (gfx_turn_t *t) |
| After a flip: take the request for the next frame. | |
| bool | gfx_turn_take_repaint (gfx_turn_t *t) |
| Whether the UI must repaint everything before the next frame; clears it. | |
| bool | gfx_turn_take_alert (gfx_turn_t *t) |
| Whether the fallback's alert is due; clears it. | |
| gfx_turn_copy_t | gfx_turn_engine_copy (const gfx_turn_engine_t *e, const gfx_color_t *src, gfx_color_t *dst, gfx_rect_t r, int width, int height, uint32_t budget_us) |
One block through e: the job built from r with e->done_ctx as its user_data, submitted and waited for. The copy function of a gfx_turn_ops_t calls it. | |
| static void * | gfx_turn_done_ctx (void *user_data) |
| The done callback's first step: the context it was given, or NULL, counted in gfx_turn_stray_dones(), when it was given none. Inline and one atomic add: callable from the engine's interrupt. | |
| uint32_t | gfx_turn_stray_dones (void) |
| Done callbacks that came with a NULL context since start-up. | |
| bool | gfx_turn_shown (void) |
| What the panel shows: the one flag picture and touch turn by. Read from any task. | |
Variables | |
| atomic_uint | gfx_turn_stray |
| Done callbacks that came with a NULL context; gfx_turn.c. | |
Screen rotation 180° in the flush: the UI draws its picture as it always does, and each flip copies what changed into the frame buffer the panel scans, turned, through a copy engine (on the ESP32-P4 the PPA, pixel-processing accelerator).
Turned, the UI draws into a logical buffer of its own, one per frame buffer, with a damage record attached (gfx_damage.h). gfx_turn_flush() copies the record's rectangles, turned, into the frame buffer of the same index; the whole picture for the GFX_TURN_FULL_FLIPS flips after a switch. NORMAL draws straight into the frame buffer and copies nothing.
One flag says what the panel shows: gfx_turn_shown(), set by gfx_turn_presented() once the frame is on the glass. The touch map turns from that flag, so picture and touch turn on the same frame.
A flush has GFX_TURN_BUDGET_US, 50ms, for all its copies. A copy that runs out of it or fails makes the flush copy the logical buffer as it stands into the frame buffer, unturned, and present that: picture and touch fall back to NORMAL together. The fallback holds until the next start (gfx_turn_init()); the stored setting stays as it is. A copy the engine finishes after its timeout writes its block once more; that block shows turned until the screen repaints it.
Every call but gfx_turn_shown() comes from the task that draws and flips.
SPDX-License-Identifier: MIT
| enum gfx_turn_copy_t |
| enum gfx_turn_fail_t |
| enum gfx_turn_show_t |
| void gfx_turn_begin | ( | gfx_turn_t * | t, |
| const gfx_canvas_t * | logical ) |
Start a frame: drawing turned, the damage record bound to logical, empty and attached; NORMAL, no record attached.
| t | the state |
| logical | the canvas the frame is drawn on |
|
inlinestatic |
The done callback's first step: the context it was given, or NULL, counted in gfx_turn_stray_dones(), when it was given none. Inline and one atomic add: callable from the engine's interrupt.
| user_data | what the engine passed |
user_data | bool gfx_turn_drawing | ( | const gfx_turn_t * | t | ) |
Whether the frame being drawn goes into a logical buffer.
| t | the state |
| gfx_turn_copy_t gfx_turn_engine_copy | ( | const gfx_turn_engine_t * | e, |
| const gfx_color_t * | src, | ||
| gfx_color_t * | dst, | ||
| gfx_rect_t | r, | ||
| int | width, | ||
| int | height, | ||
| uint32_t | budget_us ) |
One block through e: the job built from r with e->done_ctx as its user_data, submitted and waited for. The copy function of a gfx_turn_ops_t calls it.
| e | the engine |
| src | the logical buffer |
| dst | the frame buffer of the same index |
| r | the block, in src's coordinates |
| width | both pictures' width, pixels |
| height | their height, rows |
| budget_us | the longest wait, us |
e, its done_ctx or a callback is missing or the engine refuses the job; GFX_TURN_COPY_TIMEOUT when the done callback does not come in time | void gfx_turn_fail | ( | gfx_turn_t * | t, |
| gfx_turn_fail_t | why ) |
Fall back to NORMAL until the next start.
| t | the state |
| why | the reason, not GFX_TURN_FAIL_NONE |
| gfx_turn_show_t gfx_turn_flush | ( | gfx_turn_t * | t, |
| const gfx_color_t * | logical, | ||
| gfx_color_t * | fb, | ||
| const gfx_turn_ops_t * | ops ) |
End a frame: copy what it drew into fb, turned.
Detaches the damage record. NORMAL copies nothing. Turned, the record's rectangles, or the whole picture while full flips are left, go through ops within GFX_TURN_BUDGET_US; a copy that times out or fails makes the frame the logical buffer as drawn, unturned, and the state fallen back.
| t | the state |
| logical | the logical buffer the frame was drawn into |
| fb | the frame buffer of the same index |
| ops | the copy engine |
fb now holds | void gfx_turn_init | ( | gfx_turn_t * | t, |
| int | width, | ||
| int | height ) |
NORMAL, nothing failed, for a width x height picture; the shown flag NORMAL too.
| t | the state |
| width | the picture's width, pixels |
| height | its height, rows |
| void gfx_turn_next | ( | gfx_turn_t * | t | ) |
After a flip: take the request for the next frame.
A switch asks the UI for a whole repaint (gfx_turn_take_repaint()), and a switch to 180° copies the whole picture for GFX_TURN_FULL_FLIPS flips. A request for 180° that meets a fallback asks for its alert once.
| t | the state |
| bool gfx_turn_presented | ( | gfx_turn_t * | t, |
| gfx_turn_show_t | show ) |
The frame of the last flush is on the glass: set the shown flag.
| t | the state |
| show | what that flush returned |
| void gfx_turn_request | ( | gfx_turn_t * | t, |
| bool | turned ) |
What the setting asks for; taken at the next gfx_turn_next().
| t | the state |
| turned | true for 180° |
| bool gfx_turn_shown | ( | void | ) |
What the panel shows: the one flag picture and touch turn by. Read from any task.
| uint32_t gfx_turn_stray_dones | ( | void | ) |
Done callbacks that came with a NULL context since start-up.
| bool gfx_turn_take_alert | ( | gfx_turn_t * | t | ) |
Whether the fallback's alert is due; clears it.
| t | the state |
| bool gfx_turn_take_repaint | ( | gfx_turn_t * | t | ) |
Whether the UI must repaint everything before the next frame; clears it.
| t | the state |