From 8b150075681455c6424ddd536e991307ac828eb4 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 26 Apr 2022 11:23:55 +0200 Subject: [PATCH] fix(draw): create intermediate layer for blend modes too --- docs/overview/style.md | 10 ++++++---- lv_conf_template.h | 6 +++--- src/core/lv_obj.c | 6 ------ src/core/lv_obj_draw.c | 14 +++++++++----- src/core/lv_refr.c | 1 + src/lv_conf_internal.h | 6 +++--- 6 files changed, 22 insertions(+), 21 deletions(-) diff --git a/docs/overview/style.md b/docs/overview/style.md index 40e1d9d36..defa0cab3 100644 --- a/docs/overview/style.md +++ b/docs/overview/style.md @@ -268,20 +268,22 @@ lv_style_transition_dsc_init(&trans1, trans_props, lv_anim_path_ease_out, durati lv_style_set_transition(&style1, &trans1); ``` -## Opacity and Transformations -If the 'opa ', `transform_angle`, or `transform_zoom` properties are set their non-default value LVGL creates a snapshot about the widget and all its children in order to blend the whole widget with the set opacity and transformation properties. +## Opacity, Blend modes and Transformations +If the `opa`, `blend_mode`, `transform_angle`, or `transform_zoom` properties are set to their non-default value LVGL creates a snapshot about the widget and all its children in order to blend the whole widget with the set opacity, blend mode and transformation properties. These properties have this effect only on the `MAIN` part of the widget. -The created snapshot is called "intermediate layer" or simply "layer". If only `opa` is set to a value different from 255 LVGL can build the layer from smaller chunks. The size of these chunks can be configured by the following properties in `lv_conf.h`: +The created snapshot is called "intermediate layer" or simply "layer". If only `opa` and/or `blend_mode` is set to a non-default value LVGL can build the layer from smaller chunks. The size of these chunks can be configured by the following properties in `lv_conf.h`: - `LV_LAYER_SIMPLE_BUF_SIZE`: [bytes] the optimal target buffer size. LVGL will try to allocate this size of memory. - `LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE`: [bytes] used if `LV_LAYER_SIMPLE_BUF_SIZE` couldn't be allocated. If transformation properties were also used the layer can not be rendered in chunks, but one larger memory needs to be allocated. The required memory depends on the angle, zoom and pivot parameters, and the size of the area to redraw, but it's never larger than the size of the widget (including the extra draw size used for shadow, outline, etc). -If the widget can fully cover the area to redraw, LVGL creates an RGB layer (which is faster to render and uses less memory). If the opposite case ARGB rendering needs to be used. A widget might not cover its area if it has radius, `bg_opa != 255`, shadow, outline, etc. +If the widget can fully cover the area to redraw, LVGL creates an RGB layer (which is faster to render and uses less memory). If the opposite case ARGB rendering needs to be used. A widget might not cover its area if it has radius, `bg_opa != 255`, has shadow, outline, etc. The click area of the widget is also transformed accordingly. + + ## Color filter TODO diff --git a/lv_conf_template.h b/lv_conf_template.h index 0b20d4a50..c46c168e3 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -29,9 +29,9 @@ /*Swap the 2 bytes of RGB565 color. Useful if the display has an 8-bit interface (e.g. SPI)*/ #define LV_COLOR_16_SWAP 0 -/*Enable more complex drawing routines to manage screens transparency. - *Can be used if the UI is above another layer, e.g. an OSD menu or video player. - *Requires `LV_COLOR_DEPTH = 32` colors and the screen's `bg_opa` should be set to non LV_OPA_COVER value*/ +/*Enable features to draw on transparent background. + *It's required if opa, and transform_* style properties are used. + *Can be also used if the UI is above another layer, e.g. an OSD menu or video player.*/ #define LV_COLOR_SCREEN_TRANSP 0 /* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. diff --git a/src/core/lv_obj.c b/src/core/lv_obj.c index 286fdef8a..ae1d9765c 100644 --- a/src/core/lv_obj.c +++ b/src/core/lv_obj.c @@ -498,12 +498,6 @@ static void lv_obj_draw(lv_event_t * e) return; } -#if LV_DRAW_COMPLEX - if(lv_obj_get_style_blend_mode(obj, LV_PART_MAIN) != LV_BLEND_MODE_NORMAL) { - info->res = LV_COVER_RES_NOT_COVER; - return; - } -#endif info->res = LV_COVER_RES_COVER; } diff --git a/src/core/lv_obj_draw.c b/src/core/lv_obj_draw.c index 67a9e5b05..e70835738 100644 --- a/src/core/lv_obj_draw.c +++ b/src/core/lv_obj_draw.c @@ -41,7 +41,7 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint32_t part, lv_draw_rect_dsc_t #if LV_DRAW_COMPLEX draw_dsc->radius = lv_obj_get_style_radius(obj, part); - draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); + if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); if(draw_dsc->bg_opa != LV_OPA_TRANSP) { draw_dsc->bg_opa = lv_obj_get_style_bg_opa(obj, part); @@ -179,7 +179,7 @@ void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint32_t part, lv_draw_label_dsc draw_dsc->line_space = lv_obj_get_style_text_line_space(obj, part); draw_dsc->decor = lv_obj_get_style_text_decor(obj, part); #if LV_DRAW_COMPLEX - draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); + if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); #endif draw_dsc->font = lv_obj_get_style_text_font(obj, part); @@ -206,7 +206,7 @@ void lv_obj_init_draw_img_dsc(lv_obj_t * obj, uint32_t part, lv_draw_img_dsc_t * draw_dsc->recolor = lv_obj_get_style_img_recolor_filtered(obj, part); } #if LV_DRAW_COMPLEX - draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); + if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); #endif } @@ -229,7 +229,7 @@ void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint32_t part, lv_draw_line_dsc_t draw_dsc->round_end = draw_dsc->round_start; #if LV_DRAW_COMPLEX - draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); + if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); #endif } @@ -247,7 +247,7 @@ void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, uint32_t part, lv_draw_arc_dsc_t * draw_dsc->rounded = lv_obj_get_style_arc_rounded(obj, part); #if LV_DRAW_COMPLEX - draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); + if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); #endif } @@ -332,6 +332,10 @@ lv_intermediate_layer_type_t _lv_obj_is_intermediate_layer(const lv_obj_t * obj) if(lv_obj_get_style_transform_angle(obj, 0) != 0) return LV_INTERMEDIATE_LAYER_TYPE_TRANSFORM; if(lv_obj_get_style_transform_zoom(obj, 0) != 256) return LV_INTERMEDIATE_LAYER_TYPE_TRANSFORM; if(lv_obj_get_style_opa(obj, 0) != LV_OPA_COVER) return LV_INTERMEDIATE_LAYER_TYPE_SIMPLE; + +#if LV_DRAW_COMPLEX + if(lv_obj_get_style_blend_mode(obj, 0) != LV_BLEND_MODE_NORMAL) return LV_INTERMEDIATE_LAYER_TYPE_SIMPLE; +#endif return LV_INTERMEDIATE_LAYER_TYPE_NONE; } diff --git a/src/core/lv_refr.c b/src/core/lv_refr.c index 8cd91d627..a8974f435 100644 --- a/src/core/lv_refr.c +++ b/src/core/lv_refr.c @@ -925,6 +925,7 @@ void refr_obj(lv_draw_ctx_t * draw_ctx, lv_obj_t * obj) draw_dsc.opa = opa; draw_dsc.angle = lv_obj_get_style_transform_angle(obj, 0); draw_dsc.zoom = lv_obj_get_style_transform_zoom(obj, 0); + draw_dsc.blend_mode = lv_obj_get_style_blend_mode(obj, 0); draw_dsc.antialias = disp_refr->driver->antialiasing; lv_point_t pivot; diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index a75a6ea20..0e766b184 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -79,9 +79,9 @@ #endif #endif -/*Enable more complex drawing routines to manage screens transparency. - *Can be used if the UI is above another layer, e.g. an OSD menu or video player. - *Requires `LV_COLOR_DEPTH = 32` colors and the screen's `bg_opa` should be set to non LV_OPA_COVER value*/ +/*Enable features to draw on transparent background. + *It's required if opa, and transform_* style properties are used. + *Can be also used if the UI is above another layer, e.g. an OSD menu or video player.*/ #ifndef LV_COLOR_SCREEN_TRANSP #ifdef CONFIG_LV_COLOR_SCREEN_TRANSP #define LV_COLOR_SCREEN_TRANSP CONFIG_LV_COLOR_SCREEN_TRANSP