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