From 12cd43b47db4460a508a6e62d53adc84698bdcaa Mon Sep 17 00:00:00 2001 From: Michael Gebhard <m.gebhard.91@gmail.com> Date: Fri, 23 Aug 2019 14:07:17 +0200 Subject: [PATCH] display: add set_all function Draw an entire image on the display, to achieve better framerates when playing videos. --- epicardium/epicardium.h | 2 ++ epicardium/modules/display.c | 11 +++++++++++ lib/gfx/gfx.c | 15 +++++++++++++++ lib/gfx/gfx.h | 1 + pycardium/modules/py/display.py | 11 +++++++++++ pycardium/modules/sys_display.c | 23 +++++++++++++++++++++++ 6 files changed, 63 insertions(+) diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h index 08f5ff97..e7947439 100644 --- a/epicardium/epicardium.h +++ b/epicardium/epicardium.h @@ -54,6 +54,7 @@ typedef _Bool bool; #define API_DISP_PIXEL 0x28 #define API_DISP_FRAMEBUFFER 0x29 #define API_DISP_BACKLIGHT 0x2a +#define API_DISP_SET_ALL 0x2b /* API_BATTERY_VOLTAGE 0x30 */ #define API_BATTERY_CURRENT 0x31 @@ -1336,6 +1337,7 @@ API(API_DISP_CIRC, */ API(API_DISP_FRAMEBUFFER, int epic_disp_framebuffer(union disp_framebuffer *fb)); +API(API_DISP_SET_ALL, int epic_disp_set_all(int32_t w, int32_t h, uint8_t *color)); /** * Set the backlight brightness value diff --git a/epicardium/modules/display.c b/epicardium/modules/display.c index c8dc5149..0fc402fc 100644 --- a/epicardium/modules/display.c +++ b/epicardium/modules/display.c @@ -48,6 +48,17 @@ int epic_disp_clear(uint16_t color) } } +int epic_disp_set_all(int32_t w, int32_t h, uint8_t *color) +{ + int cl = check_lock(); + if (cl < 0) { + return cl; + } else { + gfx_set_all(&display_screen, w, h, color); + return 0; + } +} + int epic_disp_pixel(uint16_t x, uint16_t y, uint16_t color) { int cl = check_lock(); diff --git a/lib/gfx/gfx.c b/lib/gfx/gfx.c index 55f1debf..143ccd83 100644 --- a/lib/gfx/gfx.c +++ b/lib/gfx/gfx.c @@ -13,6 +13,21 @@ const struct gfx_color_rgb gfx_colors_rgb[COLORS] = { { 255, 255, 0 } /* YELLOW */ }; +void gfx_set_all(struct gfx_region *r, int32_t w, int32_t h, uint8_t *color) +{ + for (int32_t i = 0; i < w*h; i++) { + fb_setpixel(r->fb, + (i%w), + (i/w), + fb_encode_color_rgb(r->fb, + color[(3*i)+0], + color[(3*i)+1], + color[(3*i)+2] + )); + } + r->fb->update(r->fb); +} + void gfx_setpixel(struct gfx_region *r, int x, int y, Color c) { if (x < 0 || y < 0) diff --git a/lib/gfx/gfx.h b/lib/gfx/gfx.h index 428b196c..7fee0608 100644 --- a/lib/gfx/gfx.h +++ b/lib/gfx/gfx.h @@ -12,6 +12,7 @@ struct gfx_region { size_t height; }; +void gfx_set_all(struct gfx_region *r, int32_t w, int32_t h, uint8_t *color); void gfx_setpixel(struct gfx_region *r, int x, int y, Color c); struct gfx_region gfx_screen(struct framebuffer *fb); void gfx_putchar(sFONT *font, struct gfx_region *reg, int x, int y, char ch, diff --git a/pycardium/modules/py/display.py b/pycardium/modules/py/display.py index e957977d..df1c7a61 100644 --- a/pycardium/modules/py/display.py +++ b/pycardium/modules/py/display.py @@ -101,6 +101,17 @@ class Display: sys_display.backlight(brightness) return self + def set_all(self, w, h, colors): + """ + Draw entire image on the display + + :param w: width, 0 < w <= 160 + :param h: height, 0 < h <= 80 + :param colors: w*h*3 RGB values + """ + sys_display.set_all(w, h, colors) + return self + def line(self, xs, ys, xe, ye, *, col=None, dotted=False, size=1): """ Draws a line on the display. diff --git a/pycardium/modules/sys_display.c b/pycardium/modules/sys_display.c index f5523d54..e3470b9d 100644 --- a/pycardium/modules/sys_display.c +++ b/pycardium/modules/sys_display.c @@ -53,6 +53,28 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN( display_print_obj, 5, 5, mp_display_print ); +static mp_obj_t mp_display_set_all(mp_obj_t w_in, mp_obj_t h_in, mp_obj_t color_in) +{ + uint32_t len = mp_obj_get_int(mp_obj_len(color_in)); + uint32_t w = mp_obj_get_int(w_in); + uint32_t h = mp_obj_get_int(h_in); + if (w*h*3 != len) { + mp_raise_ValueError("width * height * 3 does not match frame size"); + } + uint8_t pattern[len]; + for (int32_t i = 0; i < len; i++) { + pattern[i] = mp_obj_get_int(mp_obj_subscr( + color_in, mp_obj_new_int(i), MP_OBJ_SENTINEL) + ); + } + int res = epic_disp_set_all(w, h, (uint8_t *)pattern); + if (res < 0) { + mp_raise_OSError(-res); + } + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_3(display_set_all_obj, mp_display_set_all); + /* draw pixel on the display */ static mp_obj_t mp_display_pixel(size_t n_args, const mp_obj_t *args) { @@ -236,6 +258,7 @@ static const mp_rom_map_elem_t display_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_print), MP_ROM_PTR(&display_print_obj) }, { MP_ROM_QSTR(MP_QSTR_pixel), MP_ROM_PTR(&display_pixel_obj) }, { MP_ROM_QSTR(MP_QSTR_backlight), MP_ROM_PTR(&display_backlight_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_all), MP_ROM_PTR(&display_set_all_obj) }, { MP_ROM_QSTR(MP_QSTR_line), MP_ROM_PTR(&display_line_obj) }, { MP_ROM_QSTR(MP_QSTR_rect), MP_ROM_PTR(&display_rect_obj) }, { MP_ROM_QSTR(MP_QSTR_circ), MP_ROM_PTR(&display_circ_obj) }, -- GitLab