1 /**
2 * @file lv_vglite_utils.c
3 *
4 */
5
6 /**
7 * Copyright 2022-2024 NXP
8 *
9 * SPDX-License-Identifier: MIT
10 */
11
12 /*********************
13 * INCLUDES
14 *********************/
15
16 #include "lv_vglite_utils.h"
17
18 #if LV_USE_DRAW_VGLITE
19 #include "lv_vglite_buf.h"
20
21 #include "../../../core/lv_refr.h"
22
23 /*********************
24 * DEFINES
25 *********************/
26
27 /**********************
28 * TYPEDEFS
29 **********************/
30
31 /**********************
32 * STATIC PROTOTYPES
33 **********************/
34
35 /**********************
36 * STATIC VARIABLES
37 **********************/
38
39 #if LV_USE_VGLITE_DRAW_ASYNC
40 static volatile bool _cmd_buf_flushed = false;
41 #endif
42
43 /**********************
44 * MACROS
45 **********************/
46
47 /**********************
48 * GLOBAL FUNCTIONS
49 **********************/
50
vglite_error_to_string(vg_lite_error_t error)51 const char * vglite_error_to_string(vg_lite_error_t error)
52 {
53 switch(error) {
54 ENUM_TO_STRING(VG_LITE_SUCCESS);
55 ENUM_TO_STRING(VG_LITE_INVALID_ARGUMENT);
56 ENUM_TO_STRING(VG_LITE_OUT_OF_MEMORY);
57 ENUM_TO_STRING(VG_LITE_NO_CONTEXT);
58 ENUM_TO_STRING(VG_LITE_TIMEOUT);
59 ENUM_TO_STRING(VG_LITE_OUT_OF_RESOURCES);
60 ENUM_TO_STRING(VG_LITE_GENERIC_IO);
61 ENUM_TO_STRING(VG_LITE_NOT_SUPPORT);
62 ENUM_TO_STRING(VG_LITE_ALREADY_EXISTS);
63 ENUM_TO_STRING(VG_LITE_NOT_ALIGNED);
64 ENUM_TO_STRING(VG_LITE_FLEXA_TIME_OUT);
65 ENUM_TO_STRING(VG_LITE_FLEXA_HANDSHAKE_FAIL);
66 default:
67 break;
68 }
69
70 return "VG_LITE_UKNOWN_ERROR";
71 }
72
73 #if LV_USE_VGLITE_DRAW_ASYNC
vglite_cmd_buf_is_flushed(void)74 bool vglite_cmd_buf_is_flushed(void)
75 {
76 return _cmd_buf_flushed;
77 }
78 #endif
79
vglite_run(void)80 void vglite_run(void)
81 {
82 #if LV_USE_VGLITE_DRAW_ASYNC
83 vg_lite_uint32_t gpu_idle = 0;
84
85 VGLITE_CHECK_ERROR(vg_lite_get_parameter(VG_LITE_GPU_IDLE_STATE, 1, (vg_lite_pointer)&gpu_idle));
86
87 if(!gpu_idle) {
88 _cmd_buf_flushed = false;
89
90 return;
91 }
92 #endif
93
94 /*
95 * If LV_USE_VGLITE_DRAW_ASYNC is enabled, simply flush the command buffer and the
96 * vglite draw thread will signal asynchronous the dispatcher for completed tasks.
97 * Without draw async, process the tasks and signal them as complete one by one.
98 */
99 #if LV_USE_VGLITE_DRAW_ASYNC
100 VGLITE_CHECK_ERROR(vg_lite_flush());
101 _cmd_buf_flushed = true;
102 #else
103 VGLITE_CHECK_ERROR(vg_lite_finish());
104 #endif
105 }
106
107 #if LV_USE_VGLITE_DRAW_ASYNC
vglite_wait_for_finish(void)108 void vglite_wait_for_finish(void)
109 {
110 VGLITE_CHECK_ERROR(vg_lite_finish());
111 }
112 #endif
113
vglite_get_color(lv_color32_t lv_col32,bool gradient)114 vg_lite_color_t vglite_get_color(lv_color32_t lv_col32, bool gradient)
115 {
116 vg_lite_color_t vg_col32;
117
118 /* Pre-multiply alpha */
119 lv_col32.red = LV_UDIV255(lv_col32.red * lv_col32.alpha);
120 lv_col32.green = LV_UDIV255(lv_col32.green * lv_col32.alpha);
121 lv_col32.blue = LV_UDIV255(lv_col32.blue * lv_col32.alpha);
122
123 if(!gradient)
124 /* The color is in ABGR8888 format with red channel in the lower 8 bits. */
125 vg_col32 = ((vg_lite_color_t)lv_col32.alpha << 24) | ((vg_lite_color_t)lv_col32.blue << 16) |
126 ((vg_lite_color_t)lv_col32.green << 8) | (vg_lite_color_t)lv_col32.red;
127 else
128 /* The gradient color is in ARGB8888 format with blue channel in the lower 8 bits. */
129 vg_col32 = ((vg_lite_color_t)lv_col32.alpha << 24) | ((vg_lite_color_t)lv_col32.red << 16) |
130 ((vg_lite_color_t)lv_col32.green << 8) | (vg_lite_color_t)lv_col32.blue;
131
132 return vg_col32;
133 }
134
vglite_get_blend_mode(lv_blend_mode_t lv_blend_mode)135 vg_lite_blend_t vglite_get_blend_mode(lv_blend_mode_t lv_blend_mode)
136 {
137 vg_lite_blend_t vg_blend_mode = VG_LITE_BLEND_NONE;
138
139 if(vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT)) {
140 switch(lv_blend_mode) {
141 case LV_BLEND_MODE_NORMAL:
142 vg_blend_mode = VG_LITE_BLEND_NORMAL_LVGL;
143 break;
144 case LV_BLEND_MODE_ADDITIVE:
145 vg_blend_mode = VG_LITE_BLEND_ADDITIVE_LVGL;
146 break;
147 case LV_BLEND_MODE_SUBTRACTIVE:
148 vg_blend_mode = VG_LITE_BLEND_SUBTRACT_LVGL;
149 break;
150 case LV_BLEND_MODE_MULTIPLY:
151 vg_blend_mode = VG_LITE_BLEND_MULTIPLY_LVGL;
152 break;
153 default:
154 VGLITE_ASSERT_MSG(false, "Unsupported blend mode.");
155 break;
156 }
157 }
158 else {
159 switch(lv_blend_mode) {
160 case LV_BLEND_MODE_NORMAL:
161 vg_blend_mode = VG_LITE_BLEND_SRC_OVER;
162 break;
163 case LV_BLEND_MODE_ADDITIVE:
164 vg_blend_mode = VG_LITE_BLEND_ADDITIVE;
165 break;
166 case LV_BLEND_MODE_SUBTRACTIVE:
167 vg_blend_mode = VG_LITE_BLEND_SUBTRACT;
168 break;
169 case LV_BLEND_MODE_MULTIPLY:
170 vg_blend_mode = VG_LITE_BLEND_MULTIPLY;
171 break;
172 default:
173 VGLITE_ASSERT_MSG(false, "Unsupported blend mode.");
174 break;
175 }
176 }
177
178 return vg_blend_mode;
179 }
180
vglite_get_buf_format(lv_color_format_t cf)181 vg_lite_buffer_format_t vglite_get_buf_format(lv_color_format_t cf)
182 {
183 vg_lite_buffer_format_t vg_buffer_format = VG_LITE_BGR565;
184
185 switch(cf) {
186 case LV_COLOR_FORMAT_L8:
187 vg_buffer_format = VG_LITE_L8;
188 break;
189 case LV_COLOR_FORMAT_A8:
190 vg_buffer_format = VG_LITE_A8;
191 break;
192 case LV_COLOR_FORMAT_I1:
193 vg_buffer_format = VG_LITE_INDEX_1;
194 break;
195 case LV_COLOR_FORMAT_I2:
196 vg_buffer_format = VG_LITE_INDEX_2;
197 break;
198 case LV_COLOR_FORMAT_I4:
199 vg_buffer_format = VG_LITE_INDEX_4;
200 break;
201 case LV_COLOR_FORMAT_I8:
202 vg_buffer_format = VG_LITE_INDEX_8;
203 break;
204 case LV_COLOR_FORMAT_RGB565:
205 vg_buffer_format = VG_LITE_BGR565;
206 break;
207 case LV_COLOR_FORMAT_RGB565A8:
208 vg_buffer_format = VG_LITE_ABGR8565;
209 break;
210 case LV_COLOR_FORMAT_RGB888:
211 vg_buffer_format = VG_LITE_BGR888;
212 break;
213 case LV_COLOR_FORMAT_ARGB8888:
214 vg_buffer_format = VG_LITE_BGRA8888;
215 break;
216 case LV_COLOR_FORMAT_XRGB8888:
217 vg_buffer_format = VG_LITE_BGRX8888;
218 break;
219
220 default:
221 VGLITE_ASSERT_MSG(false, "Unsupported color format.");
222 break;
223 }
224
225 return vg_buffer_format;
226 }
227
vglite_get_stride_alignment(lv_color_format_t cf)228 uint8_t vglite_get_stride_alignment(lv_color_format_t cf)
229 {
230 uint8_t align_bytes = LV_COLOR_DEPTH / 8 * 16; /*16 pixels*/
231
232 switch(cf) {
233 case LV_COLOR_FORMAT_I1:
234 case LV_COLOR_FORMAT_I2:
235 case LV_COLOR_FORMAT_I4:
236 align_bytes = 8;
237 break;
238 case LV_COLOR_FORMAT_I8:
239 case LV_COLOR_FORMAT_A8:
240 case LV_COLOR_FORMAT_L8:
241 align_bytes = 16;
242 break;
243 case LV_COLOR_FORMAT_RGB565:
244 align_bytes = 32;
245 break;
246 case LV_COLOR_FORMAT_RGB565A8:
247 case LV_COLOR_FORMAT_RGB888:
248 align_bytes = 48;
249 break;
250 case LV_COLOR_FORMAT_ARGB8888:
251 case LV_COLOR_FORMAT_XRGB8888:
252 align_bytes = 64;
253 break;
254
255 default:
256 VGLITE_ASSERT_MSG(false, "Unsupported buffer format.");
257 break;
258 }
259
260 return align_bytes;
261 }
262
vglite_src_buf_aligned(const void * buf,uint32_t stride,lv_color_format_t cf)263 bool vglite_src_buf_aligned(const void * buf, uint32_t stride, lv_color_format_t cf)
264 {
265 /* No alignment requirement for destination buffer when using mode VG_LITE_LINEAR */
266
267 /* Test for pointer alignment */
268 if((uintptr_t)buf % LV_ATTRIBUTE_MEM_ALIGN_SIZE)
269 return false;
270
271 /* Test for stride alignment */
272 if(stride == 0 || stride % vglite_get_stride_alignment(cf))
273 return false;
274
275 return true;
276 }
277
278 /**********************
279 * STATIC FUNCTIONS
280 **********************/
281
282 #endif /*LV_USE_DRAW_VGLITE*/
283