diff --git a/components/st3m/st3m_gfx.c b/components/st3m/st3m_gfx.c index a2facf3bf34f26a47e16d8147b5c7cd81f7803bd..a88e58e756608f2acd8820433ac33f0791312432 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 e5a2d94b6aab70834ec9ec0cd6923461404ad27b..571779459eb53543dd15d4dc19d3b0916491e154 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 b24384d8dd7778ed5564ec9ecfeae739dc4f5e4d..42ed2d164ec8c57b775bdad7fc90f0dddf23a595 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.