1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

fix(draw): make SW render work with any stride and add stride=64 to CI

This commit is contained in:
Gabor Kiss-Vamosi 2023-11-14 22:19:56 +01:00
parent cb44516c59
commit 6cda061c65
5 changed files with 28 additions and 31 deletions

View File

@ -23,7 +23,7 @@
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define MAX_BUF_SIZE (uint32_t) 4 * lv_draw_buf_width_to_stride(lv_display_get_horizontal_resolution(_lv_refr_get_disp_refreshing()), lv_display_get_color_format(_lv_refr_get_disp_refreshing())) #define MAX_BUF_SIZE (uint32_t) (4 * lv_display_get_horizontal_resolution(_lv_refr_get_disp_refreshing()) * lv_color_format_get_size(lv_display_get_color_format(_lv_refr_get_disp_refreshing())))
/********************** /**********************
* TYPEDEFS * TYPEDEFS
@ -361,21 +361,19 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t
uint32_t px_size = lv_color_format_get_size(cf_final); uint32_t px_size = lv_color_format_get_size(cf_final);
int32_t buf_h; int32_t buf_h;
if(cf_final == LV_COLOR_FORMAT_RGB565A8) { if(cf_final == LV_COLOR_FORMAT_RGB565A8) {
uint32_t buf_stride = lv_draw_buf_width_to_stride(blend_w, LV_COLOR_FORMAT_RGB565); uint32_t buf_stride = blend_w * 3;
buf_stride += blend_w; /*For the A8 part which is not stride aligned*/
buf_h = MAX_BUF_SIZE / buf_stride; buf_h = MAX_BUF_SIZE / buf_stride;
if(buf_h > blend_h) buf_h = blend_h; if(buf_h > blend_h) buf_h = blend_h;
tmp_buf = lv_draw_buf_malloc(buf_stride * buf_h, LV_COLOR_FORMAT_RGB565A8); tmp_buf = lv_malloc(buf_stride * buf_h);
} }
else { else {
uint32_t buf_stride = lv_draw_buf_width_to_stride(blend_w, cf_final); uint32_t buf_stride = blend_w * lv_color_format_get_size(cf_final);
buf_h = MAX_BUF_SIZE / buf_stride; buf_h = MAX_BUF_SIZE / buf_stride;
if(buf_h > blend_h) buf_h = blend_h; if(buf_h > blend_h) buf_h = blend_h;
tmp_buf = lv_draw_buf_malloc(buf_stride * buf_h, cf_final); tmp_buf = lv_malloc(buf_stride * buf_h);
} }
uint8_t * tmp_buf_aligned = lv_draw_buf_align(tmp_buf, cf_final); blend_dsc.src_buf = tmp_buf;
blend_dsc.src_buf = tmp_buf_aligned;
blend_dsc.src_color_format = cf_final; blend_dsc.src_color_format = cf_final;
int32_t y_last = blend_area.y2; int32_t y_last = blend_area.y2;
blend_area.y2 = blend_area.y1 + buf_h - 1; blend_area.y2 = blend_area.y1 + buf_h - 1;
@ -384,8 +382,8 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t
if(cf_final == LV_COLOR_FORMAT_RGB565A8) { if(cf_final == LV_COLOR_FORMAT_RGB565A8) {
/*RGB565A8 images will blended as RGB565 + mask /*RGB565A8 images will blended as RGB565 + mask
*Therefore the stride can be different. */ *Therefore the stride can be different. */
blend_dsc.src_stride = lv_draw_buf_width_to_stride(blend_w, LV_COLOR_FORMAT_RGB565); blend_dsc.src_stride = blend_w * 2;
blend_dsc.mask_buf = tmp_buf_aligned + lv_draw_buf_width_to_stride(blend_w, LV_COLOR_FORMAT_RGB565) * buf_h; blend_dsc.mask_buf = tmp_buf + blend_w * 2 * buf_h;
blend_dsc.mask_stride = blend_w; blend_dsc.mask_stride = blend_w;
blend_dsc.mask_area = &blend_area; blend_dsc.mask_area = &blend_area;
blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED;
@ -400,7 +398,7 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t
blend_dsc.src_buf = NULL; blend_dsc.src_buf = NULL;
} }
else { else {
blend_dsc.src_stride = lv_draw_buf_width_to_stride(blend_w, cf_final); blend_dsc.src_stride = blend_w * lv_color_format_get_size(cf_final);
} }
while(blend_area.y1 <= y_last) { while(blend_area.y1 <= y_last) {
@ -410,7 +408,7 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t
lv_area_move(&relative_area, -img_coords->x1, -img_coords->y1); lv_area_move(&relative_area, -img_coords->x1, -img_coords->y1);
if(transformed) { if(transformed) {
lv_draw_sw_transform(draw_unit, &relative_area, src_buf, src_w, src_h, img_stride, lv_draw_sw_transform(draw_unit, &relative_area, src_buf, src_w, src_h, img_stride,
draw_dsc, sup, cf, tmp_buf_aligned); draw_dsc, sup, cf, tmp_buf);
} }
else if(draw_dsc->recolor_opa >= LV_OPA_MIN) { else if(draw_dsc->recolor_opa >= LV_OPA_MIN) {
int32_t h = lv_area_get_height(&relative_area); int32_t h = lv_area_get_height(&relative_area);
@ -419,7 +417,7 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t
const uint8_t * rgb_src_buf = src_buf + stride_px * 2 * relative_area.y1 + relative_area.x1 * 2; const uint8_t * rgb_src_buf = src_buf + stride_px * 2 * relative_area.y1 + relative_area.x1 * 2;
const uint8_t * a_src_buf = src_buf + stride_px * 2 * src_h + stride_px * relative_area.y1 + const uint8_t * a_src_buf = src_buf + stride_px * 2 * src_h + stride_px * relative_area.y1 +
relative_area.x1; relative_area.x1;
uint8_t * rgb_dest_buf = tmp_buf_aligned; uint8_t * rgb_dest_buf = tmp_buf;
uint8_t * a_dest_buf = (uint8_t *)blend_dsc.mask_buf; uint8_t * a_dest_buf = (uint8_t *)blend_dsc.mask_buf;
int32_t i; int32_t i;
for(i = 0; i < h; i++) { for(i = 0; i < h; i++) {
@ -433,7 +431,7 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t
} }
else if(cf_final != LV_COLOR_FORMAT_A8) { else if(cf_final != LV_COLOR_FORMAT_A8) {
const uint8_t * src_buf_tmp = src_buf + img_stride * relative_area.y1 + relative_area.x1 * px_size; const uint8_t * src_buf_tmp = src_buf + img_stride * relative_area.y1 + relative_area.x1 * px_size;
uint8_t * dest_buf_tmp = tmp_buf_aligned; uint8_t * dest_buf_tmp = tmp_buf;
int32_t i; int32_t i;
for(i = 0; i < h; i++) { for(i = 0; i < h; i++) {
lv_memcpy(dest_buf_tmp, src_buf_tmp, blend_w * px_size); lv_memcpy(dest_buf_tmp, src_buf_tmp, blend_w * px_size);
@ -453,9 +451,9 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t
c_mult[0] = (color.blue >> 3) * mix; c_mult[0] = (color.blue >> 3) * mix;
c_mult[1] = (color.green >> 2) * mix; c_mult[1] = (color.green >> 2) * mix;
c_mult[2] = (color.red >> 3) * mix; c_mult[2] = (color.red >> 3) * mix;
uint16_t * buf16 = (uint16_t *)tmp_buf_aligned; uint16_t * buf16 = (uint16_t *)tmp_buf;
int32_t i; int32_t i;
int32_t size = lv_draw_buf_width_to_stride(blend_w, LV_COLOR_FORMAT_RGB565) / 2 * lv_area_get_height(&blend_area); int32_t size = lv_area_get_size(&blend_area);
for(i = 0; i < size; i++) { for(i = 0; i < size; i++) {
buf16[i] = (((c_mult[2] + ((buf16[i] >> 11) & 0x1F) * mix_inv) << 3) & 0xF800) + buf16[i] = (((c_mult[2] + ((buf16[i] >> 11) & 0x1F) * mix_inv) << 3) & 0xF800) +
(((c_mult[1] + ((buf16[i] >> 5) & 0x3F) * mix_inv) >> 3) & 0x07E0) + (((c_mult[1] + ((buf16[i] >> 5) & 0x3F) * mix_inv) >> 3) & 0x07E0) +
@ -469,7 +467,7 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t
c_mult[0] = color.blue * mix; c_mult[0] = color.blue * mix;
c_mult[1] = color.green * mix; c_mult[1] = color.green * mix;
c_mult[2] = color.red * mix; c_mult[2] = color.red * mix;
uint8_t * tmp_buf_2 = tmp_buf_aligned; uint8_t * tmp_buf_2 = tmp_buf;
for(i = 0; i < size * px_size; i += px_size) { for(i = 0; i < size * px_size; i += px_size) {
tmp_buf_2[i + 0] = (c_mult[0] + (tmp_buf_2[i + 0] * mix_inv)) >> 8; tmp_buf_2[i + 0] = (c_mult[0] + (tmp_buf_2[i + 0] * mix_inv)) >> 8;
tmp_buf_2[i + 1] = (c_mult[1] + (tmp_buf_2[i + 1] * mix_inv)) >> 8; tmp_buf_2[i + 1] = (c_mult[1] + (tmp_buf_2[i + 1] * mix_inv)) >> 8;
@ -481,19 +479,18 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t
/*Blend*/ /*Blend*/
lv_draw_sw_blend(draw_unit, &blend_dsc); lv_draw_sw_blend(draw_unit, &blend_dsc);
/*Go to the next lines*/ /*Go to the next area*/
blend_area.y1 = blend_area.y2 + 1; blend_area.y1 = blend_area.y2 + 1;
blend_area.y2 = blend_area.y1 + buf_h - 1; blend_area.y2 = blend_area.y1 + buf_h - 1;
if(blend_area.y2 > y_last) { if(blend_area.y2 > y_last) {
blend_area.y2 = y_last; blend_area.y2 = y_last;
if(cf_final == LV_COLOR_FORMAT_RGB565A8) { if(cf_final == LV_COLOR_FORMAT_RGB565A8) {
blend_dsc.mask_buf = tmp_buf_aligned + lv_draw_buf_width_to_stride(blend_w, blend_dsc.mask_buf = tmp_buf + blend_w * 2 * lv_area_get_height(&blend_area);
LV_COLOR_FORMAT_RGB565) * lv_area_get_height(&blend_area);
} }
} }
} }
lv_draw_buf_free(tmp_buf); lv_free(tmp_buf);
} }
} }

View File

@ -116,15 +116,15 @@ void lv_draw_sw_transform(lv_draw_unit_t * draw_unit, const lv_area_t * dest_are
int32_t dest_stride; int32_t dest_stride;
int32_t src_stride_px; int32_t src_stride_px;
if(src_cf == LV_COLOR_FORMAT_RGB888) { if(src_cf == LV_COLOR_FORMAT_RGB888) {
dest_stride = lv_draw_buf_width_to_stride(dest_w, LV_COLOR_FORMAT_ARGB8888); dest_stride = dest_w * lv_color_format_get_size(LV_COLOR_FORMAT_ARGB8888);
src_stride_px = src_stride / lv_color_format_get_size(LV_COLOR_FORMAT_RGB888); src_stride_px = src_stride / lv_color_format_get_size(LV_COLOR_FORMAT_RGB888);
} }
else if(src_cf == LV_COLOR_FORMAT_RGB565A8) { else if(src_cf == LV_COLOR_FORMAT_RGB565A8) {
dest_stride = lv_draw_buf_width_to_stride(dest_w, LV_COLOR_FORMAT_RGB565); dest_stride = dest_w * 2;
src_stride_px = src_stride / lv_color_format_get_size(LV_COLOR_FORMAT_RGB565); src_stride_px = src_stride / lv_color_format_get_size(LV_COLOR_FORMAT_RGB565);
} }
else { else {
dest_stride = lv_draw_buf_width_to_stride(dest_w, src_cf); dest_stride = dest_w * lv_color_format_get_size(src_cf);
src_stride_px = src_stride / lv_color_format_get_size(src_cf); src_stride_px = src_stride / lv_color_format_get_size(src_cf);
} }

View File

@ -102,26 +102,26 @@ void lv_canvas_set_px(lv_obj_t * obj, int32_t x, int32_t y, lv_color_t color, lv
} }
else if(canvas->dsc.header.cf == LV_COLOR_FORMAT_A8) { else if(canvas->dsc.header.cf == LV_COLOR_FORMAT_A8) {
uint8_t * buf = (uint8_t *)canvas->dsc.data; uint8_t * buf = (uint8_t *)canvas->dsc.data;
buf += canvas->dsc.header.w * y + x; buf += canvas->dsc.header.stride * y + x;
*buf = opa; *buf = opa;
} }
else if(canvas->dsc.header.cf == LV_COLOR_FORMAT_RGB565) { else if(canvas->dsc.header.cf == LV_COLOR_FORMAT_RGB565) {
lv_color16_t * buf = (lv_color16_t *)canvas->dsc.data; lv_color16_t * buf = (lv_color16_t *)canvas->dsc.data;
buf += canvas->dsc.header.w * y + x; buf += canvas->dsc.header.stride / 2 * y + x;
buf->red = color.red >> 3; buf->red = color.red >> 3;
buf->green = color.green >> 2; buf->green = color.green >> 2;
buf->blue = color.blue >> 3; buf->blue = color.blue >> 3;
} }
else if(canvas->dsc.header.cf == LV_COLOR_FORMAT_RGB888) { else if(canvas->dsc.header.cf == LV_COLOR_FORMAT_RGB888) {
uint8_t * buf = (uint8_t *)canvas->dsc.data; uint8_t * buf = (uint8_t *)canvas->dsc.data;
buf += canvas->dsc.header.w * y * 3 + x * 3; buf += canvas->dsc.header.stride / 3 * y * 3 + x * 3;
buf[2] = color.red; buf[2] = color.red;
buf[1] = color.green; buf[1] = color.green;
buf[0] = color.blue; buf[0] = color.blue;
} }
else if(canvas->dsc.header.cf == LV_COLOR_FORMAT_XRGB8888) { else if(canvas->dsc.header.cf == LV_COLOR_FORMAT_XRGB8888) {
uint8_t * buf = (uint8_t *)canvas->dsc.data; uint8_t * buf = (uint8_t *)canvas->dsc.data;
buf += canvas->dsc.header.w * y * 4 + x * 4; buf += canvas->dsc.header.stride / 4 * y * 4 + x * 4;
buf[2] = color.red; buf[2] = color.red;
buf[1] = color.green; buf[1] = color.green;
buf[0] = color.blue; buf[0] = color.blue;
@ -129,7 +129,7 @@ void lv_canvas_set_px(lv_obj_t * obj, int32_t x, int32_t y, lv_color_t color, lv
} }
else if(canvas->dsc.header.cf == LV_COLOR_FORMAT_ARGB8888) { else if(canvas->dsc.header.cf == LV_COLOR_FORMAT_ARGB8888) {
lv_color32_t * buf = (lv_color32_t *)canvas->dsc.data; lv_color32_t * buf = (lv_color32_t *)canvas->dsc.data;
buf += canvas->dsc.header.w * y + x; buf += canvas->dsc.header.stride / 4 * y + x;
buf->red = color.red; buf->red = color.red;
buf->green = color.green; buf->green = color.green;
buf->blue = color.blue; buf->blue = color.blue;

View File

@ -87,7 +87,7 @@ typedef void * lv_user_data_t;
#undef LV_LOG_PRINTF #undef LV_LOG_PRINTF
/*Use a large value be sure any issues will cause crash*/ /*Use a large value be sure any issues will cause crash*/
//#define LV_DRAW_BUF_STRIDE_ALIGN 64 #define LV_DRAW_BUF_STRIDE_ALIGN 64
/*Use non power of 2 to avoid the case when `malloc` returns aligned pointer by default, and use a large value be sure any issues will cause crash*/ /*Use non power of 2 to avoid the case when `malloc` returns aligned pointer by default, and use a large value be sure any issues will cause crash*/
#define LV_DRAW_BUF_ALIGN 852 #define LV_DRAW_BUF_ALIGN 852

View File

@ -153,7 +153,7 @@ static void create_ui(void)
} }
/*Large byte array*/ /*Large byte array*/
static uint8_t canvas_buf[CANVAS_WIDTH_TO_STRIDE(400, 2) * 100 * 2]; static uint8_t canvas_buf[CANVAS_WIDTH_TO_STRIDE(400, 2) * 100 * 2 + LV_DRAW_BUF_ALIGN];
lv_obj_t * canvas = lv_canvas_create(scr); lv_obj_t * canvas = lv_canvas_create(scr);
lv_obj_set_grid_cell(canvas, LV_GRID_ALIGN_START, 0, 2, LV_GRID_ALIGN_START, 2, 1); lv_obj_set_grid_cell(canvas, LV_GRID_ALIGN_START, 0, 2, LV_GRID_ALIGN_START, 2, 1);