From 42d9c07eeb0abfdbf8746da3569a5f8bc156ae71 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 18 May 2022 23:06:21 +0200 Subject: [PATCH] fix(color): compensate rounding error during blending fixes #3362 --- src/draw/sw/lv_draw_sw_blend.c | 8 ++++++++ src/misc/lv_color.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/draw/sw/lv_draw_sw_blend.c b/src/draw/sw/lv_draw_sw_blend.c index 5a74fcd3c..f08ad4be8 100644 --- a/src/draw/sw/lv_draw_sw_blend.c +++ b/src/draw/sw/lv_draw_sw_blend.c @@ -249,6 +249,14 @@ LV_ATTRIBUTE_FAST_MEM static void fill_normal(lv_color_t * dest_buf, const lv_ar lv_color_t last_dest_color = lv_color_black(); lv_color_t last_res_color = lv_color_mix(color, last_dest_color, opa); +#if LV_COLOR_MIX_ROUND_OFS == 0 && LV_COLOR_DEPTH == 16 + /*lv_color_mix work with an optimized algorithm with 16 bit color depth. + *However, it introduces some rounded error on opa. + *Introduce the same error here too to make lv_color_premult produces the same result */ + opa = (uint32_t)((uint32_t)opa + 4) >> 3; + opa = opa << 3; +#endif + uint16_t color_premult[3]; lv_color_premult(color, opa, color_premult); lv_opa_t opa_inv = 255 - opa; diff --git a/src/misc/lv_color.h b/src/misc/lv_color.h index e994ff236..2cc92f277 100644 --- a/src/misc/lv_color.h +++ b/src/misc/lv_color.h @@ -442,7 +442,7 @@ LV_ATTRIBUTE_FAST_MEM static inline lv_color_t lv_color_mix(lv_color_t c1, lv_co #if LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP == 0 && LV_COLOR_MIX_ROUND_OFS == 0 /*Source: https://stackoverflow.com/a/50012418/1999969*/ - mix = (mix + 4) >> 3; + mix = (uint32_t)((uint32_t)mix + 4) >> 3; uint32_t bg = (uint32_t)((uint32_t)c2.full | ((uint32_t)c2.full << 16)) & 0x7E0F81F; /*0b00000111111000001111100000011111*/ uint32_t fg = (uint32_t)((uint32_t)c1.full | ((uint32_t)c1.full << 16)) & 0x7E0F81F;