arch(draw): allow replacing the draw engine

BREAKING CHANGE: the API of lv_draw_... function have been changed
This commit is contained in:
Gabor Kiss-Vamosi
2021-11-29 14:54:37 +01:00
parent 0831b6ba76
commit db53ea925c
121 changed files with 3984 additions and 3382 deletions

View File

@@ -25,11 +25,10 @@
/**********************
* STATIC PROTOTYPES
**********************/
LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * clip_area,
const void * src,
const lv_draw_img_dsc_t * draw_dsc);
LV_ATTRIBUTE_FAST_MEM static lv_res_t decode_and_draw(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * draw_dsc,
const lv_area_t * coords, const void * src);
static void show_error(const lv_area_t * coords, const lv_area_t * clip_area, const char * msg);
static void show_error(lv_draw_ctx_t * draw_ctx, const lv_area_t * coords, const char * msg);
static void draw_cleanup(_lv_img_cache_entry_t * cache);
/**********************
@@ -60,29 +59,27 @@ void lv_draw_img_dsc_init(lv_draw_img_dsc_t * dsc)
* @param src pointer to a lv_color_t array which contains the pixels of the image
* @param dsc pointer to an initialized `lv_draw_img_dsc_t` variable
*/
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_draw_img_dsc_t * dsc)
void lv_draw_img(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc, const lv_area_t * coords, const void * src)
{
if(src == NULL) {
LV_LOG_WARN("Image draw: src is NULL");
show_error(coords, mask, "No\ndata");
show_error(draw_ctx, coords, "No\ndata");
return;
}
if(dsc->opa <= LV_OPA_MIN) return;
const lv_draw_backend_t * backend = lv_draw_backend_get();
lv_res_t res;
if(backend->draw_img_core) {
res = backend->draw_img_core(coords, mask, src, dsc);
if(draw_ctx->draw_img) {
res = draw_ctx->draw_img(draw_ctx, dsc, coords, src);
}
else {
res = lv_img_draw_core(coords, mask, src, dsc);
res = decode_and_draw(draw_ctx, dsc, coords, src);
}
if(res == LV_RES_INV) {
LV_LOG_WARN("Image draw error");
show_error(coords, mask, "No\ndata");
show_error(draw_ctx, coords, "No\ndata");
return;
}
}
@@ -222,13 +219,20 @@ lv_img_src_t lv_img_src_get_type(const void * src)
return img_src_type;
}
void lv_draw_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc,
const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t color_format)
{
if(draw_ctx->draw_img_decoded == NULL) return;
draw_ctx->draw_img_decoded(draw_ctx, dsc, coords, map_p, color_format);
}
/**********************
* STATIC FUNCTIONS
**********************/
LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * clip_area,
const void * src,
const lv_draw_img_dsc_t * draw_dsc)
LV_ATTRIBUTE_FAST_MEM static lv_res_t decode_and_draw(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * draw_dsc,
const lv_area_t * coords, const void * src)
{
if(draw_dsc->opa <= LV_OPA_MIN) return LV_RES_OK;
@@ -237,14 +241,15 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords,
if(cdsc == NULL) return LV_RES_INV;
const lv_draw_backend_t * backend = lv_draw_backend_get();
bool chroma_keyed = lv_img_cf_is_chroma_keyed(cdsc->dec_dsc.header.cf);
bool alpha_byte = lv_img_cf_has_alpha(cdsc->dec_dsc.header.cf);
lv_img_cf_t cf;
if(lv_img_cf_is_chroma_keyed(cdsc->dec_dsc.header.cf)) cf = LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED;
else if(lv_img_cf_has_alpha(cdsc->dec_dsc.header.cf)) cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
else cf = LV_IMG_CF_TRUE_COLOR;
if(cdsc->dec_dsc.error_msg != NULL) {
LV_LOG_WARN("Image draw error");
show_error(coords, clip_area, cdsc->dec_dsc.error_msg);
show_error(draw_ctx, coords, cdsc->dec_dsc.error_msg);
}
/*The decoder could open the image and gave the entire uncompressed image.
*Just draw it!*/
@@ -263,22 +268,25 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords,
map_area_rot.y2 += coords->y1;
}
lv_area_t mask_com; /*Common area of mask and coords*/
lv_area_t clip_com; /*Common area of mask and coords*/
bool union_ok;
union_ok = _lv_area_intersect(&mask_com, clip_area, &map_area_rot);
union_ok = _lv_area_intersect(&clip_com, draw_ctx->clip_area, &map_area_rot);
/*Out of mask. There is nothing to draw so the image is drawn successfully.*/
if(union_ok == false) {
draw_cleanup(cdsc);
return LV_RES_OK;
}
backend->draw_img(coords, &mask_com, cdsc->dec_dsc.img_data, draw_dsc, chroma_keyed, alpha_byte);
const lv_area_t * clip_area_ori = draw_ctx->clip_area;
draw_ctx->clip_area = &clip_com;
lv_draw_img_decoded(draw_ctx, draw_dsc, coords, cdsc->dec_dsc.img_data, cf);
draw_ctx->clip_area = clip_area_ori;
}
/*The whole uncompressed image is not available. Try to read it line-by-line*/
else {
lv_area_t mask_com; /*Common area of mask and coords*/
bool union_ok;
union_ok = _lv_area_intersect(&mask_com, clip_area, coords);
union_ok = _lv_area_intersect(&mask_com, draw_ctx->clip_area, coords);
/*Out of mask. There is nothing to draw so the image is drawn successfully.*/
if(union_ok == false) {
draw_cleanup(cdsc);
@@ -299,7 +307,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords,
lv_res_t read_res;
for(row = mask_com.y1; row <= mask_com.y2; row++) {
lv_area_t mask_line;
union_ok = _lv_area_intersect(&mask_line, clip_area, &line);
union_ok = _lv_area_intersect(&mask_line, draw_ctx->clip_area, &line);
if(union_ok == false) continue;
read_res = lv_img_decoder_read_line(&cdsc->dec_dsc, x, y, width, buf);
@@ -311,7 +319,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords,
return LV_RES_INV;
}
backend->draw_img(&line, &mask_line, buf, draw_dsc, chroma_keyed, alpha_byte);
lv_draw_img_decoded(draw_ctx, draw_dsc, &line, buf, cf);
line.y1++;
line.y2++;
y++;
@@ -324,16 +332,16 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords,
}
static void show_error(const lv_area_t * coords, const lv_area_t * clip_area, const char * msg)
static void show_error(lv_draw_ctx_t * draw_ctx, const lv_area_t * coords, const char * msg)
{
lv_draw_rect_dsc_t rect_dsc;
lv_draw_rect_dsc_init(&rect_dsc);
rect_dsc.bg_color = lv_color_white();
lv_draw_rect(coords, clip_area, &rect_dsc);
lv_draw_rect(draw_ctx, &rect_dsc, coords);
lv_draw_label_dsc_t label_dsc;
lv_draw_label_dsc_init(&label_dsc);
lv_draw_label(coords, clip_area, &label_dsc, msg, NULL);
lv_draw_label(draw_ctx, &label_dsc, coords, msg, NULL);
}
static void draw_cleanup(_lv_img_cache_entry_t * cache)