1 /**
2 * @file lv_draw_sw_blend.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9 #include "../../../misc/lv_area_private.h"
10 #include "lv_draw_sw_blend_private.h"
11 #include "../../lv_draw_private.h"
12 #include "../lv_draw_sw.h"
13 #if LV_DRAW_SW_SUPPORT_L8
14 #include "lv_draw_sw_blend_to_l8.h"
15 #endif
16 #if LV_DRAW_SW_SUPPORT_AL88
17 #include "lv_draw_sw_blend_to_al88.h"
18 #endif
19 #if LV_DRAW_SW_SUPPORT_RGB565
20 #include "lv_draw_sw_blend_to_rgb565.h"
21 #endif
22 #if LV_DRAW_SW_SUPPORT_ARGB8888
23 #include "lv_draw_sw_blend_to_argb8888.h"
24 #endif
25 #if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888
26 #include "lv_draw_sw_blend_to_rgb888.h"
27 #endif
28 #if LV_DRAW_SW_SUPPORT_I1
29 #include "lv_draw_sw_blend_to_i1.h"
30 #endif
31 #if LV_USE_DRAW_SW
32
33 /*********************
34 * DEFINES
35 *********************/
36
37 /**********************
38 * TYPEDEFS
39 **********************/
40
41 /**********************
42 * STATIC PROTOTYPES
43 **********************/
44 /**********************
45 * STATIC VARIABLES
46 **********************/
47
48 /**********************
49 * MACROS
50 **********************/
51
52 /**********************
53 * GLOBAL FUNCTIONS
54 **********************/
55
lv_draw_sw_blend(lv_draw_unit_t * draw_unit,const lv_draw_sw_blend_dsc_t * blend_dsc)56 void lv_draw_sw_blend(lv_draw_unit_t * draw_unit, const lv_draw_sw_blend_dsc_t * blend_dsc)
57 {
58 /*Do not draw transparent things*/
59 if(blend_dsc->opa <= LV_OPA_MIN) return;
60 if(blend_dsc->mask_buf && blend_dsc->mask_res == LV_DRAW_SW_MASK_RES_TRANSP) return;
61
62 lv_area_t blend_area;
63 if(!lv_area_intersect(&blend_area, blend_dsc->blend_area, draw_unit->clip_area)) return;
64
65 LV_PROFILER_DRAW_BEGIN;
66 lv_layer_t * layer = draw_unit->target_layer;
67 uint32_t layer_stride_byte = layer->draw_buf->header.stride;
68
69 if(blend_dsc->src_buf == NULL) {
70 lv_draw_sw_blend_fill_dsc_t fill_dsc;
71 fill_dsc.dest_w = lv_area_get_width(&blend_area);
72 fill_dsc.dest_h = lv_area_get_height(&blend_area);
73 fill_dsc.dest_stride = layer_stride_byte;
74 fill_dsc.opa = blend_dsc->opa;
75 fill_dsc.color = blend_dsc->color;
76 fill_dsc.mask_stride = 0;
77
78 if(blend_dsc->mask_buf == NULL) fill_dsc.mask_buf = NULL;
79 else if(blend_dsc->mask_res == LV_DRAW_SW_MASK_RES_FULL_COVER) fill_dsc.mask_buf = NULL;
80 else fill_dsc.mask_buf = blend_dsc->mask_buf;
81
82
83 fill_dsc.relative_area = blend_area;
84 lv_area_move(&fill_dsc.relative_area, -layer->buf_area.x1, -layer->buf_area.y1);
85 fill_dsc.dest_buf = lv_draw_layer_go_to_xy(layer, blend_area.x1 - layer->buf_area.x1,
86 blend_area.y1 - layer->buf_area.y1);
87 if(fill_dsc.mask_buf) {
88 fill_dsc.mask_stride = blend_dsc->mask_stride == 0 ? lv_area_get_width(blend_dsc->mask_area) : blend_dsc->mask_stride;
89 fill_dsc.mask_buf += fill_dsc.mask_stride * (blend_area.y1 - blend_dsc->mask_area->y1) +
90 (blend_area.x1 - blend_dsc->mask_area->x1);
91 }
92
93 switch(layer->color_format) {
94 #if LV_DRAW_SW_SUPPORT_RGB565
95 case LV_COLOR_FORMAT_RGB565:
96 lv_draw_sw_blend_color_to_rgb565(&fill_dsc);
97 break;
98 #endif
99 #if LV_DRAW_SW_SUPPORT_ARGB8888
100 case LV_COLOR_FORMAT_ARGB8888:
101 lv_draw_sw_blend_color_to_argb8888(&fill_dsc);
102 break;
103 #endif
104 #if LV_DRAW_SW_SUPPORT_RGB888
105 case LV_COLOR_FORMAT_RGB888:
106 lv_draw_sw_blend_color_to_rgb888(&fill_dsc, 3);
107 break;
108 #endif
109 #if LV_DRAW_SW_SUPPORT_XRGB8888
110 case LV_COLOR_FORMAT_XRGB8888:
111 lv_draw_sw_blend_color_to_rgb888(&fill_dsc, 4);
112 break;
113 #endif
114 #if LV_DRAW_SW_SUPPORT_L8
115 case LV_COLOR_FORMAT_L8:
116 lv_draw_sw_blend_color_to_l8(&fill_dsc);
117 break;
118 #endif
119 #if LV_DRAW_SW_SUPPORT_AL88
120 case LV_COLOR_FORMAT_AL88:
121 lv_draw_sw_blend_color_to_al88(&fill_dsc);
122 break;
123 #endif
124 #if LV_DRAW_SW_SUPPORT_I1
125 case LV_COLOR_FORMAT_I1:
126 lv_draw_sw_blend_color_to_i1(&fill_dsc);
127 break;
128 #endif
129 default:
130 break;
131 }
132 }
133 else {
134 if(!lv_area_intersect(&blend_area, &blend_area, blend_dsc->src_area)) {
135 LV_PROFILER_DRAW_END;
136 return;
137 }
138
139 if(blend_dsc->mask_area && !lv_area_intersect(&blend_area, &blend_area, blend_dsc->mask_area)) {
140 LV_PROFILER_DRAW_END;
141 return;
142 }
143
144 lv_draw_sw_blend_image_dsc_t image_dsc;
145 image_dsc.dest_w = lv_area_get_width(&blend_area);
146 image_dsc.dest_h = lv_area_get_height(&blend_area);
147 image_dsc.dest_stride = layer_stride_byte;
148
149 image_dsc.opa = blend_dsc->opa;
150 image_dsc.blend_mode = blend_dsc->blend_mode;
151 image_dsc.src_stride = blend_dsc->src_stride;
152 image_dsc.src_color_format = blend_dsc->src_color_format;
153
154 const uint8_t * src_buf = blend_dsc->src_buf;
155 uint32_t src_px_size = lv_color_format_get_bpp(blend_dsc->src_color_format);
156 src_buf += image_dsc.src_stride * (blend_area.y1 - blend_dsc->src_area->y1);
157 src_buf += ((blend_area.x1 - blend_dsc->src_area->x1) * src_px_size) >> 3;
158 image_dsc.src_buf = src_buf;
159 image_dsc.mask_stride = 0;
160
161 if(blend_dsc->mask_buf == NULL) image_dsc.mask_buf = NULL;
162 else if(blend_dsc->mask_res == LV_DRAW_SW_MASK_RES_FULL_COVER) image_dsc.mask_buf = NULL;
163 else image_dsc.mask_buf = blend_dsc->mask_buf;
164
165 if(image_dsc.mask_buf) {
166 LV_ASSERT_NULL(blend_dsc->mask_area);
167 image_dsc.mask_buf = blend_dsc->mask_buf;
168 image_dsc.mask_stride = blend_dsc->mask_stride ? blend_dsc->mask_stride : lv_area_get_width(blend_dsc->mask_area);
169 image_dsc.mask_buf += image_dsc.mask_stride * (blend_area.y1 - blend_dsc->mask_area->y1) +
170 (blend_area.x1 - blend_dsc->mask_area->x1);
171 }
172
173 image_dsc.relative_area = blend_area;
174 lv_area_move(&image_dsc.relative_area, -layer->buf_area.x1, -layer->buf_area.y1);
175
176 image_dsc.src_area = *blend_dsc->src_area;
177 lv_area_move(&image_dsc.src_area, -layer->buf_area.x1, -layer->buf_area.y1);
178
179 image_dsc.dest_buf = lv_draw_layer_go_to_xy(layer, blend_area.x1 - layer->buf_area.x1,
180 blend_area.y1 - layer->buf_area.y1);
181
182 switch(layer->color_format) {
183 #if LV_DRAW_SW_SUPPORT_RGB565
184 case LV_COLOR_FORMAT_RGB565:
185 case LV_COLOR_FORMAT_RGB565A8:
186 lv_draw_sw_blend_image_to_rgb565(&image_dsc);
187 break;
188 #endif
189 #if LV_DRAW_SW_SUPPORT_ARGB8888
190 case LV_COLOR_FORMAT_ARGB8888:
191 lv_draw_sw_blend_image_to_argb8888(&image_dsc);
192 break;
193 #endif
194 #if LV_DRAW_SW_SUPPORT_RGB888
195 case LV_COLOR_FORMAT_RGB888:
196 lv_draw_sw_blend_image_to_rgb888(&image_dsc, 3);
197 break;
198 #endif
199 #if LV_DRAW_SW_SUPPORT_XRGB8888
200 case LV_COLOR_FORMAT_XRGB8888:
201 lv_draw_sw_blend_image_to_rgb888(&image_dsc, 4);
202 break;
203 #endif
204 #if LV_DRAW_SW_SUPPORT_L8
205 case LV_COLOR_FORMAT_L8:
206 lv_draw_sw_blend_image_to_l8(&image_dsc);
207 break;
208 #endif
209 #if LV_DRAW_SW_SUPPORT_AL88
210 case LV_COLOR_FORMAT_AL88:
211 lv_draw_sw_blend_image_to_al88(&image_dsc);
212 break;
213 #endif
214 #if LV_DRAW_SW_SUPPORT_I1
215 case LV_COLOR_FORMAT_I1:
216 lv_draw_sw_blend_image_to_i1(&image_dsc);
217 break;
218 #endif
219 default:
220 break;
221 }
222 }
223 LV_PROFILER_DRAW_END;
224 }
225
226 /**********************
227 * STATIC FUNCTIONS
228 **********************/
229
230 #endif
231