Skip to content
Snippets Groups Projects
Commit dea000bd authored by pippin's avatar pippin
Browse files

st3m_gfx, recovery, uctx: reduce API layering

parent d07fa1d8
Branches
Tags
No related merge requests found
...@@ -18,8 +18,6 @@ ...@@ -18,8 +18,6 @@
#include "mp_uctx.h" #include "mp_uctx.h"
static st3m_ctx_desc_t *gfx_last_desc = NULL;
STATIC mp_obj_t mp_set_backlight(mp_obj_t percent_in) { STATIC mp_obj_t mp_set_backlight(mp_obj_t percent_in) {
uint8_t percent = mp_obj_get_int(percent_in); uint8_t percent = mp_obj_get_int(percent_in);
flow3r_bsp_display_set_backlight(percent); flow3r_bsp_display_set_backlight(percent);
...@@ -27,15 +25,11 @@ STATIC mp_obj_t mp_set_backlight(mp_obj_t percent_in) { ...@@ -27,15 +25,11 @@ STATIC mp_obj_t mp_set_backlight(mp_obj_t percent_in) {
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_set_backlight_obj, mp_set_backlight); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_set_backlight_obj, mp_set_backlight);
static Ctx *global_ctx = NULL;
STATIC mp_obj_t mp_get_ctx(void) { STATIC mp_obj_t mp_get_ctx(void) {
if (gfx_last_desc == NULL) { if (!global_ctx) global_ctx = st3m_ctx(0);
gfx_last_desc = st3m_gfx_drawctx_free_get(0); if (global_ctx == NULL) return mp_const_none;
if (gfx_last_desc == NULL) { return mp_ctx_from_ctx(global_ctx);
return mp_const_none;
}
}
mp_obj_t mp_ctx = mp_ctx_from_ctx(gfx_last_desc->ctx);
return mp_ctx;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_get_ctx_obj, mp_get_ctx); STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_get_ctx_obj, mp_get_ctx);
...@@ -45,15 +39,9 @@ STATIC mp_obj_t mp_update(mp_obj_t ctx_in) { ...@@ -45,15 +39,9 @@ STATIC mp_obj_t mp_update(mp_obj_t ctx_in) {
mp_raise_ValueError("not a ctx"); mp_raise_ValueError("not a ctx");
return mp_const_none; return mp_const_none;
} }
if (global_ctx) {
if (gfx_last_desc != NULL) { st3m_ctx_end_frame(self->ctx);
if (gfx_last_desc->ctx != self->ctx) { global_ctx = NULL;
mp_raise_ValueError(
"not the correct ctx (do not hold on to ctx objects!)");
return mp_const_none;
}
st3m_gfx_drawctx_pipe_put(gfx_last_desc);
gfx_last_desc = NULL;
} }
return mp_const_none; return mp_const_none;
} }
......
...@@ -410,7 +410,8 @@ static mp_obj_t mp_ctx_image(size_t n_args, const mp_obj_t *args) { ...@@ -410,7 +410,8 @@ static mp_obj_t mp_ctx_image(size_t n_args, const mp_obj_t *args) {
if (n_args > 7) clip_y = mp_obj_get_float(args[7]); if (n_args > 7) clip_y = mp_obj_get_float(args[7]);
if (n_args > 8) clip_width = mp_obj_get_float(args[8]); if (n_args > 8) clip_width = mp_obj_get_float(args[8]);
if (n_args > 9) clip_height = mp_obj_get_float(args[9]); if (n_args > 9) clip_height = mp_obj_get_float(args[9]);
ctx_draw_image_clipped(self->ctx, path, x0, y0, width, height, clip_x, clip_y, clip_width, clip_height); ctx_draw_image_clipped(self->ctx, path, x0, y0, width, height, clip_x,
clip_y, clip_width, clip_height);
return args[0]; return args[0];
} }
......
#include "st3m_gfx.h" #include "st3m_gfx.h"
// Submit a filled ctx descriptor to the rasterization pipeline.
#include <string.h> #include <string.h>
...@@ -18,6 +19,32 @@ ...@@ -18,6 +19,32 @@
#include "st3m_counter.h" #include "st3m_counter.h"
#include "st3m_version.h" #include "st3m_version.h"
// Each buffer takes ~116kB SPIRAM. While one framebuffer is being blitted, the
// other one is being written to by the rasterizer.
#define ST3M_GFX_NBUFFERS 1
// More ctx drawlists than buffers so that micropython doesn't get starved when
// pipeline runs in lockstep.
#define ST3M_GFX_NCTX 1
// A framebuffer descriptor, pointing at a framebuffer.
typedef struct {
// The numeric ID of this descriptor.
int num;
// SPIRAM buffer.
uint16_t buffer[240 * 240];
Ctx *ctx;
} st3m_framebuffer_desc_t;
// Get a free drawlist ctx to draw into.
//
// ticks_to_wait can be used to limit the time to wait for a free ctx
// descriptor, or portDELAY_MAX can be specified to wait forever. If the timeout
// expires, NULL will be returned.
static st3m_ctx_desc_t *st3m_gfx_drawctx_free_get(TickType_t ticks_to_wait);
// Submit a filled ctx descriptor to the rasterization pipeline.
static void st3m_gfx_drawctx_pipe_put(st3m_ctx_desc_t *desc);
static const char *TAG = "st3m-gfx"; static const char *TAG = "st3m-gfx";
// Framebuffer descriptors, containing framebuffer and ctx for each of the // Framebuffer descriptors, containing framebuffer and ctx for each of the
...@@ -479,7 +506,7 @@ void st3m_gfx_init(void) { ...@@ -479,7 +506,7 @@ void st3m_gfx_init(void) {
assert(res == pdPASS); assert(res == pdPASS);
} }
st3m_ctx_desc_t *st3m_gfx_drawctx_free_get(TickType_t ticks_to_wait) { static st3m_ctx_desc_t *st3m_gfx_drawctx_free_get(TickType_t ticks_to_wait) {
int descno; int descno;
BaseType_t res = xQueueReceive(dctx_freeq, &descno, ticks_to_wait); BaseType_t res = xQueueReceive(dctx_freeq, &descno, ticks_to_wait);
if (res != pdTRUE) { if (res != pdTRUE) {
...@@ -488,7 +515,7 @@ st3m_ctx_desc_t *st3m_gfx_drawctx_free_get(TickType_t ticks_to_wait) { ...@@ -488,7 +515,7 @@ st3m_ctx_desc_t *st3m_gfx_drawctx_free_get(TickType_t ticks_to_wait) {
return &dctx_descs[descno]; return &dctx_descs[descno];
} }
void st3m_gfx_drawctx_pipe_put(st3m_ctx_desc_t *desc) { static void st3m_gfx_drawctx_pipe_put(st3m_ctx_desc_t *desc) {
xQueueSend(dctx_rastq, &desc->num, portMAX_DELAY); xQueueSend(dctx_rastq, &desc->num, portMAX_DELAY);
} }
...@@ -523,3 +550,16 @@ void st3m_gfx_flush(void) { ...@@ -523,3 +550,16 @@ void st3m_gfx_flush(void) {
} }
ESP_LOGW(TAG, "Pipeline flush/reset done."); ESP_LOGW(TAG, "Pipeline flush/reset done.");
} }
static int st3m_dctx_no = 0; // always 0 - but this keeps pipelined
// rendering working as a compile time opt-in
Ctx *st3m_ctx(TickType_t ticks_to_wait) {
st3m_ctx_desc_t *foo = st3m_gfx_drawctx_free_get(ticks_to_wait);
if (!foo) return NULL;
st3m_dctx_no = foo->num;
return foo->ctx;
}
void st3m_ctx_end_frame(Ctx *ctx) {
xQueueSend(dctx_rastq, &st3m_dctx_no, portMAX_DELAY);
}
...@@ -7,21 +7,9 @@ ...@@ -7,21 +7,9 @@
#include "ctx.h" #include "ctx.h"
// clang-format on // clang-format on
// Each buffer takes ~116kB SPIRAM. While one framebuffer is being blitted, the Ctx *st3m_ctx(TickType_t ticks_to_wait);
// other one is being written to by the rasterizer. void st3m_ctx_end_frame(Ctx *ctx); // temporary, signature compatible
#define ST3M_GFX_NBUFFERS 1 // with ctx_end_frame()
// More ctx drawlists than buffers so that micropython doesn't get starved when
// pipeline runs in lockstep.
#define ST3M_GFX_NCTX 1
// A framebuffer descriptor, pointing at a framebuffer.
typedef struct {
// The numeric ID of this descriptor.
int num;
// SPIRAM buffer.
uint16_t buffer[240 * 240];
Ctx *ctx;
} st3m_framebuffer_desc_t;
// Initialize the gfx subsystem of st3m, includng the rasterization and // Initialize the gfx subsystem of st3m, includng the rasterization and
// crtx/blitter pipeline. // crtx/blitter pipeline.
...@@ -34,16 +22,6 @@ typedef struct { ...@@ -34,16 +22,6 @@ typedef struct {
Ctx *ctx; Ctx *ctx;
} st3m_ctx_desc_t; } st3m_ctx_desc_t;
// Get a free drawlist ctx to draw into.
//
// ticks_to_wait can be used to limit the time to wait for a free ctx
// descriptor, or portDELAY_MAX can be specified to wait forever. If the timeout
// expires, NULL will be returned.
st3m_ctx_desc_t *st3m_gfx_drawctx_free_get(TickType_t ticks_to_wait);
// Submit a filled ctx descriptor to the rasterization pipeline.
void st3m_gfx_drawctx_pipe_put(st3m_ctx_desc_t *desc);
// Returns true if the rasterizaiton pipeline submission would block. // Returns true if the rasterizaiton pipeline submission would block.
uint8_t st3m_gfx_drawctx_pipe_full(void); uint8_t st3m_gfx_drawctx_pipe_full(void);
......
...@@ -6,21 +6,21 @@ ...@@ -6,21 +6,21 @@
void rec_fatal(const char *msg) { void rec_fatal(const char *msg) {
for (;;) { for (;;) {
st3m_ctx_desc_t *target = st3m_gfx_drawctx_free_get(portMAX_DELAY); Ctx *ctx = st3m_ctx(portMAX_DELAY);
// Draw background. // Draw background.
ctx_rgb(target->ctx, 0.29, 0.0, 0.0); ctx_rgb(ctx, 0.29, 0.0, 0.0);
ctx_rectangle(target->ctx, -120, -120, 240, 240); ctx_rectangle(ctx, -120, -120, 240, 240);
ctx_fill(target->ctx); ctx_fill(ctx);
ctx_font_size(target->ctx, 15.0); ctx_font_size(ctx, 15.0);
ctx_gray(target->ctx, 0.8); ctx_gray(ctx, 0.8);
ctx_text_align(target->ctx, CTX_TEXT_ALIGN_CENTER); ctx_text_align(ctx, CTX_TEXT_ALIGN_CENTER);
ctx_text_baseline(target->ctx, CTX_TEXT_BASELINE_MIDDLE); ctx_text_baseline(ctx, CTX_TEXT_BASELINE_MIDDLE);
ctx_move_to(target->ctx, 0, 0); ctx_move_to(ctx, 0, 0);
ctx_text(target->ctx, msg); ctx_text(ctx, msg);
st3m_gfx_drawctx_pipe_put(target); st3m_ctx_end_frame(ctx);
vTaskDelay(10 / portTICK_PERIOD_MS); vTaskDelay(10 / portTICK_PERIOD_MS);
} }
......
...@@ -9,71 +9,71 @@ ...@@ -9,71 +9,71 @@
#include "ctx.h" #include "ctx.h"
// clang-format on // clang-format on
static void _header_draw(st3m_ctx_desc_t *target) { static void _header_draw(Ctx *ctx) {
// Draw background. // Draw background.
ctx_rgb(target->ctx, 0.29, 0.10, 0.35); ctx_rgb(ctx, 0.29, 0.10, 0.35);
ctx_rectangle(target->ctx, -120, -120, 240, 240); ctx_rectangle(ctx, -120, -120, 240, 240);
ctx_fill(target->ctx); ctx_fill(ctx);
// Draw header. // Draw header.
ctx_gray(target->ctx, 1.0); ctx_gray(ctx, 1.0);
ctx_text_align(target->ctx, CTX_TEXT_ALIGN_CENTER); ctx_text_align(ctx, CTX_TEXT_ALIGN_CENTER);
ctx_text_baseline(target->ctx, CTX_TEXT_BASELINE_MIDDLE); ctx_text_baseline(ctx, CTX_TEXT_BASELINE_MIDDLE);
ctx_font_size(target->ctx, 15.0); ctx_font_size(ctx, 15.0);
ctx_move_to(target->ctx, 0, -100); ctx_move_to(ctx, 0, -100);
ctx_text(target->ctx, "oh no it's"); ctx_text(ctx, "oh no it's");
ctx_font_size(target->ctx, 30.0); ctx_font_size(ctx, 30.0);
ctx_move_to(target->ctx, 0, -80); ctx_move_to(ctx, 0, -80);
ctx_text(target->ctx, "Recovery"); ctx_text(ctx, "Recovery");
ctx_move_to(target->ctx, 0, -55); ctx_move_to(ctx, 0, -55);
ctx_text(target->ctx, "Mode"); ctx_text(ctx, "Mode");
// Draw version. // Draw version.
ctx_font_size(target->ctx, 15.0); ctx_font_size(ctx, 15.0);
ctx_gray(target->ctx, 0.6); ctx_gray(ctx, 0.6);
ctx_move_to(target->ctx, 0, 100); ctx_move_to(ctx, 0, 100);
ctx_text(target->ctx, st3m_version); ctx_text(ctx, st3m_version);
} }
void rec_erasing_draw(void) { void rec_erasing_draw(void) {
st3m_ctx_desc_t *target = st3m_gfx_drawctx_free_get(portMAX_DELAY); Ctx *ctx = st3m_ctx(portMAX_DELAY);
_header_draw(target); _header_draw(ctx);
ctx_move_to(target->ctx, 0, 0); ctx_move_to(ctx, 0, 0);
ctx_font_size(target->ctx, 20.0); ctx_font_size(ctx, 20.0);
ctx_gray(target->ctx, 0.8); ctx_gray(ctx, 0.8);
ctx_text(target->ctx, "Erasing..."); ctx_text(ctx, "Erasing...");
st3m_gfx_drawctx_pipe_put(target); st3m_ctx_end_frame(ctx);
} }
void rec_flashing_draw(int percent) { void rec_flashing_draw(int percent) {
st3m_ctx_desc_t *target = st3m_gfx_drawctx_free_get(portMAX_DELAY); Ctx *ctx = st3m_ctx(portMAX_DELAY);
_header_draw(target); _header_draw(ctx);
ctx_move_to(target->ctx, 0, 0); ctx_move_to(ctx, 0, 0);
ctx_font_size(target->ctx, 20.0); ctx_font_size(ctx, 20.0);
ctx_gray(target->ctx, 0.8); ctx_gray(ctx, 0.8);
char buf[128]; char buf[128];
snprintf(buf, sizeof(buf), "Flashing... %2d%%", percent); snprintf(buf, sizeof(buf), "Flashing... %2d%%", percent);
ctx_text(target->ctx, buf); ctx_text(ctx, buf);
ctx_rectangle(target->ctx, -120, 20, 240 * percent / 100, 20); ctx_rectangle(ctx, -120, 20, 240 * percent / 100, 20);
ctx_fill(target->ctx); ctx_fill(ctx);
st3m_gfx_drawctx_pipe_put(target); st3m_ctx_end_frame(ctx);
} }
void rec_menu_draw(menu_t *menu) { void rec_menu_draw(menu_t *menu) {
st3m_ctx_desc_t *target = st3m_gfx_drawctx_free_get(portMAX_DELAY); Ctx *ctx = st3m_ctx(portMAX_DELAY);
_header_draw(target); _header_draw(ctx);
int y = -20; int y = -20;
ctx_font_size(target->ctx, 15.0); ctx_font_size(ctx, 15.0);
ctx_gray(target->ctx, 0.8); ctx_gray(ctx, 0.8);
if (menu->help != NULL) { if (menu->help != NULL) {
const char *help = menu->help; const char *help = menu->help;
const char *next = NULL; const char *next = NULL;
...@@ -83,36 +83,36 @@ void rec_menu_draw(menu_t *menu) { ...@@ -83,36 +83,36 @@ void rec_menu_draw(menu_t *menu) {
memcpy(line, help, len); memcpy(line, help, len);
line[len] = 0; line[len] = 0;
ctx_move_to(target->ctx, 0, y); ctx_move_to(ctx, 0, y);
ctx_text(target->ctx, line); ctx_text(ctx, line);
free(line); free(line);
y += 15; y += 15;
help = next + 1; help = next + 1;
} }
ctx_move_to(target->ctx, 0, y); ctx_move_to(ctx, 0, y);
ctx_text(target->ctx, help); ctx_text(ctx, help);
y += 25; y += 25;
} }
ctx_font_size(target->ctx, 18.0); ctx_font_size(ctx, 18.0);
for (int i = 0; i < menu->entries_count; i++) { for (int i = 0; i < menu->entries_count; i++) {
menu_entry_t *entry = &menu->entries[i]; menu_entry_t *entry = &menu->entries[i];
if (i == menu->selected) { if (i == menu->selected) {
ctx_gray(target->ctx, 1.0); ctx_gray(ctx, 1.0);
ctx_rectangle(target->ctx, -120, y - 9, 240, 18); ctx_rectangle(ctx, -120, y - 9, 240, 18);
ctx_fill(target->ctx); ctx_fill(ctx);
ctx_rgb(target->ctx, 0.29, 0.10, 0.35); ctx_rgb(ctx, 0.29, 0.10, 0.35);
} else if (entry->disabled) { } else if (entry->disabled) {
ctx_gray(target->ctx, 0.5); ctx_gray(ctx, 0.5);
} else { } else {
ctx_gray(target->ctx, 1.0); ctx_gray(ctx, 1.0);
} }
ctx_move_to(target->ctx, 0, y); ctx_move_to(ctx, 0, y);
ctx_text(target->ctx, entry->label); ctx_text(ctx, entry->label);
y += 18; y += 18;
} }
st3m_gfx_drawctx_pipe_put(target); st3m_ctx_end_frame(ctx);
} }
void rec_menu_process(menu_t *menu) { void rec_menu_process(menu_t *menu) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment