From 3db31e44e5e2d4e4dac605ecb0935939ab453a2e Mon Sep 17 00:00:00 2001 From: VIFEX Date: Fri, 30 Aug 2024 16:48:24 +0800 Subject: [PATCH] fix(vg_lite): select blend mode based on premultiplication (#6766) Signed-off-by: pengyiqiang Co-authored-by: pengyiqiang --- src/draw/lv_draw_buf.c | 2 +- src/draw/lv_draw_buf.h | 2 +- src/draw/vg_lite/lv_draw_vg_lite_arc.c | 2 +- src/draw/vg_lite/lv_draw_vg_lite_img.c | 13 ++++++++++--- src/draw/vg_lite/lv_draw_vg_lite_vector.c | 2 +- src/draw/vg_lite/lv_vg_lite_utils.c | 10 +++++----- src/draw/vg_lite/lv_vg_lite_utils.h | 4 ++-- 7 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/draw/lv_draw_buf.c b/src/draw/lv_draw_buf.c index daebe9543..06e67ed25 100644 --- a/src/draw/lv_draw_buf.c +++ b/src/draw/lv_draw_buf.c @@ -536,7 +536,7 @@ void lv_draw_buf_set_palette(lv_draw_buf_t * draw_buf, uint8_t index, lv_color32 palette[index] = color; } -bool lv_draw_buf_has_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag) +bool lv_draw_buf_has_flag(const lv_draw_buf_t * draw_buf, lv_image_flags_t flag) { return draw_buf->header.flags & flag; } diff --git a/src/draw/lv_draw_buf.h b/src/draw/lv_draw_buf.h index 05fb9008d..f491aa97a 100644 --- a/src/draw/lv_draw_buf.h +++ b/src/draw/lv_draw_buf.h @@ -304,7 +304,7 @@ lv_result_t lv_draw_buf_adjust_stride(lv_draw_buf_t * src, uint32_t stride); */ lv_result_t lv_draw_buf_premultiply(lv_draw_buf_t * draw_buf); -bool lv_draw_buf_has_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag); +bool lv_draw_buf_has_flag(const lv_draw_buf_t * draw_buf, lv_image_flags_t flag); void lv_draw_buf_set_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag); diff --git a/src/draw/vg_lite/lv_draw_vg_lite_arc.c b/src/draw/vg_lite/lv_draw_vg_lite_arc.c index 68893c0e4..e432dd0ca 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_arc.c +++ b/src/draw/vg_lite/lv_draw_vg_lite_arc.c @@ -174,7 +174,7 @@ void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * d if(dsc->img_src) { vg_lite_buffer_t src_buf; lv_image_decoder_dsc_t decoder_dsc; - if(lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->img_src, false)) { + if(lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->img_src, false, true)) { vg_lite_matrix_t path_matrix; vg_lite_identity(&path_matrix); lv_vg_lite_matrix_multiply(&path_matrix, &u->global_matrix); diff --git a/src/draw/vg_lite/lv_draw_vg_lite_img.c b/src/draw/vg_lite/lv_draw_vg_lite_img.c index 84ce9d268..36cbb9cbe 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_img.c +++ b/src/draw/vg_lite/lv_draw_vg_lite_img.c @@ -74,7 +74,10 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * vg_lite_buffer_t src_buf; lv_image_decoder_dsc_t decoder_dsc; - if(!lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->src, no_cache)) { + + /* if not support blend normal, premultiply alpha */ + bool premultiply = !lv_vg_lite_support_blend_normal(); + if(!lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->src, no_cache, premultiply)) { LV_PROFILER_END; return; } @@ -91,6 +94,10 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * lv_memset(&color, dsc->opa, sizeof(color)); } + /* convert the blend mode to vg-lite blend mode, considering the premultiplied alpha */ + bool has_pre_mul = lv_draw_buf_has_flag(decoder_dsc.decoded, LV_IMAGE_FLAGS_PREMULTIPLIED); + vg_lite_blend_t blend = lv_vg_lite_blend_mode(dsc->blend_mode, has_pre_mul); + vg_lite_matrix_t matrix; vg_lite_identity(&matrix); lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix); @@ -118,7 +125,7 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * &src_buf, &rect, &matrix, - lv_vg_lite_blend_mode(dsc->blend_mode), + blend, color, filter)); LV_PROFILER_END_TAG("vg_lite_blit_rect"); @@ -168,7 +175,7 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * &path_matrix, &src_buf, &matrix, - lv_vg_lite_blend_mode(dsc->blend_mode), + blend, VG_LITE_PATTERN_COLOR, 0, color, diff --git a/src/draw/vg_lite/lv_draw_vg_lite_vector.c b/src/draw/vg_lite/lv_draw_vg_lite_vector.c index a70caf804..5aa443afa 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_vector.c +++ b/src/draw/vg_lite/lv_draw_vg_lite_vector.c @@ -217,7 +217,7 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec /* draw image */ vg_lite_buffer_t image_buffer; lv_image_decoder_dsc_t decoder_dsc; - if(lv_vg_lite_buffer_open_image(&image_buffer, &decoder_dsc, dsc->fill_dsc.img_dsc.src, false)) { + if(lv_vg_lite_buffer_open_image(&image_buffer, &decoder_dsc, dsc->fill_dsc.img_dsc.src, false, true)) { /* Calculate pattern matrix. Should start from path bond box, and also apply fill matrix. */ lv_matrix_t m = dsc->matrix; lv_matrix_translate(&m, min_x, min_y); diff --git a/src/draw/vg_lite/lv_vg_lite_utils.c b/src/draw/vg_lite/lv_vg_lite_utils.c index e2b763692..360eff38a 100644 --- a/src/draw/vg_lite/lv_vg_lite_utils.c +++ b/src/draw/vg_lite/lv_vg_lite_utils.c @@ -714,7 +714,7 @@ void lv_vg_lite_image_matrix(vg_lite_matrix_t * matrix, int32_t x, int32_t y, co } bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_dsc_t * decoder_dsc, const void * src, - bool no_cache) + bool no_cache, bool premultiply) { LV_ASSERT_NULL(buffer); LV_ASSERT_NULL(decoder_dsc); @@ -722,7 +722,7 @@ bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_ds lv_image_decoder_args_t args; lv_memzero(&args, sizeof(lv_image_decoder_args_t)); - args.premultiply = !lv_vg_lite_support_blend_normal(); + args.premultiply = premultiply; args.stride_align = true; args.use_indexed = true; args.no_cache = no_cache; @@ -819,9 +819,9 @@ vg_lite_color_t lv_vg_lite_color(lv_color_t color, lv_opa_t opa, bool pre_mul) return (uint32_t)opa << 24 | (uint32_t)color.blue << 16 | (uint32_t)color.green << 8 | color.red; } -vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode) +vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode, bool has_pre_mul) { - if(vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT)) { + if(!has_pre_mul && vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT)) { switch(blend_mode) { case LV_BLEND_MODE_NORMAL: /**< Simply mix according to the opacity value*/ return VG_LITE_BLEND_NORMAL_LVGL; @@ -842,7 +842,7 @@ vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode) switch(blend_mode) { case LV_BLEND_MODE_NORMAL: /**< Simply mix according to the opacity value*/ - if(vg_lite_query_feature(gcFEATURE_BIT_VG_HW_PREMULTIPLY)) { + if(!has_pre_mul && vg_lite_query_feature(gcFEATURE_BIT_VG_HW_PREMULTIPLY)) { return VG_LITE_BLEND_PREMULTIPLY_SRC_OVER; } return VG_LITE_BLEND_SRC_OVER; diff --git a/src/draw/vg_lite/lv_vg_lite_utils.h b/src/draw/vg_lite/lv_vg_lite_utils.h index 62e65620d..704731700 100644 --- a/src/draw/vg_lite/lv_vg_lite_utils.h +++ b/src/draw/vg_lite/lv_vg_lite_utils.h @@ -131,13 +131,13 @@ void lv_vg_lite_image_matrix(vg_lite_matrix_t * matrix, int32_t x, int32_t y, co void lv_vg_lite_image_dec_init(vg_lite_matrix_t * matrix, int32_t x, int32_t y, const lv_draw_image_dsc_t * dsc); bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_dsc_t * decoder_dsc, const void * src, - bool no_cache); + bool no_cache, bool premultiply); void lv_vg_lite_image_dsc_init(struct lv_draw_vg_lite_unit_t * unit); void lv_vg_lite_image_dsc_deinit(struct lv_draw_vg_lite_unit_t * unit); -vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode); +vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode, bool has_pre_mul); uint32_t lv_vg_lite_get_palette_size(vg_lite_buffer_format_t format);