Skip to content
Snippets Groups Projects
Verified Commit 1fb3f90a authored by dos's avatar dos
Browse files

st3m: gfx: Release drawlists already before scanout

The framebuffer won't be modified until graphics task gets
to another iteration of its infinite loop, so there's no reason
to still hold the drawlist during scanout.

Since this decouples drawlist release and ability to submit
another drawlist from each other, split existing st3m_gfx_pipe_full
into two functions - one that checks whether there's a free
drawlist available to take, and one that checks whether
a drawlist can be submitted for rasterization.
parent 98315c6e
Branches
Tags
No related merge requests found
......@@ -106,6 +106,14 @@ STATIC mp_obj_t mp_pipe_full(void) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_pipe_full_obj, mp_pipe_full);
STATIC mp_obj_t mp_pipe_available(void) {
if (st3m_gfx_pipe_available()) {
return mp_const_true;
}
return mp_const_false;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_pipe_available_obj, mp_pipe_available);
STATIC mp_obj_t mp_pipe_flush(void) {
st3m_gfx_flush(1000);
return mp_const_none;
......@@ -115,6 +123,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_pipe_flush_obj, mp_pipe_flush);
STATIC const mp_rom_map_elem_t mp_module_sys_display_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sys_display) },
{ MP_ROM_QSTR(MP_QSTR_pipe_full), MP_ROM_PTR(&mp_pipe_full_obj) },
{ MP_ROM_QSTR(MP_QSTR_pipe_available), MP_ROM_PTR(&mp_pipe_available_obj) },
{ MP_ROM_QSTR(MP_QSTR_pipe_flush), MP_ROM_PTR(&mp_pipe_flush_obj) },
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mp_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_fb), MP_ROM_PTR(&mp_fb_obj) },
......
......@@ -491,22 +491,26 @@ static void st3m_gfx_task(void *_arg) {
st3m_clear_fbs = 0;
}
if (((set_mode & st3m_gfx_direct_ctx) == 0))
int osd_x0 = drawlist->osd_x0, osd_x1 = drawlist->osd_x1,
osd_y0 = drawlist->osd_y0, osd_y1 = drawlist->osd_y1;
if ((set_mode & st3m_gfx_direct_ctx) == 0) {
ctx_render_ctx(drawlist->user_ctx, user_target);
ctx_drawlist_clear(drawlist->user_ctx);
st3m_gfx_viewport_transform(drawlist->user_ctx);
}
xQueueSend(user_ctx_freeq, &desc_no, portMAX_DELAY);
#if CONFIG_FLOW3R_CTX_FLAVOUR_FULL
if ((scale > 1) || ((set_mode & st3m_gfx_osd) &&
(drawlist->osd_y0 != drawlist->osd_y1))) {
if (((set_mode & st3m_gfx_osd) &&
(drawlist->osd_y0 != drawlist->osd_y1))) {
if ((scale > 1) || ((set_mode & st3m_gfx_osd) && (osd_y0 != osd_y1))) {
if (((set_mode & st3m_gfx_osd) && (osd_y0 != osd_y1))) {
while (st3m_osd_lock > 0) {
st3m_osd_lock--;
usleep(1);
}
st3m_osd_ctx_lock = ST3M_OSD_LOCK_TIMEOUT;
flow3r_bsp_display_send_fb_osd(
user_fb, bits, scale, osd_fb, drawlist->osd_x0,
drawlist->osd_y0, drawlist->osd_x1, drawlist->osd_y1);
flow3r_bsp_display_send_fb_osd(user_fb, bits, scale, osd_fb,
osd_x0, osd_y0, osd_x1, osd_y1);
st3m_osd_ctx_lock = 0;
} else {
flow3r_bsp_display_send_fb_osd(user_fb, bits, scale, NULL, 0, 0,
......@@ -519,12 +523,6 @@ static void st3m_gfx_task(void *_arg) {
}
fb_ready = 1;
if ((set_mode & st3m_gfx_direct_ctx) == 0) {
ctx_drawlist_clear(drawlist->user_ctx);
st3m_gfx_viewport_transform(drawlist->user_ctx);
}
xQueueSend(user_ctx_freeq, &desc_no, portMAX_DELAY);
st3m_counter_rate_sample(&rast_rate);
float rate = 1000000.0 / st3m_counter_rate_average(&rast_rate);
smoothed_fps = smoothed_fps * 0.75 + 0.25 * rate;
......@@ -896,8 +894,12 @@ void st3m_gfx_end_frame(Ctx *ctx) {
st3m_gfx_pipe_put();
}
uint8_t st3m_gfx_pipe_available(void) {
return uxQueueMessagesWaiting(user_ctx_freeq) > _st3m_gfx_low_latency;
}
uint8_t st3m_gfx_pipe_full(void) {
return uxQueueMessagesWaiting(user_ctx_freeq) <= _st3m_gfx_low_latency;
return uxQueueSpacesAvailable(user_ctx_rastq) == 0;
}
void st3m_gfx_flush(int timeout_ms) {
......
......@@ -88,6 +88,9 @@ void st3m_gfx_init(void);
// Returns true if we right now cannot accept another frame
uint8_t st3m_gfx_pipe_full(void);
// Returns true if there's a free drawlist available to retrieve
uint8_t st3m_gfx_pipe_available(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
......
......@@ -2,6 +2,7 @@ from ctx import Context
def ctx() -> Context: ...
def pipe_full() -> bool: ...
def pipe_available() -> bool: ...
def pipe_flush() -> None: ...
def update(c: Context) -> None: ...
def set_backlight(percent: int) -> None: ...
......@@ -142,7 +142,7 @@ class Reactor:
self._top.think(hr, delta)
# Draw!
if self._ctx is None:
if self._ctx is None and sys_display.pipe_available():
self._ctx = sys_display.ctx(0)
if self._ctx is not None:
if self._last_ctx_get is not None:
......
......@@ -5,6 +5,10 @@ def pipe_full():
return False
def pipe_available():
return True
def overlay_clip(x0, y0, x1, y1):
pass
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment