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

fix(vg_lite): select blend mode based on premultiplication (#6766)

Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com>
Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
VIFEX 2024-08-30 16:48:24 +08:00 committed by GitHub
parent 5bfbf0c10d
commit 3db31e44e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 21 additions and 14 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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);