rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
gfx_turn.h File Reference

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.

Detailed Description

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

Enumeration Type Documentation

◆ gfx_turn_copy_t

How one copy ended.

Enumerator
GFX_TURN_COPY_DONE 

the block is in the frame buffer

GFX_TURN_COPY_TIMEOUT 

the engine did not finish in the budget

GFX_TURN_COPY_ERROR 

the engine refused the block

◆ gfx_turn_fail_t

Why the flush fell back to NORMAL.

Enumerator
GFX_TURN_FAIL_NONE 

it did not

GFX_TURN_FAIL_TIMEOUT 

a copy timed out

GFX_TURN_FAIL_ERROR 

a copy was refused

GFX_TURN_FAIL_ENGINE 

no copy engine or no logical buffers

◆ gfx_turn_show_t

What a flush leaves in the frame buffer.

Enumerator
GFX_TURN_SHOW_NORMAL 

the picture as drawn

GFX_TURN_SHOW_TURNED 

the picture turned by 180°

GFX_TURN_SHOW_FALLBACK 

as drawn, after a failed copy

Function Documentation

◆ gfx_turn_begin()

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.

Parameters
tthe state
logicalthe canvas the frame is drawn on

◆ gfx_turn_done_ctx()

void * gfx_turn_done_ctx ( void * user_data)
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.

Parameters
user_datawhat the engine passed
Returns
user_data

◆ gfx_turn_drawing()

bool gfx_turn_drawing ( const gfx_turn_t * t)

Whether the frame being drawn goes into a logical buffer.

Parameters
tthe state
Returns
true while turned and not fallen back

◆ gfx_turn_engine_copy()

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.

Parameters
ethe engine
srcthe logical buffer
dstthe frame buffer of the same index
rthe block, in src's coordinates
widthboth pictures' width, pixels
heighttheir height, rows
budget_usthe longest wait, us
Returns
GFX_TURN_COPY_ERROR when 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

◆ gfx_turn_fail()

void gfx_turn_fail ( gfx_turn_t * t,
gfx_turn_fail_t why )

Fall back to NORMAL until the next start.

Parameters
tthe state
whythe reason, not GFX_TURN_FAIL_NONE

◆ gfx_turn_flush()

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.

Parameters
tthe state
logicalthe logical buffer the frame was drawn into
fbthe frame buffer of the same index
opsthe copy engine
Returns
what fb now holds

◆ gfx_turn_init()

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.

Parameters
tthe state
widththe picture's width, pixels
heightits height, rows

◆ gfx_turn_next()

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.

Parameters
tthe state

◆ gfx_turn_presented()

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.

Parameters
tthe state
showwhat that flush returned
Returns
true when the shown flag changed

◆ gfx_turn_request()

void gfx_turn_request ( gfx_turn_t * t,
bool turned )

What the setting asks for; taken at the next gfx_turn_next().

Parameters
tthe state
turnedtrue for 180°

◆ gfx_turn_shown()

bool gfx_turn_shown ( void )

What the panel shows: the one flag picture and touch turn by. Read from any task.

Returns
true while the picture on the glass is turned by 180°

◆ gfx_turn_stray_dones()

uint32_t gfx_turn_stray_dones ( void )

Done callbacks that came with a NULL context since start-up.

Returns
the count; it wraps at 2^32

◆ gfx_turn_take_alert()

bool gfx_turn_take_alert ( gfx_turn_t * t)

Whether the fallback's alert is due; clears it.

Parameters
tthe state
Returns
true once per start that falls back while 180° is asked for

◆ gfx_turn_take_repaint()

bool gfx_turn_take_repaint ( gfx_turn_t * t)

Whether the UI must repaint everything before the next frame; clears it.

Parameters
tthe state
Returns
true once per switch