From 359fb894fe4a556ecd13ec577dc1f6056de9eb9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Kol=C3=A5s?= <pippin@gimp.org> Date: Thu, 10 Aug 2023 14:17:05 +0200 Subject: [PATCH] st3m/gfx: make empty drawlists skip render and blit --- components/st3m/st3m_gfx.c | 17 +++++++++++++++-- components/st3m/st3m_gfx.h | 6 ++++-- python_payload/st3m/reactor.py | 4 +++- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/components/st3m/st3m_gfx.c b/components/st3m/st3m_gfx.c index a2facf3bf3..a88e58e756 100644 --- a/components/st3m/st3m_gfx.c +++ b/components/st3m/st3m_gfx.c @@ -81,7 +81,8 @@ static void st3m_gfx_crtc_task(void *_arg) { st3m_counter_timer_sample(&blit_read_time, end - start); start = esp_timer_get_time(); - flow3r_bsp_display_send_fb(framebuffer_descs[descno].buffer); + if (!framebuffer_descs[descno].empty) + flow3r_bsp_display_send_fb(framebuffer_descs[descno].buffer); end = esp_timer_get_time(); st3m_counter_timer_sample(&blit_work_time, end - start); @@ -131,7 +132,19 @@ static void st3m_gfx_rast_task(void *_arg) { // Render drawctx into fbctx. start = esp_timer_get_time(); - ctx_render_ctx(draw->ctx, fb->ctx); + int count = 0; + const CtxEntry *drawlist = ctx_get_drawlist(draw->ctx, &count); + + // XXX maybe we should just rely on count < 4 meaning empty, + // this is after-all a time critical path + if ((count == 4 && (drawlist[0].code == CTX_SAVE) && + (drawlist[1].code == CTX_SAVE)) || + count <= 2) { + fb->empty = 1; + } else { + fb->empty = 0; + ctx_render_ctx(draw->ctx, fb->ctx); + } ctx_drawlist_clear(draw->ctx); end = esp_timer_get_time(); st3m_counter_timer_sample(&rast_work_time, end - start); diff --git a/components/st3m/st3m_gfx.h b/components/st3m/st3m_gfx.h index e5a2d94b6a..571779459e 100644 --- a/components/st3m/st3m_gfx.h +++ b/components/st3m/st3m_gfx.h @@ -18,6 +18,8 @@ typedef struct { // The numeric ID of this descriptor. int num; + // set when the drawlist was empty + int empty; // SPIRAM buffer. uint16_t buffer[240 * 240]; Ctx *ctx; @@ -50,7 +52,7 @@ uint8_t st3m_gfx_drawctx_pipe_full(void); // Flush any in-flight pipelined work, resetting the free ctx/framebuffer queues // to their initial state. This should be called if there has been any drawlist // ctx dropped (ie. drawctx_free_get was called but then drawctx_pipe_put -// wasn't, for exaple if Micropython restarted). +// wasn't, for example if Micropython restarted). // // This causes a graphical disturbance and shouldn't be called during normal // operation. @@ -74,4 +76,4 @@ void st3m_gfx_splash(const char *text); // Draw the flow3r multi-coloured logo at coordinates x,y and with given // dimension (approx. bounding box size). -void st3m_gfx_flow3r_logo(Ctx *ctx, float x, float y, float dim); \ No newline at end of file +void st3m_gfx_flow3r_logo(Ctx *ctx, float x, float y, float dim); diff --git a/python_payload/st3m/reactor.py b/python_payload/st3m/reactor.py index b24384d8dd..42ed2d164e 100644 --- a/python_payload/st3m/reactor.py +++ b/python_payload/st3m/reactor.py @@ -40,7 +40,9 @@ class Responder(ABCBase): coordinates are +/- 120 in both X and Y (positive numbers towards up and right), with 0,0 being the middle of the screen. - The Reactor will then rasterize and blit the result. + The Reactor will then rasterize and blit the result. If no ctx drawing + commands are issued, it is interpreted as a wish to keep the display + contents as-is, and cpu time is not spent on rasterization and blitting. The code must not sleep or block during this callback, as that will impact the system tickrate and framerate. -- GitLab