diff --git a/src/lv_core/lv_style.c b/src/lv_core/lv_style.c index 26f7267ed..ac432c407 100644 --- a/src/lv_core/lv_style.c +++ b/src/lv_core/lv_style.c @@ -71,7 +71,7 @@ void lv_style_init(void) /*Screen style*/ lv_style_scr.glass = 0; - lv_style_scr.body.opa = LV_OPA_COVER; + lv_style_scr.body.opa = LV_OPA_TRANSP; lv_style_scr.body.main_color = LV_COLOR_WHITE; lv_style_scr.body.grad_color = LV_COLOR_WHITE; lv_style_scr.body.radius = 0; @@ -111,12 +111,13 @@ void lv_style_init(void) lv_style_scr.line.opa = LV_OPA_COVER; lv_style_scr.line.color = lv_color_make(0x20, 0x20, 0x20); - lv_style_scr.line.width = 2; + lv_style_scr.line.width = 1; lv_style_scr.line.rounded = 0; lv_style_scr.line.blend_mode = LV_BLEND_MODE_NORMAL; /*Plain style (by default near the same as the screen style)*/ lv_style_copy(&lv_style_plain, &lv_style_scr); + lv_style_plain.body.opa = LV_OPA_COVER; lv_style_plain.body.padding.left = LV_DPI / 20; lv_style_plain.body.padding.right = LV_DPI / 20; lv_style_plain.body.padding.top = LV_DPI / 20; @@ -173,7 +174,7 @@ void lv_style_init(void) lv_style_btn_rel.body.main_color = lv_color_make(0x76, 0xa2, 0xd0); lv_style_btn_rel.body.grad_color = lv_color_make(0x19, 0x3a, 0x5d); lv_style_btn_rel.body.radius = LV_DPI / 15; - lv_style_btn_rel.body.opa = LV_OPA_COVER; + lv_style_btn_rel.body.opa = LV_OPA_50; // lv_style_btn_rel.body.blend_mode = LV_BLEND_MODE_ADDITIVE; lv_style_btn_rel.body.padding.left = LV_DPI / 4; lv_style_btn_rel.body.padding.right = LV_DPI / 4; diff --git a/src/lv_draw/lv_draw_blend.c b/src/lv_draw/lv_draw_blend.c index 30dcf3b3e..c49bb210a 100644 --- a/src/lv_draw/lv_draw_blend.c +++ b/src/lv_draw/lv_draw_blend.c @@ -17,6 +17,7 @@ *********************/ #define FILL_DIRECT_LEN 32 #define FILL_DIRECT_MASK 0x1F +#define GPU_WIDTH_LIMIT 32 /********************** * TYPEDEFS @@ -36,6 +37,8 @@ static void fill_true_color_blended(const lv_area_t * disp_area, lv_color_t * di +static inline lv_color_t color_mix_with_alpha(lv_color_t bg_color, lv_opa_t bg_opa, lv_color_t fg_color, lv_opa_t fg_opa); + static inline lv_color_t color_blend_true_color_additive(lv_color_t bg, lv_color_t fg, lv_opa_t opa); static inline lv_color_t color_blend_true_color_subtractive(lv_color_t fg, lv_color_t bg, lv_opa_t opa); @@ -77,7 +80,6 @@ void lv_blend_fill(const lv_area_t * clip_area, const lv_area_t * fill_area, lv_disp_buf_t * vdb = lv_disp_get_buf(disp); const lv_area_t * disp_area = &vdb->area; lv_color_t * disp_buf = vdb->buf_act; - lv_img_cf_t cf = LV_IMG_CF_TRUE_COLOR; /* Get clipped fill area which is the real draw area. @@ -94,20 +96,15 @@ void lv_blend_fill(const lv_area_t * clip_area, const lv_area_t * fill_area, draw_area.x2 -= disp_area->x1; draw_area.y2 -= disp_area->y1; - if(cf == LV_IMG_CF_TRUE_COLOR && mode == LV_BLEND_MODE_NORMAL) { + if(mode == LV_BLEND_MODE_NORMAL) { fill_true_color_normal(disp_area, disp_buf, &draw_area, color, opa, mask, mask_res); } else { fill_true_color_blended(disp_area, disp_buf, &draw_area, color, opa, mask, mask_res, mode); - } - - } - - void lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area, const lv_color_t * map_buf, const lv_opa_t * mask, lv_draw_mask_res_t mask_res, lv_opa_t opa, lv_blend_mode_t mode) @@ -127,7 +124,6 @@ void lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area, const lv_disp_buf_t * vdb = lv_disp_get_buf(disp); const lv_area_t * disp_area = &vdb->area; lv_color_t * disp_buf = vdb->buf_act; - lv_img_cf_t cf = LV_IMG_CF_TRUE_COLOR; /* Now `draw_area` has absolute coordinates. * Make it relative to `disp_area` to simplify draw to `disp_buf`*/ @@ -139,6 +135,9 @@ void lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area, const /*Get the width of the `disp_area` it will be used to go to the next line*/ lv_coord_t disp_w = lv_area_get_width(disp_area); + /*Get the width of the `draw_area` it will be used to go to the next line of the mask*/ + lv_coord_t draw_area_w = lv_area_get_width(&draw_area); + /*Get the width of the `mask_area` it will be used to go to the next line*/ lv_coord_t map_w = lv_area_get_width(map_area); @@ -155,8 +154,23 @@ void lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area, const if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) { /*Go to the first px of the map*/ map_buf_tmp += (draw_area.x1 - (map_area->x1 - disp_area->x1)); + +#if LV_USE_GPU + lv_disp_t * disp = lv_refr_get_disp_refreshing(); + if(disp->driver.gpu_blend_cb && + ((draw_area_w > GPU_WIDTH_LIMIT * 4 && opa == LV_OPA_COVER) || + (draw_area_w > GPU_WIDTH_LIMIT && opa != LV_OPA_COVER))) { + for(y = draw_area.y1; y <= draw_area.y2; y++) { + disp->driver.gpu_blend_cb(&disp->driver, &disp_buf_tmp[draw_area.x1], map_buf_tmp, draw_area_w, opa); + disp_buf_tmp += disp_w; + map_buf_tmp += map_w; + } + return; + } +#endif + + if(opa > LV_OPA_MAX) { - lv_coord_t draw_area_w = lv_area_get_width(&draw_area); for(y = draw_area.y1; y <= draw_area.y2; y++) { memcpy(&disp_buf_tmp[draw_area.x1], map_buf_tmp, draw_area_w * sizeof(lv_color_t)); @@ -170,9 +184,6 @@ void lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area, const } /*Masked*/ else { - /*Get the width of the `draw_area` it will be used to go to the next line of the mask*/ - lv_coord_t draw_area_w = lv_area_get_width(&draw_area); - /* The mask is relative to the clipped area. * In the cycles below mask will be indexed from `draw_area.x1` * but it corresponds to zero index. So prepare `mask_tmp` accordingly. */ @@ -194,9 +205,16 @@ void lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area, const for(x = draw_area.x1; x <= draw_area.x2; x++) { if(mask_tmp[x] == 0) continue; if(mask_tmp[x] != last_mask || last_dest_color.full != disp_buf_tmp[x].full || last_map_color.full != map_buf_tmp[x].full) { - if(mask_tmp[x] > LV_OPA_MAX) last_res_color = map_buf_tmp[x]; - else if(mask_tmp[x] < LV_OPA_MIN) last_res_color = disp_buf_tmp[x]; - else last_res_color = lv_color_mix(map_buf_tmp[x], disp_buf_tmp[x], mask_tmp[x]); +#if LV_COLOR_SCREEN_TRANSP + if(disp->driver.screen_transp) { + last_res_color = color_mix_with_alpha(disp_buf_tmp[x], disp_buf_tmp[x].ch.alpha, map_buf_tmp[x], mask_tmp[x]); + } else +#endif + { + if(mask_tmp[x] > LV_OPA_MAX) last_res_color = map_buf_tmp[x]; + else if(mask_tmp[x] < LV_OPA_MIN) last_res_color = disp_buf_tmp[x]; + else last_res_color = lv_color_mix(map_buf_tmp[x], disp_buf_tmp[x], mask_tmp[x]); + } last_mask = mask_tmp[x]; last_dest_color.full = disp_buf_tmp[x].full; last_map_color.full = map_buf_tmp[x].full; @@ -213,8 +231,6 @@ void lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area, const } } - - } @@ -227,9 +243,14 @@ static void fill_true_color_normal(const lv_area_t * disp_area, lv_color_t * dis const lv_opa_t * mask, lv_draw_mask_res_t mask_res) { + lv_disp_t * disp = lv_refr_get_disp_refreshing(); + /*Get the width of the `disp_area` it will be used to go to the next line*/ lv_coord_t disp_w = lv_area_get_width(disp_area); + /*Get the width of the `draw_area` it will be used to go to the next line of the mask*/ + lv_coord_t draw_area_w = lv_area_get_width(draw_area); + /*Create a temp. disp_buf which always point to current line to draw*/ lv_color_t * disp_buf_tmp = disp_buf + disp_w * draw_area->y1; @@ -239,9 +260,16 @@ static void fill_true_color_normal(const lv_area_t * disp_area, lv_color_t * dis /*Simple fill (maybe with opacity), no masking*/ if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) { if(opa > LV_OPA_MAX) { - lv_coord_t draw_area_w = lv_area_get_width(draw_area); lv_color_t * disp_buf_tmp_ori = disp_buf_tmp; +#if LV_USE_GPU + lv_disp_t * disp = lv_refr_get_disp_refreshing(); + if(disp->driver.gpu_fill_cb && draw_area_w > GPU_WIDTH_LIMIT) { + disp->driver.gpu_fill_cb(&disp->driver, disp_buf, disp_w, draw_area, color); + return; + } +#endif + /*Fill the first line. Use `memcpy` because it's faster then simple value assignment*/ /*Set the first pixels manually*/ lv_coord_t direct_fill_end = LV_MATH_MIN(draw_area->x2, draw_area->x1 + FILL_DIRECT_LEN + (draw_area_w & FILL_DIRECT_MASK) - 1); @@ -261,13 +289,34 @@ static void fill_true_color_normal(const lv_area_t * disp_area, lv_color_t * dis } } else { + +#if LV_USE_GPU + if(disp->driver.gpu_blend_cb && draw_area_w > GPU_WIDTH_LIMIT) { + static lv_color_t blend_buf[LV_HOR_RES_MAX]; + for(x = 0; x < draw_area_w ; x++) blend_buf[x].full = color.full; + + for(y = draw_area->y1; y <= draw_area->y2; y++) { + disp->driver.gpu_blend_cb(&disp->driver, &disp_buf_tmp[draw_area->x1], blend_buf, draw_area_w, opa); + disp_buf_tmp += disp_w; + } + return; + } +#endif lv_color_t last_dest_color = LV_COLOR_BLACK; lv_color_t last_res_color = lv_color_mix(color, last_dest_color, opa); for(y = draw_area->y1; y <= draw_area->y2; y++) { for(x = draw_area->x1; x <= draw_area->x2; x++) { if(last_dest_color.full != disp_buf_tmp[x].full) { last_dest_color = disp_buf_tmp[x]; - last_res_color = lv_color_mix(color, disp_buf_tmp[x], opa); + +#if LV_COLOR_SCREEN_TRANSP + if(disp->driver.screen_transp) { + last_res_color = color_mix_with_alpha(disp_buf_tmp[x], disp_buf_tmp[x].ch.alpha, color, opa); + } else +#endif + { + last_res_color = lv_color_mix(color, disp_buf_tmp[x], opa); + } } disp_buf_tmp[x] = last_res_color; } @@ -277,9 +326,6 @@ static void fill_true_color_normal(const lv_area_t * disp_area, lv_color_t * dis } /*Masked*/ else { - /*Get the width of the `draw_area` it will be used to go to the next line of the mask*/ - lv_coord_t draw_area_w = lv_area_get_width(draw_area); - /* The mask is relative to the clipped area. * In the cycles below mask will be indexed from `draw_area.x1` * but it corresponds to zero index. So prepare `mask_tmp` accordingly. */ @@ -298,10 +344,17 @@ static void fill_true_color_normal(const lv_area_t * disp_area, lv_color_t * dis for(x = draw_area->x1; x <= draw_area->x2; x++) { if(mask_tmp[x] == 0) continue; if(mask_tmp[x] != last_mask || last_dest_color.full != disp_buf_tmp[x].full) { - if(mask_tmp[x] > LV_OPA_MAX) last_res_color = color; - else if(mask_tmp[x] < LV_OPA_MIN) last_res_color = disp_buf_tmp[x]; - else if(disp_buf_tmp[x].full == color.full) last_res_color = disp_buf_tmp[x]; - else last_res_color = lv_color_mix(color, disp_buf_tmp[x], mask_tmp[x]); +#if LV_COLOR_SCREEN_TRANSP + if(disp->driver.screen_transp) { + last_res_color = color_mix_with_alpha(disp_buf_tmp[x], disp_buf_tmp[x].ch.alpha, color, mask_tmp[x]); + } else +#endif + { + if(mask_tmp[x] > LV_OPA_MAX) last_res_color = color; + else if(mask_tmp[x] < LV_OPA_MIN) last_res_color = disp_buf_tmp[x]; + else if(disp_buf_tmp[x].full == color.full) last_res_color = disp_buf_tmp[x]; + else last_res_color = lv_color_mix(color, disp_buf_tmp[x], mask_tmp[x]); + } last_mask = mask_tmp[x]; last_dest_color.full = disp_buf_tmp[x].full; } @@ -318,11 +371,17 @@ static void fill_true_color_normal(const lv_area_t * disp_area, lv_color_t * dis if(mask_tmp[x] == 0) continue; if(mask_tmp[x] != last_mask || last_dest_color.full != disp_buf_tmp[x].full) { lv_opa_t opa_tmp = (uint16_t)((uint16_t)mask_tmp[x] * opa) >> 8; - - if(opa_tmp > LV_OPA_MAX) last_res_color = lv_color_mix(color, disp_buf_tmp[x], mask_tmp[x]); - else if(opa_tmp < LV_OPA_MIN) last_res_color = disp_buf_tmp[x]; - else if(disp_buf_tmp[x].full == color.full) last_res_color = disp_buf_tmp[x]; - else last_res_color = lv_color_mix(color, disp_buf_tmp[x],opa_tmp); +#if LV_COLOR_SCREEN_TRANSP + if(disp->driver.screen_transp) { + last_res_color = color_mix_with_alpha(disp_buf_tmp[x], disp_buf_tmp[x].ch.alpha, color, opa_tmp); + } else +#endif + { + if(opa_tmp > LV_OPA_MAX) last_res_color = lv_color_mix(color, disp_buf_tmp[x], mask_tmp[x]); + else if(opa_tmp < LV_OPA_MIN) last_res_color = disp_buf_tmp[x]; + else if(disp_buf_tmp[x].full == color.full) last_res_color = disp_buf_tmp[x]; + else last_res_color = lv_color_mix(color, disp_buf_tmp[x],opa_tmp); + } last_mask = mask_tmp[x]; last_dest_color.full = disp_buf_tmp[x].full; } @@ -413,7 +472,7 @@ static void fill_true_color_blended(const lv_area_t * disp_area, lv_color_t * di } } } -#if 0 + /** * Mix two colors. Both color can have alpha value. It requires ARGB888 colors. * @param bg_color background color @@ -466,7 +525,6 @@ static inline lv_color_t color_mix_with_alpha(lv_color_t bg_color, lv_opa_t bg_o return c; } } -#endif static inline lv_color_t color_blend_true_color_additive(lv_color_t fg, lv_color_t bg, lv_opa_t opa) { diff --git a/src/lv_draw/lv_draw_img.c b/src/lv_draw/lv_draw_img.c index 59d155850..35469869b 100644 --- a/src/lv_draw/lv_draw_img.c +++ b/src/lv_draw/lv_draw_img.c @@ -615,13 +615,13 @@ static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area, } lv_draw_mask_res_t mask_res; + mask_res = (alpha_byte || chroma_key) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER; lv_coord_t x; lv_coord_t y; for(y = 0; y < lv_area_get_height(&draw_area); y++) { map_px = map_buf_tmp; px_i_start = px_i; - mask_res = (alpha_byte || chroma_key) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER; for(x = 0; x < lv_area_get_width(&draw_area); x++, map_px += px_size_byte, px_i++) { if(alpha_byte) { lv_opa_t px_opa = map_px[LV_IMG_PX_SIZE_ALPHA_BYTE - 1]; @@ -636,7 +636,7 @@ static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area, #elif LV_COLOR_DEPTH == 16 c.full = map_px[0] + (map_px[1] << 8); #elif LV_COLOR_DEPTH == 32 - c.full = map_px[0] + (map_px[1] << 8) + (map_px[2] << 16); + c.full = *((uint32_t*)map_px); #endif if (chroma_key) { @@ -674,6 +674,7 @@ static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area, blend_area.y2 = blend_area.y1; px_i = 0; + mask_res = (alpha_byte || chroma_key) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER; /*Prepare the `mask_buf`if there are other masks*/ if(other_mask_cnt) { diff --git a/src/lv_draw/lv_draw_rect.c b/src/lv_draw/lv_draw_rect.c index 70e525867..4bed1fd38 100644 --- a/src/lv_draw/lv_draw_rect.c +++ b/src/lv_draw/lv_draw_rect.c @@ -54,8 +54,6 @@ void lv_draw_rect(const lv_area_t * coords, const lv_area_t * clip, const lv_sty draw_bg(coords, clip, style, opa_scale); draw_shadow(coords, clip, style, opa_scale); - - } /********************** diff --git a/src/lv_objx/lv_objmask.c b/src/lv_objx/lv_objmask.c index b44be6d20..c32c9bdf9 100644 --- a/src/lv_objx/lv_objmask.c +++ b/src/lv_objx/lv_objmask.c @@ -58,7 +58,7 @@ lv_obj_t * lv_objmask_create(lv_obj_t * par, const lv_obj_t * copy) lv_mem_assert(ext); if(ext == NULL) return NULL; if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_objmask); - if(ancestor_design == NULL) ancestor_design= lv_obj_get_design_cb(new_objmask); + if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_objmask); /*Initialize the allocated 'ext' */ lv_ll_init(&ext->mask_ll, sizeof(lv_objmask_mask_t)); @@ -69,7 +69,7 @@ lv_obj_t * lv_objmask_create(lv_obj_t * par, const lv_obj_t * copy) /*Init the new object mask object mask*/ if(copy == NULL) { - lv_objmask_set_style(new_objmask, LV_OBJMASK_STYLE_BG, &lv_style_plain_color); + lv_objmask_set_style(new_objmask, LV_OBJMASK_STYLE_BG, &lv_style_plain); } /*Copy an existing object mask*/ @@ -158,7 +158,7 @@ static lv_design_res_t lv_objmask_design(lv_obj_t * objmask, const lv_area_t * c lv_draw_mask_remove_custom(objmask); } - return true; + return LV_DESIGN_RES_OK; } /** diff --git a/src/lv_objx/lv_page.c b/src/lv_objx/lv_page.c index d41f66325..a6b57333a 100644 --- a/src/lv_objx/lv_page.c +++ b/src/lv_objx/lv_page.c @@ -108,7 +108,7 @@ lv_obj_t * lv_page_create(lv_obj_t * par, const lv_obj_t * copy) /*Init the new page object*/ if(copy == NULL) { - ext->bg.masked = 1; + ext->bg.masked = 0; ext->scrl = lv_cont_create(new_page, NULL); lv_obj_set_signal_cb(ext->scrl, lv_page_scrollable_signal); lv_obj_set_design_cb(ext->scrl, lv_scrl_design);