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

Merge branch 'mr-origin-509' into test

parents a90c802a e3c2fdba
Branches
No related tags found
No related merge requests found
Pipeline #9023 passed
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
#define CTX_BAREMETAL 1 #define CTX_BAREMETAL 1
#define CTX_ONE_FONT_ENGINE 1 #define CTX_ONE_FONT_ENGINE 1
#define CTX_MAX_SCANLINE_LENGTH 256 #define CTX_MAX_SCANLINE_LENGTH 960
#define CTX_MAX_JOURNAL_SIZE (1024*512) #define CTX_MAX_JOURNAL_SIZE (1024*512)
// is also max and limits complexity // is also max and limits complexity
// of paths that can be filled // of paths that can be filled
......
...@@ -29,6 +29,13 @@ STATIC mp_obj_t mp_overlay_clip(size_t n_arge, const mp_obj_t *args) { ...@@ -29,6 +29,13 @@ STATIC mp_obj_t mp_overlay_clip(size_t n_arge, const mp_obj_t *args) {
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_overlay_clip_obj, 4, 4, STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_overlay_clip_obj, 4, 4,
mp_overlay_clip); mp_overlay_clip);
STATIC mp_obj_t mp_fbconfig(size_t n_arge, const mp_obj_t *args) {
st3m_gfx_fbconfig(mp_obj_get_int(args[0]), mp_obj_get_int(args[1]),
mp_obj_get_int(args[2]), mp_obj_get_int(args[3]));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_fbconfig_obj, 4, 4, mp_fbconfig);
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);
...@@ -136,6 +143,7 @@ STATIC const mp_rom_map_elem_t mp_module_sys_display_globals_table[] = { ...@@ -136,6 +143,7 @@ STATIC const mp_rom_map_elem_t mp_module_sys_display_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_set_palette), MP_ROM_PTR(&mp_set_palette_obj) }, { MP_ROM_QSTR(MP_QSTR_set_palette), MP_ROM_PTR(&mp_set_palette_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_backlight), MP_ROM_PTR(&mp_set_backlight_obj) }, { MP_ROM_QSTR(MP_QSTR_set_backlight), MP_ROM_PTR(&mp_set_backlight_obj) },
{ MP_ROM_QSTR(MP_QSTR_overlay_clip), MP_ROM_PTR(&mp_overlay_clip_obj) }, { MP_ROM_QSTR(MP_QSTR_overlay_clip), MP_ROM_PTR(&mp_overlay_clip_obj) },
{ MP_ROM_QSTR(MP_QSTR_fbconfig), MP_ROM_PTR(&mp_fbconfig_obj) },
{ MP_ROM_QSTR(MP_QSTR_default), MP_ROM_INT((int)st3m_gfx_default) }, { MP_ROM_QSTR(MP_QSTR_default), MP_ROM_INT((int)st3m_gfx_default) },
{ MP_ROM_QSTR(MP_QSTR_rgb332), MP_ROM_INT((int)st3m_gfx_rgb332) }, { MP_ROM_QSTR(MP_QSTR_rgb332), MP_ROM_INT((int)st3m_gfx_rgb332) },
......
...@@ -90,6 +90,9 @@ typedef struct { ...@@ -90,6 +90,9 @@ typedef struct {
int osd_y1; int osd_y1;
int osd_x1; int osd_x1;
int blit_x; // upper left pixel in framebuffer coordinates
int blit_y; //
st3m_gfx_mode mode; st3m_gfx_mode mode;
uint8_t *blit_src; uint8_t *blit_src;
} st3m_gfx_drawlist; } st3m_gfx_drawlist;
...@@ -117,6 +120,12 @@ static TaskHandle_t graphics_blit_task; ...@@ -117,6 +120,12 @@ static TaskHandle_t graphics_blit_task;
static int _st3m_gfx_low_latency = 0; static int _st3m_gfx_low_latency = 0;
static int st3m_gfx_fb_width = 0;
static int st3m_gfx_fb_height = 0;
static int st3m_gfx_blit_x = 0;
static int st3m_gfx_blit_y = 0;
static int st3m_gfx_geom_dirty = 0;
static inline int st3m_gfx_scale(void) { static inline int st3m_gfx_scale(void) {
st3m_gfx_mode set_mode = _st3m_gfx_mode ? _st3m_gfx_mode : default_mode; st3m_gfx_mode set_mode = _st3m_gfx_mode ? _st3m_gfx_mode : default_mode;
switch ((int)(set_mode & st3m_gfx_4x)) { switch ((int)(set_mode & st3m_gfx_4x)) {
...@@ -351,6 +360,8 @@ st3m_gfx_mode st3m_gfx_set_mode(st3m_gfx_mode mode) { ...@@ -351,6 +360,8 @@ st3m_gfx_mode st3m_gfx_set_mode(st3m_gfx_mode mode) {
((mode & st3m_gfx_direct_ctx) != 0)) ((mode & st3m_gfx_direct_ctx) != 0))
_st3m_gfx_low_latency = (N_DRAWLISTS - 1); _st3m_gfx_low_latency = (N_DRAWLISTS - 1);
st3m_gfx_fbconfig(240, 240, 0, 0);
return mode; return mode;
} }
...@@ -367,7 +378,7 @@ uint8_t *st3m_gfx_fb(st3m_gfx_mode mode, int *width, int *height, int *stride) { ...@@ -367,7 +378,7 @@ uint8_t *st3m_gfx_fb(st3m_gfx_mode mode, int *width, int *height, int *stride) {
if (height) *height = 256; if (height) *height = 256;
return st3m_pal; return st3m_pal;
} else if (mode == st3m_gfx_default) { } else if (mode == st3m_gfx_default) {
if (stride) *stride = FLOW3R_BSP_DISPLAY_WIDTH * bpp / 8; if (stride) *stride = st3m_gfx_fb_width * bpp / 8;
if (width) *width = FLOW3R_BSP_DISPLAY_WIDTH; if (width) *width = FLOW3R_BSP_DISPLAY_WIDTH;
if (height) *height = FLOW3R_BSP_DISPLAY_HEIGHT; if (height) *height = FLOW3R_BSP_DISPLAY_HEIGHT;
return ((uint8_t *)st3m_fb); return ((uint8_t *)st3m_fb);
...@@ -465,9 +476,11 @@ static void st3m_gfx_rast_task(void *_arg) { ...@@ -465,9 +476,11 @@ static void st3m_gfx_rast_task(void *_arg) {
#if CONFIG_FLOW3R_CTX_FLAVOUR_FULL #if CONFIG_FLOW3R_CTX_FLAVOUR_FULL
ctx_set_textureclock(osd_ctx, ctx_textureclock(fb_ctx)); ctx_set_textureclock(osd_ctx, ctx_textureclock(fb_ctx));
#endif #endif
if (prev_set_mode != set_mode) { if (st3m_gfx_geom_dirty || (prev_set_mode != set_mode)) {
int was_geom_dirty = (prev_set_mode == set_mode);
bits = _st3m_gfx_bpp(set_mode); bits = _st3m_gfx_bpp(set_mode);
prev_set_mode = set_mode; prev_set_mode = set_mode;
st3m_gfx_geom_dirty = 0;
#if ST3M_GFX_BLIT_TASK #if ST3M_GFX_BLIT_TASK
if ((bits > 16)) if ((bits > 16))
...@@ -475,33 +488,40 @@ static void st3m_gfx_rast_task(void *_arg) { ...@@ -475,33 +488,40 @@ static void st3m_gfx_rast_task(void *_arg) {
else else
direct_blit = 0; direct_blit = 0;
#endif #endif
int stride = (bits * 240) / 8;
int stride = (bits * st3m_gfx_fb_width) / 8;
switch (bits) { switch (bits) {
#if CONFIG_FLOW3R_CTX_FLAVOUR_FULL #if CONFIG_FLOW3R_CTX_FLAVOUR_FULL
case 1: case 1:
ctx_rasterizer_reinit(fb_ctx, st3m_fb, 0, 0, 240, 240, ctx_rasterizer_reinit(fb_ctx, st3m_fb, 0, 0,
st3m_gfx_fb_width, st3m_gfx_fb_height,
stride, CTX_FORMAT_GRAY1); stride, CTX_FORMAT_GRAY1);
break; break;
case 2: case 2:
ctx_rasterizer_reinit(fb_ctx, st3m_fb, 0, 0, 240, 240, ctx_rasterizer_reinit(fb_ctx, st3m_fb, 0, 0,
st3m_gfx_fb_width, st3m_gfx_fb_height,
stride, CTX_FORMAT_GRAY2); stride, CTX_FORMAT_GRAY2);
break; break;
case 4: case 4:
ctx_rasterizer_reinit(fb_ctx, st3m_fb, 0, 0, 240, 240, ctx_rasterizer_reinit(fb_ctx, st3m_fb, 0, 0,
st3m_gfx_fb_width, st3m_gfx_fb_height,
stride, CTX_FORMAT_GRAY4); stride, CTX_FORMAT_GRAY4);
break; break;
case 8: case 8:
case 9: case 9:
if ((set_mode & 0xf) == 9) if ((set_mode & 0xf) == 9)
ctx_rasterizer_reinit(fb_ctx, st3m_fb, 0, 0, 240, 240, ctx_rasterizer_reinit(
stride, CTX_FORMAT_RGB332); fb_ctx, st3m_fb, 0, 0, st3m_gfx_fb_width,
st3m_gfx_fb_height, stride, CTX_FORMAT_RGB332);
else else
ctx_rasterizer_reinit(fb_ctx, st3m_fb, 0, 0, 240, 240, ctx_rasterizer_reinit(
stride, CTX_FORMAT_GRAY8); fb_ctx, st3m_fb, 0, 0, st3m_gfx_fb_width,
st3m_gfx_fb_height, stride, CTX_FORMAT_GRAY8);
break; break;
#endif #endif
case 16: case 16:
ctx_rasterizer_reinit(fb_ctx, st3m_fb, 0, 0, 240, 240, ctx_rasterizer_reinit(fb_ctx, st3m_fb, 0, 0,
st3m_gfx_fb_width, st3m_gfx_fb_height,
stride, stride,
CTX_FORMAT_RGB565_BYTESWAPPED); CTX_FORMAT_RGB565_BYTESWAPPED);
break; break;
...@@ -518,10 +538,10 @@ static void st3m_gfx_rast_task(void *_arg) { ...@@ -518,10 +538,10 @@ static void st3m_gfx_rast_task(void *_arg) {
#endif #endif
} }
st3m_gfx_viewport_transform(fb_ctx); st3m_gfx_viewport_transform(fb_ctx);
memset(st3m_fb, 0, sizeof(st3m_fb)); if (!was_geom_dirty) memset(st3m_fb, 0, sizeof(st3m_fb));
#if CONFIG_FLOW3R_CTX_FLAVOUR_FULL #if CONFIG_FLOW3R_CTX_FLAVOUR_FULL
st3m_gfx_viewport_transform(osd_ctx); st3m_gfx_viewport_transform(osd_ctx);
memset(st3m_fb2, 0, sizeof(st3m_fb2)); if (!was_geom_dirty) memset(st3m_fb2, 0, sizeof(st3m_fb2));
#endif #endif
} }
...@@ -541,7 +561,76 @@ static void st3m_gfx_rast_task(void *_arg) { ...@@ -541,7 +561,76 @@ static void st3m_gfx_rast_task(void *_arg) {
} else { } else {
drawlist->blit_src = st3m_fb_copy; drawlist->blit_src = st3m_fb_copy;
xSemaphoreTake(st3m_fb_copy_lock, portMAX_DELAY); xSemaphoreTake(st3m_fb_copy_lock, portMAX_DELAY);
memcpy(st3m_fb_copy, st3m_fb, 240 * (240 * bits / 8)); int disp_stride = 240 * bits / 8;
if ((st3m_gfx_fb_width == 240) && (drawlist->blit_x == 0)) {
int blit_offset = st3m_gfx_blit_y * 240 * bits / 8;
int overlap = (st3m_gfx_blit_y + 240) - st3m_gfx_fb_height;
if (overlap > 0) {
// vertical overlap, 2 memcpys
int start_scans = 240 - overlap;
memcpy(st3m_fb_copy, st3m_fb + blit_offset,
start_scans * disp_stride);
memcpy(st3m_fb_copy + start_scans * disp_stride, st3m_fb,
overlap * disp_stride);
} else { // best case
memcpy(st3m_fb_copy, st3m_fb + blit_offset,
240 * disp_stride);
}
} else {
int fb_stride = st3m_gfx_fb_width * bits / 8;
int scan_offset = drawlist->blit_x * bits / 8;
int scan_overlap = (drawlist->blit_x + 240) - st3m_gfx_fb_width;
if (scan_overlap <= 0) { // only vertical wrap-around
int blit_offset =
(st3m_gfx_blit_y * 240 + drawlist->blit_x) * bits / 8;
int overlap = (st3m_gfx_blit_y + 240) - st3m_gfx_fb_height;
if (overlap <= 0) overlap = 0;
int start_scans = 240 - overlap;
for (int i = 0; i < start_scans; i++)
memcpy(st3m_fb_copy + i * disp_stride,
st3m_fb + blit_offset + i * fb_stride,
disp_stride);
for (int i = 0; i < overlap; i++)
memcpy(st3m_fb_copy + (i + start_scans) * disp_stride,
st3m_fb + (drawlist->blit_x * bits / 8) +
i * fb_stride,
disp_stride);
} else { // generic case, handles both horizontal and vertical
// wrap-around
int start_bit = 240 - scan_overlap;
int blit_offset = (st3m_gfx_blit_y)*fb_stride;
int overlap = (st3m_gfx_blit_y + 240) - st3m_gfx_fb_height;
if (overlap <= 0) overlap = 0;
int start_scans = 240 - overlap;
int start_bytes = start_bit * bits / 8;
int scan_overlap_bytes = scan_overlap * bits / 8;
for (int i = 0; i < start_scans; i++)
memcpy(
st3m_fb_copy + i * disp_stride,
st3m_fb + blit_offset + i * fb_stride + scan_offset,
start_bytes);
for (int i = 0; i < overlap; i++)
memcpy(st3m_fb_copy + (i + start_scans) * disp_stride,
st3m_fb + scan_offset + i * fb_stride,
start_bytes);
// second pass over scanlines, filling in second half (which
// is wrapped to start of fb-scans)
for (int i = 0; i < start_scans; i++)
memcpy(st3m_fb_copy + i * disp_stride + start_bytes,
st3m_fb + blit_offset + i * fb_stride,
scan_overlap_bytes);
for (int i = 0; i < overlap; i++)
memcpy(st3m_fb_copy + (i + start_scans) * disp_stride +
start_bytes,
st3m_fb + i * fb_stride, scan_overlap_bytes);
}
}
xSemaphoreGive(st3m_fb_copy_lock); xSemaphoreGive(st3m_fb_copy_lock);
xSemaphoreGive(st3m_fb_lock); xSemaphoreGive(st3m_fb_lock);
xQueueSend(user_ctx_blitq, &desc_no, portMAX_DELAY); xQueueSend(user_ctx_blitq, &desc_no, portMAX_DELAY);
...@@ -882,6 +971,8 @@ static void st3m_gfx_pipe_put(void) { ...@@ -882,6 +971,8 @@ static void st3m_gfx_pipe_put(void) {
drawlist->osd_y0 = _st3m_osd_y0; drawlist->osd_y0 = _st3m_osd_y0;
drawlist->osd_x1 = _st3m_osd_x1; drawlist->osd_x1 = _st3m_osd_x1;
drawlist->osd_y1 = _st3m_osd_y1; drawlist->osd_y1 = _st3m_osd_y1;
drawlist->blit_x = st3m_gfx_blit_x;
drawlist->blit_y = st3m_gfx_blit_y;
#endif #endif
xQueueSend(user_ctx_rastq, &last_descno, portMAX_DELAY); xQueueSend(user_ctx_rastq, &last_descno, portMAX_DELAY);
} }
...@@ -966,3 +1057,30 @@ void st3m_gfx_overlay_clip(int x0, int y0, int x1, int y1) { ...@@ -966,3 +1057,30 @@ void st3m_gfx_overlay_clip(int x0, int y0, int x1, int y1) {
} }
} }
#endif #endif
void st3m_gfx_fbconfig(int width, int height, int blit_x, int blit_y) {
if (width <= 0) width = st3m_gfx_fb_width;
if (height <= 0) height = st3m_gfx_fb_height;
st3m_gfx_mode set_mode = _st3m_gfx_mode ? _st3m_gfx_mode : default_mode;
int bits = st3m_gfx_bpp(set_mode);
if (width > CTX_MAX_SCANLINE_LENGTH) width = CTX_MAX_SCANLINE_LENGTH;
if ((width * height * bits) / 8 > (240 * 240 * 4))
height = 240 * 240 * 4 * 8 / (width * bits);
blit_x %= width;
blit_y %= height;
if ((st3m_gfx_fb_width != width) || (st3m_gfx_fb_height != height)) {
st3m_gfx_fb_width = width;
st3m_gfx_fb_height = height;
st3m_gfx_geom_dirty++;
}
st3m_gfx_blit_x = blit_x;
st3m_gfx_blit_y = blit_y;
}
void st3m_gfx_get_fbconfig(int *width, int *height, int *blit_x, int *blit_y) {
if (width) *width = st3m_gfx_fb_width;
if (height) *height = st3m_gfx_fb_height;
if (blit_x) *blit_x = st3m_gfx_blit_x;
if (blit_y) *blit_y = st3m_gfx_blit_y;
}
...@@ -43,10 +43,10 @@ typedef enum { ...@@ -43,10 +43,10 @@ typedef enum {
st3m_gfx_1bpp = 1, st3m_gfx_1bpp = 1,
st3m_gfx_2bpp = 2, st3m_gfx_2bpp = 2,
st3m_gfx_4bpp = 4, st3m_gfx_4bpp = 4,
st3m_gfx_8bpp = 8, st3m_gfx_8bpp = 8, // bare 8bpp mode is grayscale
st3m_gfx_rgb332 = 9, st3m_gfx_rgb332 = 9, // variant of 8bpp mode using RGB
st3m_gfx_sepia = 10, st3m_gfx_sepia = 10, // grayscale rendering with sepia palette
st3m_gfx_cool = 11, st3m_gfx_cool = 11, // grayscale rendering with cool palette
st3m_gfx_palette = 15, st3m_gfx_palette = 15,
// 16bpp modes have the lowest blit overhead - no osd for now // 16bpp modes have the lowest blit overhead - no osd for now
st3m_gfx_16bpp = 16, st3m_gfx_16bpp = 16,
...@@ -136,3 +136,15 @@ void st3m_gfx_splash(const char *text); ...@@ -136,3 +136,15 @@ void st3m_gfx_splash(const char *text);
// Draw the flow3r multi-coloured logo at coordinates x,y and with given // Draw the flow3r multi-coloured logo at coordinates x,y and with given
// dimension (approx. bounding box size). // dimension (approx. bounding box size).
void st3m_gfx_flow3r_logo(Ctx *ctx, float x, float y, float dim); void st3m_gfx_flow3r_logo(Ctx *ctx, float x, float y, float dim);
// configure virtual viewport, the default values are 0, 0, 240, 240 which
// also gives room for a copy of the fb for separate rasterize/blit in 16bpp
//
// with, height: width and height of virtual framebuffer
//
// changing the viewport should be done after setting the graphics mode - upon
// graphics mode setting viewport is reset to 240, 240, 0,0,0,0
void st3m_gfx_fbconfig(int width, int height, int blit_x, int blit_y);
// get fbconfig values, arguments passed NULL ptrs are ignored.
void st3m_gfx_get_fbconfig(int *width, int *height, int *blit_x, int *blit_y);
...@@ -75,6 +75,7 @@ class ApplicationMenu(SimpleMenu): ...@@ -75,6 +75,7 @@ class ApplicationMenu(SimpleMenu):
# set the default graphics mode, this is a no-op if # set the default graphics mode, this is a no-op if
# it is already set # it is already set
sys_display.set_mode(0) sys_display.set_mode(0)
sys_display.fbconfig(240, 240, 0, 0)
leds.set_slew_rate(100) leds.set_slew_rate(100)
leds.set_gamma(1.0, 1.0, 1.0) leds.set_gamma(1.0, 1.0, 1.0)
leds.set_auto_update(False) leds.set_auto_update(False)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment