arch(draw): allow replacing the draw engine
BREAKING CHANGE: the API of lv_draw_... function have been changed
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user