1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

fix(draw): create intermediate layer for blend modes too

This commit is contained in:
Gabor Kiss-Vamosi 2022-04-26 11:23:55 +02:00
parent 318146a2c2
commit 8b15007568
6 changed files with 22 additions and 21 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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