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