diff --git a/examples/styles/lv_example_style_15.c b/examples/styles/lv_example_style_15.c index 0e5184f11..cab321f71 100644 --- a/examples/styles/lv_example_style_15.c +++ b/examples/styles/lv_example_style_15.c @@ -35,7 +35,7 @@ void lv_example_style_15(void) *The button and the label is rendered to a layer first and that layer is transformed*/ btn = lv_btn_create(lv_scr_act()); lv_obj_set_size(btn, 100, 40); - lv_obj_set_style_transform_angle(btn, 150, 0); /*150 deg*/ + lv_obj_set_style_transform_angle(btn, 150, 0); /*15 deg*/ lv_obj_set_style_transform_zoom(btn, 256 + 64, 0); /*1.25x*/ lv_obj_set_style_transform_pivot_x(btn, 50, 0); lv_obj_set_style_transform_pivot_y(btn, 20, 0); diff --git a/src/core/lv_obj.h b/src/core/lv_obj.h index e9c6d7f30..c89e46099 100644 --- a/src/core/lv_obj.h +++ b/src/core/lv_obj.h @@ -167,7 +167,8 @@ typedef struct { lv_scroll_snap_t scroll_snap_x : 2; /**< Where to align the snappable children horizontally*/ lv_scroll_snap_t scroll_snap_y : 2; /**< Where to align the snappable children vertically*/ lv_dir_t scroll_dir : 4; /**< The allowed scroll direction(s)*/ - uint8_t event_dsc_cnt; /**< Number of event callbacks stored in `event_dsc` array*/ + uint8_t event_dsc_cnt : 6; /**< Number of event callbacks stored in `event_dsc` array*/ + uint8_t layer_type : 2; /**< Cache the layer type here. Element of @lv_intermediate_layer_type_t */ } _lv_obj_spec_attr_t; typedef struct _lv_obj_t { diff --git a/src/core/lv_obj_draw.c b/src/core/lv_obj_draw.c index 3ab3c9686..f2428cddf 100644 --- a/src/core/lv_obj_draw.c +++ b/src/core/lv_obj_draw.c @@ -394,16 +394,11 @@ lv_coord_t _lv_obj_get_ext_draw_size(const lv_obj_t * obj) else return 0; } -lv_intermediate_layer_type_t _lv_obj_is_intermediate_layer(const lv_obj_t * obj) +lv_layer_type_t _lv_obj_get_layer_type(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; + if(obj->spec_attr) return obj->spec_attr->layer_type; + else return LV_LAYER_TYPE_NONE; } /********************** diff --git a/src/core/lv_obj_draw.h b/src/core/lv_obj_draw.h index f981e6013..3f9d0f30f 100644 --- a/src/core/lv_obj_draw.h +++ b/src/core/lv_obj_draw.h @@ -34,10 +34,10 @@ typedef enum { } lv_cover_res_t; typedef enum { - LV_INTERMEDIATE_LAYER_TYPE_NONE, - LV_INTERMEDIATE_LAYER_TYPE_SIMPLE, - LV_INTERMEDIATE_LAYER_TYPE_TRANSFORM, -} lv_intermediate_layer_type_t; + LV_LAYER_TYPE_NONE, + LV_LAYER_TYPE_SIMPLE, + LV_LAYER_TYPE_TRANSFORM, +} lv_layer_type_t; typedef struct { lv_draw_ctx_t * draw_ctx; /**< Draw context*/ @@ -159,7 +159,7 @@ void lv_obj_refresh_ext_draw_size(struct _lv_obj_t * obj); lv_coord_t _lv_obj_get_ext_draw_size(const struct _lv_obj_t * obj); -lv_intermediate_layer_type_t _lv_obj_is_intermediate_layer(const struct _lv_obj_t * obj); +lv_layer_type_t _lv_obj_get_layer_type(const struct _lv_obj_t * obj); /********************** * MACROS diff --git a/src/core/lv_obj_pos.c b/src/core/lv_obj_pos.c index f65970249..c8998b5a1 100644 --- a/src/core/lv_obj_pos.c +++ b/src/core/lv_obj_pos.c @@ -798,12 +798,14 @@ void lv_obj_move_children_by(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_dif void lv_obj_transform_point(const lv_obj_t * obj, lv_point_t * p, bool recursive, bool inv) { if(obj) { + lv_layer_type_t layer_type = _lv_obj_get_layer_type(obj); + bool do_tranf = layer_type == LV_LAYER_TYPE_TRANSFORM; if(inv) { if(recursive) lv_obj_transform_point(lv_obj_get_parent(obj), p, recursive, inv); - transform_point(obj, p, inv); + if(do_tranf) transform_point(obj, p, inv); } else { - transform_point(obj, p, inv); + if(do_tranf) transform_point(obj, p, inv); if(recursive) lv_obj_transform_point(lv_obj_get_parent(obj), p, recursive, inv); } } @@ -818,6 +820,7 @@ void lv_obj_get_transformed_area(const lv_obj_t * obj, lv_area_t * area, bool re {area->x2, area->y1}, {area->x2, area->y2}, }; + lv_obj_transform_point(obj, &p[0], recursive, inv); lv_obj_transform_point(obj, &p[1], recursive, inv); lv_obj_transform_point(obj, &p[2], recursive, inv); diff --git a/src/core/lv_obj_style.c b/src/core/lv_obj_style.c index 117b7b4b2..d2636b32a 100644 --- a/src/core/lv_obj_style.c +++ b/src/core/lv_obj_style.c @@ -51,6 +51,7 @@ static bool trans_del(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop, tran static void trans_anim_cb(void * _tr, int32_t v); static void trans_anim_start_cb(lv_anim_t * a); static void trans_anim_ready_cb(lv_anim_t * a); +static lv_layer_type_t calculate_layer_type(lv_obj_t * obj); static void fade_anim_cb(void * obj, int32_t v); static void fade_in_anim_ready(lv_anim_t * a); @@ -176,6 +177,7 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_selector_t selector, lv_style bool is_layout_refr = lv_style_prop_has_flag(prop, LV_STYLE_PROP_LAYOUT_REFR); bool is_ext_draw = lv_style_prop_has_flag(prop, LV_STYLE_PROP_EXT_DRAW); bool is_inherit = lv_style_prop_has_flag(prop, LV_STYLE_PROP_INHERIT); + bool is_layer_refr = lv_style_prop_has_flag(prop, LV_STYLE_PROP_LAYER_REFR); if(is_layout_refr) { if(part == LV_PART_ANY || @@ -191,6 +193,16 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_selector_t selector, lv_style if(parent) lv_obj_mark_layout_as_dirty(parent); } + /*Cache the layer type*/ + if((part == LV_PART_ANY || part == LV_PART_MAIN) && is_layer_refr) { + lv_layer_type_t layer_type = calculate_layer_type(obj); + if(obj->spec_attr) obj->spec_attr->layer_type = layer_type; + else if(layer_type != LV_LAYER_TYPE_NONE) { + lv_obj_allocate_spec_attr(obj); + obj->spec_attr->layer_type = layer_type; + } + } + if(prop == LV_STYLE_PROP_ANY || is_ext_draw) { lv_obj_refresh_ext_draw_size(obj); } @@ -810,6 +822,18 @@ static void trans_anim_ready_cb(lv_anim_t * a) } } +static lv_layer_type_t calculate_layer_type(lv_obj_t * obj) +{ + if(lv_obj_get_style_transform_angle(obj, 0) != 0) return LV_LAYER_TYPE_TRANSFORM; + if(lv_obj_get_style_transform_zoom(obj, 0) != 256) return LV_LAYER_TYPE_TRANSFORM; + if(lv_obj_get_style_opa(obj, 0) != LV_OPA_COVER) return LV_LAYER_TYPE_SIMPLE; + +#if LV_DRAW_COMPLEX + if(lv_obj_get_style_blend_mode(obj, 0) != LV_BLEND_MODE_NORMAL) return LV_LAYER_TYPE_SIMPLE; +#endif + return LV_LAYER_TYPE_NONE; +} + static void fade_anim_cb(void * obj, int32_t v) { lv_obj_set_style_opa(obj, v, 0); diff --git a/src/core/lv_refr.c b/src/core/lv_refr.c index ef9be3ede..09a30282d 100644 --- a/src/core/lv_refr.c +++ b/src/core/lv_refr.c @@ -731,7 +731,7 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj) if(_lv_area_is_in(area_p, &obj->coords, 0) == false) return NULL; if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return NULL; - if(_lv_obj_is_intermediate_layer(obj)) return NULL; + if(_lv_obj_get_layer_type(obj)) return NULL; /*If this object is fully cover the draw area then check the children too*/ lv_cover_check_info_t info; @@ -815,8 +815,8 @@ void refr_obj(lv_draw_ctx_t * draw_ctx, lv_obj_t * obj) { /*Do not refresh hidden objects*/ if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return; - lv_intermediate_layer_type_t inlayer = _lv_obj_is_intermediate_layer(obj); - if(inlayer == LV_INTERMEDIATE_LAYER_TYPE_NONE) { + lv_layer_type_t inlayer = _lv_obj_get_layer_type(obj); + if(inlayer == LV_LAYER_TYPE_NONE) { lv_obj_redraw(draw_ctx, obj); } else { @@ -831,7 +831,7 @@ void refr_obj(lv_draw_ctx_t * draw_ctx, lv_obj_t * obj) lv_area_increase(&obj_coords_ext, ext_draw_size, ext_draw_size); uint32_t buf_size_sub; - if(inlayer == LV_INTERMEDIATE_LAYER_TYPE_TRANSFORM) { + if(inlayer == LV_LAYER_TYPE_TRANSFORM) { lv_area_t clip_coords_for_obj; lv_area_t tranf_coords = obj_coords_ext; lv_obj_get_transformed_area(obj, &tranf_coords, false, false); @@ -847,7 +847,7 @@ void refr_obj(lv_draw_ctx_t * draw_ctx, lv_obj_t * obj) draw_area = inverse_clip_coords_for_obj; } - else if(inlayer == LV_INTERMEDIATE_LAYER_TYPE_SIMPLE) { + else if(inlayer == LV_LAYER_TYPE_SIMPLE) { lv_area_t clip_coords_for_obj; if(!_lv_area_intersect(&clip_coords_for_obj, clip_area_ori, &obj_coords_ext)) { return; @@ -875,7 +875,7 @@ void refr_obj(lv_draw_ctx_t * draw_ctx, lv_obj_t * obj) uint32_t px_size = full_cover ? sizeof(lv_color_t) : LV_IMG_PX_SIZE_ALPHA_BYTE; - if(inlayer == LV_INTERMEDIATE_LAYER_TYPE_SIMPLE) { + if(inlayer == LV_LAYER_TYPE_SIMPLE) { buf_size_sub = LV_LAYER_SIMPLE_BUF_SIZE; } else { @@ -887,7 +887,7 @@ void refr_obj(lv_draw_ctx_t * draw_ctx, lv_obj_t * obj) uint8_t * layer_buf = lv_mem_alloc(buf_size_sub); /*Try again with a smaller buf size*/ - if(inlayer == LV_INTERMEDIATE_LAYER_TYPE_SIMPLE) { + if(inlayer == LV_LAYER_TYPE_SIMPLE) { if(layer_buf == NULL) { LV_LOG_WARN("Cannot allocate %"LV_PRIu32" bytes for layer buffer. Allocating %"LV_PRIu32" bytes instead. (Reduced performance)", (uint32_t)buf_size_sub * px_size, (uint32_t)LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE * px_size); diff --git a/src/misc/lv_style.c b/src/misc/lv_style.c index 1e96b082c..fa2960f77 100644 --- a/src/misc/lv_style.c +++ b/src/misc/lv_style.c @@ -40,8 +40,8 @@ const uint8_t _lv_style_builtin_prop_flag_lookup_table[_LV_STYLE_NUM_BUILT_IN_PR [LV_STYLE_TRANSFORM_HEIGHT] = LV_STYLE_PROP_EXT_DRAW, [LV_STYLE_TRANSLATE_X] = LV_STYLE_PROP_LAYOUT_REFR | LV_STYLE_PROP_PARENT_LAYOUT_REFR, [LV_STYLE_TRANSLATE_Y] = LV_STYLE_PROP_LAYOUT_REFR | LV_STYLE_PROP_PARENT_LAYOUT_REFR, - [LV_STYLE_TRANSFORM_ZOOM] = LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYOUT_REFR | LV_STYLE_PROP_PARENT_LAYOUT_REFR, - [LV_STYLE_TRANSFORM_ANGLE] = LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYOUT_REFR | LV_STYLE_PROP_PARENT_LAYOUT_REFR, + [LV_STYLE_TRANSFORM_ZOOM] = LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYER_REFR, + [LV_STYLE_TRANSFORM_ANGLE] = LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYER_REFR, [LV_STYLE_PAD_TOP] = LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYOUT_REFR, [LV_STYLE_PAD_BOTTOM] = LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYOUT_REFR, @@ -110,13 +110,13 @@ const uint8_t _lv_style_builtin_prop_flag_lookup_table[_LV_STYLE_NUM_BUILT_IN_PR [LV_STYLE_RADIUS] = 0, [LV_STYLE_CLIP_CORNER] = 0, - [LV_STYLE_OPA] = 0, + [LV_STYLE_OPA] = LV_STYLE_PROP_LAYER_REFR, [LV_STYLE_COLOR_FILTER_DSC] = LV_STYLE_PROP_INHERIT, [LV_STYLE_COLOR_FILTER_OPA] = LV_STYLE_PROP_INHERIT, [LV_STYLE_ANIM_TIME] = 0, [LV_STYLE_ANIM_SPEED] = 0, [LV_STYLE_TRANSITION] = 0, - [LV_STYLE_BLEND_MODE] = 0, + [LV_STYLE_BLEND_MODE] = LV_STYLE_PROP_LAYER_REFR, [LV_STYLE_LAYOUT] = LV_STYLE_PROP_LAYOUT_REFR, [LV_STYLE_BASE_DIR] = LV_STYLE_PROP_INHERIT | LV_STYLE_PROP_LAYOUT_REFR, }; diff --git a/src/misc/lv_style.h b/src/misc/lv_style.h index 8075d8f99..53720442d 100644 --- a/src/misc/lv_style.h +++ b/src/misc/lv_style.h @@ -40,7 +40,8 @@ extern "C" { #define LV_STYLE_PROP_EXT_DRAW (1 << 1) /*Requires ext. draw size update when changed*/ #define LV_STYLE_PROP_LAYOUT_REFR (1 << 2) /*Requires layout update when changed*/ #define LV_STYLE_PROP_PARENT_LAYOUT_REFR (1 << 3) /*Requires layout update on parent when changed*/ -#define LV_STYLE_PROP_ALL (0xf) /*Indicating all flags*/ +#define LV_STYLE_PROP_LAYER_REFR (1 << 4) /*Affects layer handling*/ +#define LV_STYLE_PROP_ALL (0x1F) /*Indicating all flags*/ /** * Other constants