1 /**
2 * @file lv_draw_sw_layer.h
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9 #include "lv_draw_sw.h"
10 #include "../../hal/lv_hal_disp.h"
11 #include "../../misc/lv_area.h"
12 #include "../../core/lv_refr.h"
13
14 /*********************
15 * DEFINES
16 *********************/
17
18 /**********************
19 * TYPEDEFS
20 **********************/
21
22 /**********************
23 * STATIC PROTOTYPES
24 **********************/
25
26 /**********************
27 * STATIC VARIABLES
28 **********************/
29
30 /**********************
31 * GLOBAL VARIABLES
32 **********************/
33
34 /**********************
35 * MACROS
36 **********************/
37
38 /**********************
39 * GLOBAL FUNCTIONS
40 **********************/
41
lv_draw_sw_layer_create(struct _lv_draw_ctx_t * draw_ctx,lv_draw_layer_ctx_t * layer_ctx,lv_draw_layer_flags_t flags)42 struct _lv_draw_layer_ctx_t * lv_draw_sw_layer_create(struct _lv_draw_ctx_t * draw_ctx, lv_draw_layer_ctx_t * layer_ctx,
43 lv_draw_layer_flags_t flags)
44 {
45 if(LV_COLOR_SCREEN_TRANSP == 0 && (flags & LV_DRAW_LAYER_FLAG_HAS_ALPHA)) {
46 LV_LOG_WARN("Rendering this widget needs LV_COLOR_SCREEN_TRANSP 1");
47 return NULL;
48 }
49
50 lv_draw_sw_layer_ctx_t * layer_sw_ctx = (lv_draw_sw_layer_ctx_t *) layer_ctx;
51 uint32_t px_size = flags & LV_DRAW_LAYER_FLAG_HAS_ALPHA ? LV_IMG_PX_SIZE_ALPHA_BYTE : sizeof(lv_color_t);
52 if(flags & LV_DRAW_LAYER_FLAG_CAN_SUBDIVIDE) {
53 layer_sw_ctx->buf_size_bytes = LV_LAYER_SIMPLE_BUF_SIZE;
54 uint32_t full_size = lv_area_get_size(&layer_sw_ctx->base_draw.area_full) * px_size;
55 if(layer_sw_ctx->buf_size_bytes > full_size) layer_sw_ctx->buf_size_bytes = full_size;
56 layer_sw_ctx->base_draw.buf = lv_mem_alloc(layer_sw_ctx->buf_size_bytes);
57 if(layer_sw_ctx->base_draw.buf == NULL) {
58 LV_LOG_WARN("Cannot allocate %"LV_PRIu32" bytes for layer buffer. Allocating %"LV_PRIu32" bytes instead. (Reduced performance)",
59 (uint32_t)layer_sw_ctx->buf_size_bytes, (uint32_t)LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE * px_size);
60 layer_sw_ctx->buf_size_bytes = LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE;
61 layer_sw_ctx->base_draw.buf = lv_mem_alloc(layer_sw_ctx->buf_size_bytes);
62 if(layer_sw_ctx->base_draw.buf == NULL) {
63 return NULL;
64 }
65 }
66 layer_sw_ctx->base_draw.area_act = layer_sw_ctx->base_draw.area_full;
67 layer_sw_ctx->base_draw.area_act.y2 = layer_sw_ctx->base_draw.area_full.y1;
68 lv_coord_t w = lv_area_get_width(&layer_sw_ctx->base_draw.area_act);
69 layer_sw_ctx->base_draw.max_row_with_alpha = layer_sw_ctx->buf_size_bytes / w / LV_IMG_PX_SIZE_ALPHA_BYTE;
70 layer_sw_ctx->base_draw.max_row_with_no_alpha = layer_sw_ctx->buf_size_bytes / w / sizeof(lv_color_t);
71 }
72 else {
73 layer_sw_ctx->base_draw.area_act = layer_sw_ctx->base_draw.area_full;
74 layer_sw_ctx->buf_size_bytes = lv_area_get_size(&layer_sw_ctx->base_draw.area_full) * px_size;
75 layer_sw_ctx->base_draw.buf = lv_mem_alloc(layer_sw_ctx->buf_size_bytes);
76 lv_memset_00(layer_sw_ctx->base_draw.buf, layer_sw_ctx->buf_size_bytes);
77 layer_sw_ctx->has_alpha = flags & LV_DRAW_LAYER_FLAG_HAS_ALPHA ? 1 : 0;
78 if(layer_sw_ctx->base_draw.buf == NULL) {
79 return NULL;
80 }
81
82 draw_ctx->buf = layer_sw_ctx->base_draw.buf;
83 draw_ctx->buf_area = &layer_sw_ctx->base_draw.area_act;
84 draw_ctx->clip_area = &layer_sw_ctx->base_draw.area_act;
85
86 lv_disp_t * disp_refr = _lv_refr_get_disp_refreshing();
87 disp_refr->driver->screen_transp = flags & LV_DRAW_LAYER_FLAG_HAS_ALPHA ? 1 : 0;
88 }
89
90 return layer_ctx;
91 }
92
lv_draw_sw_layer_adjust(struct _lv_draw_ctx_t * draw_ctx,struct _lv_draw_layer_ctx_t * layer_ctx,lv_draw_layer_flags_t flags)93 void lv_draw_sw_layer_adjust(struct _lv_draw_ctx_t * draw_ctx, struct _lv_draw_layer_ctx_t * layer_ctx,
94 lv_draw_layer_flags_t flags)
95 {
96
97 lv_draw_sw_layer_ctx_t * layer_sw_ctx = (lv_draw_sw_layer_ctx_t *) layer_ctx;
98 lv_disp_t * disp_refr = _lv_refr_get_disp_refreshing();
99 if(flags & LV_DRAW_LAYER_FLAG_HAS_ALPHA) {
100 lv_memset_00(layer_ctx->buf, layer_sw_ctx->buf_size_bytes);
101 layer_sw_ctx->has_alpha = 1;
102 disp_refr->driver->screen_transp = 1;
103 }
104 else {
105 layer_sw_ctx->has_alpha = 0;
106 disp_refr->driver->screen_transp = 0;
107 }
108
109 draw_ctx->buf = layer_ctx->buf;
110 draw_ctx->buf_area = &layer_ctx->area_act;
111 draw_ctx->clip_area = &layer_ctx->area_act;
112 }
113
lv_draw_sw_layer_blend(struct _lv_draw_ctx_t * draw_ctx,struct _lv_draw_layer_ctx_t * layer_ctx,const lv_draw_img_dsc_t * draw_dsc)114 void lv_draw_sw_layer_blend(struct _lv_draw_ctx_t * draw_ctx, struct _lv_draw_layer_ctx_t * layer_ctx,
115 const lv_draw_img_dsc_t * draw_dsc)
116 {
117 lv_draw_sw_layer_ctx_t * layer_sw_ctx = (lv_draw_sw_layer_ctx_t *) layer_ctx;
118
119 lv_img_dsc_t img;
120 img.data = draw_ctx->buf;
121 img.header.always_zero = 0;
122 img.header.w = lv_area_get_width(draw_ctx->buf_area);
123 img.header.h = lv_area_get_height(draw_ctx->buf_area);
124 img.header.cf = layer_sw_ctx->has_alpha ? LV_IMG_CF_TRUE_COLOR_ALPHA : LV_IMG_CF_TRUE_COLOR;
125
126 /*Restore the original draw_ctx*/
127 draw_ctx->buf = layer_ctx->original.buf;
128 draw_ctx->buf_area = layer_ctx->original.buf_area;
129 draw_ctx->clip_area = layer_ctx->original.clip_area;
130 lv_disp_t * disp_refr = _lv_refr_get_disp_refreshing();
131 disp_refr->driver->screen_transp = layer_ctx->original.screen_transp;
132
133 /*Blend the layer*/
134 lv_draw_img(draw_ctx, draw_dsc, &layer_ctx->area_act, &img);
135 lv_draw_wait_for_finish(draw_ctx);
136 lv_img_cache_invalidate_src(&img);
137 }
138
lv_draw_sw_layer_destroy(lv_draw_ctx_t * draw_ctx,lv_draw_layer_ctx_t * layer_ctx)139 void lv_draw_sw_layer_destroy(lv_draw_ctx_t * draw_ctx, lv_draw_layer_ctx_t * layer_ctx)
140 {
141 LV_UNUSED(draw_ctx);
142
143 lv_mem_free(layer_ctx->buf);
144 }
145
146 /**********************
147 * STATIC FUNCTIONS
148 **********************/
149