1 /**
2 * @file vg_lite_utils.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9
10 #include "../lv_image_decoder_private.h"
11 #include "lv_vg_lite_utils.h"
12
13 #if LV_USE_DRAW_VG_LITE
14
15 #include "lv_vg_lite_decoder.h"
16 #include "lv_vg_lite_path.h"
17 #include "lv_vg_lite_pending.h"
18 #include "lv_vg_lite_grad.h"
19 #include "lv_draw_vg_lite_type.h"
20 #include <string.h>
21 #include <math.h>
22
23 /*********************
24 * DEFINES
25 *********************/
26
27 #define ENUM_TO_STRING(e) \
28 case (e): \
29 return #e
30
31 #define VG_LITE_ENUM_TO_STRING(e) \
32 case (VG_LITE_##e): \
33 return #e
34
35 #define VLC_OP_ENUM_TO_STRING(e) \
36 case (VLC_OP_##e): \
37 return #e
38
39 #define FEATURE_ENUM_TO_STRING(e) \
40 case (gcFEATURE_BIT_VG_##e): \
41 return #e
42
43 /**********************
44 * TYPEDEFS
45 **********************/
46
47 /**********************
48 * STATIC PROTOTYPES
49 **********************/
50
51 static void image_dsc_free_cb(void * dsc, void * user_data);
52
53 /**********************
54 * STATIC VARIABLES
55 **********************/
56
57 /**********************
58 * MACROS
59 **********************/
60
61 /**********************
62 * GLOBAL FUNCTIONS
63 **********************/
64
lv_vg_lite_dump_info(void)65 void lv_vg_lite_dump_info(void)
66 {
67 char name[64];
68 vg_lite_uint32_t chip_id;
69 vg_lite_uint32_t chip_rev;
70 vg_lite_uint32_t cid;
71 vg_lite_get_product_info(name, &chip_id, &chip_rev);
72 vg_lite_get_register(0x30, &cid);
73 LV_LOG_USER("Product Info: %s"
74 " | Chip ID: 0x%" LV_PRIx32
75 " | Revision: 0x%" LV_PRIx32
76 " | CID: 0x%" LV_PRIx32,
77 name, (uint32_t)chip_id, (uint32_t)chip_rev, (uint32_t)cid);
78
79 vg_lite_info_t info;
80 vg_lite_get_info(&info);
81 LV_LOG_USER("VGLite API version: 0x%" LV_PRIx32, (uint32_t)info.api_version);
82 LV_LOG_USER("VGLite API header version: 0x%" LV_PRIx32, (uint32_t)info.header_version);
83 LV_LOG_USER("VGLite release version: 0x%" LV_PRIx32, (uint32_t)info.release_version);
84
85 for(int feature = 0; feature < gcFEATURE_COUNT; feature++) {
86 vg_lite_uint32_t ret = vg_lite_query_feature((vg_lite_feature_t)feature);
87 LV_UNUSED(ret);
88 LV_LOG_USER("Feature-%d: %s\t - %s",
89 feature, lv_vg_lite_feature_string((vg_lite_feature_t)feature),
90 ret ? "YES" : "NO");
91 }
92
93 vg_lite_uint32_t mem_size = 0;
94 vg_lite_get_mem_size(&mem_size);
95 LV_LOG_USER("Memory size: %" LV_PRId32 " Bytes", (uint32_t)mem_size);
96 }
97
lv_vg_lite_error_dump_info(vg_lite_error_t error)98 void lv_vg_lite_error_dump_info(vg_lite_error_t error)
99 {
100 LV_LOG_USER("Error code: %d(%s)", (int)error, lv_vg_lite_error_string(error));
101 switch(error) {
102 case VG_LITE_SUCCESS:
103 LV_LOG_USER("No error");
104 break;
105
106 case VG_LITE_OUT_OF_MEMORY:
107 case VG_LITE_OUT_OF_RESOURCES: {
108 vg_lite_uint32_t mem_size = 0;
109 vg_lite_error_t ret = vg_lite_get_mem_size(&mem_size);
110 if(ret != VG_LITE_SUCCESS) {
111 LV_LOG_ERROR("vg_lite_get_mem_size error: %d(%s)",
112 (int)ret, lv_vg_lite_error_string(ret));
113 return;
114 }
115
116 LV_LOG_USER("Memory size: %" LV_PRId32 " Bytes", (uint32_t)mem_size);
117 }
118 break;
119
120 case VG_LITE_TIMEOUT:
121 case VG_LITE_FLEXA_TIME_OUT: {
122 vg_lite_error_t ret = vg_lite_dump_command_buffer();
123 if(ret != VG_LITE_SUCCESS) {
124 LV_LOG_ERROR("vg_lite_dump_command_buffer error: %d(%s)",
125 (int)ret, lv_vg_lite_error_string(ret));
126 return;
127 }
128
129 LV_LOG_USER("Command buffer finished");
130 }
131 break;
132
133 default:
134 lv_vg_lite_dump_info();
135 break;
136 }
137 }
138
lv_vg_lite_error_string(vg_lite_error_t error)139 const char * lv_vg_lite_error_string(vg_lite_error_t error)
140 {
141 switch(error) {
142 VG_LITE_ENUM_TO_STRING(SUCCESS);
143 VG_LITE_ENUM_TO_STRING(INVALID_ARGUMENT);
144 VG_LITE_ENUM_TO_STRING(OUT_OF_MEMORY);
145 VG_LITE_ENUM_TO_STRING(NO_CONTEXT);
146 VG_LITE_ENUM_TO_STRING(TIMEOUT);
147 VG_LITE_ENUM_TO_STRING(OUT_OF_RESOURCES);
148 VG_LITE_ENUM_TO_STRING(GENERIC_IO);
149 VG_LITE_ENUM_TO_STRING(NOT_SUPPORT);
150 VG_LITE_ENUM_TO_STRING(ALREADY_EXISTS);
151 VG_LITE_ENUM_TO_STRING(NOT_ALIGNED);
152 VG_LITE_ENUM_TO_STRING(FLEXA_TIME_OUT);
153 VG_LITE_ENUM_TO_STRING(FLEXA_HANDSHAKE_FAIL);
154 default:
155 break;
156 }
157 return "UNKNOW_ERROR";
158 }
159
lv_vg_lite_feature_string(vg_lite_feature_t feature)160 const char * lv_vg_lite_feature_string(vg_lite_feature_t feature)
161 {
162 switch(feature) {
163 FEATURE_ENUM_TO_STRING(IM_INDEX_FORMAT);
164 FEATURE_ENUM_TO_STRING(SCISSOR);
165 FEATURE_ENUM_TO_STRING(BORDER_CULLING);
166 FEATURE_ENUM_TO_STRING(RGBA2_FORMAT);
167 FEATURE_ENUM_TO_STRING(QUALITY_8X);
168 FEATURE_ENUM_TO_STRING(IM_FASTCLAER);
169 FEATURE_ENUM_TO_STRING(RADIAL_GRADIENT);
170 FEATURE_ENUM_TO_STRING(GLOBAL_ALPHA);
171 FEATURE_ENUM_TO_STRING(RGBA8_ETC2_EAC);
172 FEATURE_ENUM_TO_STRING(COLOR_KEY);
173 FEATURE_ENUM_TO_STRING(DOUBLE_IMAGE);
174 FEATURE_ENUM_TO_STRING(YUV_OUTPUT);
175 FEATURE_ENUM_TO_STRING(FLEXA);
176 FEATURE_ENUM_TO_STRING(24BIT);
177 FEATURE_ENUM_TO_STRING(DITHER);
178 FEATURE_ENUM_TO_STRING(USE_DST);
179 FEATURE_ENUM_TO_STRING(PE_CLEAR);
180 FEATURE_ENUM_TO_STRING(IM_INPUT);
181 FEATURE_ENUM_TO_STRING(DEC_COMPRESS);
182 FEATURE_ENUM_TO_STRING(LINEAR_GRADIENT_EXT);
183 FEATURE_ENUM_TO_STRING(MASK);
184 FEATURE_ENUM_TO_STRING(MIRROR);
185 FEATURE_ENUM_TO_STRING(GAMMA);
186 FEATURE_ENUM_TO_STRING(NEW_BLEND_MODE);
187 FEATURE_ENUM_TO_STRING(STENCIL);
188 FEATURE_ENUM_TO_STRING(SRC_PREMULTIPLIED); /*! Valid only if FEATURE_ENUM_TO_STRING(HW_PREMULTIPLY is 0 */
189 FEATURE_ENUM_TO_STRING(HW_PREMULTIPLY); /*! HW multiplier can accept either premultiplied or not */
190 FEATURE_ENUM_TO_STRING(COLOR_TRANSFORMATION);
191 FEATURE_ENUM_TO_STRING(LVGL_SUPPORT);
192 FEATURE_ENUM_TO_STRING(INDEX_ENDIAN);
193 FEATURE_ENUM_TO_STRING(24BIT_PLANAR);
194 FEATURE_ENUM_TO_STRING(PIXEL_MATRIX);
195 FEATURE_ENUM_TO_STRING(NEW_IMAGE_INDEX);
196 FEATURE_ENUM_TO_STRING(PARALLEL_PATHS);
197 FEATURE_ENUM_TO_STRING(STRIPE_MODE);
198 FEATURE_ENUM_TO_STRING(IM_DEC_INPUT);
199 FEATURE_ENUM_TO_STRING(GAUSSIAN_BLUR);
200 FEATURE_ENUM_TO_STRING(RECTANGLE_TILED_OUT);
201 FEATURE_ENUM_TO_STRING(TESSELLATION_TILED_OUT);
202 FEATURE_ENUM_TO_STRING(IM_REPEAT_REFLECT);
203 FEATURE_ENUM_TO_STRING(YUY2_INPUT);
204 FEATURE_ENUM_TO_STRING(YUV_INPUT);
205 FEATURE_ENUM_TO_STRING(YUV_TILED_INPUT);
206 FEATURE_ENUM_TO_STRING(AYUV_INPUT);
207 FEATURE_ENUM_TO_STRING(16PIXELS_ALIGN);
208 FEATURE_ENUM_TO_STRING(DEC_COMPRESS_2_0);
209 default:
210 break;
211 }
212 return "UNKNOW_FEATURE";
213 }
214
lv_vg_lite_buffer_format_string(vg_lite_buffer_format_t format)215 const char * lv_vg_lite_buffer_format_string(vg_lite_buffer_format_t format)
216 {
217 switch(format) {
218 VG_LITE_ENUM_TO_STRING(RGBA8888);
219 VG_LITE_ENUM_TO_STRING(BGRA8888);
220 VG_LITE_ENUM_TO_STRING(RGBX8888);
221 VG_LITE_ENUM_TO_STRING(BGRX8888);
222 VG_LITE_ENUM_TO_STRING(RGB565);
223 VG_LITE_ENUM_TO_STRING(BGR565);
224 VG_LITE_ENUM_TO_STRING(RGBA4444);
225 VG_LITE_ENUM_TO_STRING(BGRA4444);
226 VG_LITE_ENUM_TO_STRING(BGRA5551);
227 VG_LITE_ENUM_TO_STRING(A4);
228 VG_LITE_ENUM_TO_STRING(A8);
229 VG_LITE_ENUM_TO_STRING(L8);
230 VG_LITE_ENUM_TO_STRING(YUYV);
231 VG_LITE_ENUM_TO_STRING(YUY2);
232 VG_LITE_ENUM_TO_STRING(NV12);
233 VG_LITE_ENUM_TO_STRING(ANV12);
234 VG_LITE_ENUM_TO_STRING(AYUY2);
235 VG_LITE_ENUM_TO_STRING(YV12);
236 VG_LITE_ENUM_TO_STRING(YV24);
237 VG_LITE_ENUM_TO_STRING(YV16);
238 VG_LITE_ENUM_TO_STRING(NV16);
239 VG_LITE_ENUM_TO_STRING(YUY2_TILED);
240 VG_LITE_ENUM_TO_STRING(NV12_TILED);
241 VG_LITE_ENUM_TO_STRING(ANV12_TILED);
242 VG_LITE_ENUM_TO_STRING(AYUY2_TILED);
243 VG_LITE_ENUM_TO_STRING(INDEX_1);
244 VG_LITE_ENUM_TO_STRING(INDEX_2);
245 VG_LITE_ENUM_TO_STRING(INDEX_4);
246 VG_LITE_ENUM_TO_STRING(INDEX_8);
247 VG_LITE_ENUM_TO_STRING(RGBA2222);
248 VG_LITE_ENUM_TO_STRING(BGRA2222);
249 VG_LITE_ENUM_TO_STRING(ABGR2222);
250 VG_LITE_ENUM_TO_STRING(ARGB2222);
251 VG_LITE_ENUM_TO_STRING(ABGR4444);
252 VG_LITE_ENUM_TO_STRING(ARGB4444);
253 VG_LITE_ENUM_TO_STRING(ABGR8888);
254 VG_LITE_ENUM_TO_STRING(ARGB8888);
255 VG_LITE_ENUM_TO_STRING(ABGR1555);
256 VG_LITE_ENUM_TO_STRING(RGBA5551);
257 VG_LITE_ENUM_TO_STRING(ARGB1555);
258 VG_LITE_ENUM_TO_STRING(XBGR8888);
259 VG_LITE_ENUM_TO_STRING(XRGB8888);
260 VG_LITE_ENUM_TO_STRING(RGBA8888_ETC2_EAC);
261 VG_LITE_ENUM_TO_STRING(RGB888);
262 VG_LITE_ENUM_TO_STRING(BGR888);
263 VG_LITE_ENUM_TO_STRING(ABGR8565);
264 VG_LITE_ENUM_TO_STRING(BGRA5658);
265 VG_LITE_ENUM_TO_STRING(ARGB8565);
266 VG_LITE_ENUM_TO_STRING(RGBA5658);
267 default:
268 break;
269 }
270 return "UNKNOW_BUFFER_FORMAT";
271 }
272
lv_vg_lite_vlc_op_string(uint8_t vlc_op)273 const char * lv_vg_lite_vlc_op_string(uint8_t vlc_op)
274 {
275 switch(vlc_op) {
276 VLC_OP_ENUM_TO_STRING(END);
277 VLC_OP_ENUM_TO_STRING(CLOSE);
278 VLC_OP_ENUM_TO_STRING(MOVE);
279 VLC_OP_ENUM_TO_STRING(MOVE_REL);
280 VLC_OP_ENUM_TO_STRING(LINE);
281 VLC_OP_ENUM_TO_STRING(LINE_REL);
282 VLC_OP_ENUM_TO_STRING(QUAD);
283 VLC_OP_ENUM_TO_STRING(QUAD_REL);
284 VLC_OP_ENUM_TO_STRING(CUBIC);
285 VLC_OP_ENUM_TO_STRING(CUBIC_REL);
286
287 VLC_OP_ENUM_TO_STRING(SCCWARC);
288 VLC_OP_ENUM_TO_STRING(SCCWARC_REL);
289 VLC_OP_ENUM_TO_STRING(SCWARC);
290 VLC_OP_ENUM_TO_STRING(SCWARC_REL);
291 VLC_OP_ENUM_TO_STRING(LCCWARC);
292 VLC_OP_ENUM_TO_STRING(LCCWARC_REL);
293 VLC_OP_ENUM_TO_STRING(LCWARC);
294 VLC_OP_ENUM_TO_STRING(LCWARC_REL);
295 default:
296 break;
297 }
298 return "UNKNOW_VLC_OP";
299 }
300
path_data_print_cb(void * user_data,uint8_t op_code,const float * data,uint32_t len)301 static void path_data_print_cb(void * user_data, uint8_t op_code, const float * data, uint32_t len)
302 {
303 LV_UNUSED(user_data);
304
305 LV_LOG("%s, ", lv_vg_lite_vlc_op_string(op_code));
306 for(uint32_t i = 0; i < len; i++) {
307 LV_LOG("%0.2f, ", data[i]);
308 }
309 LV_LOG("\n");
310 }
311
lv_vg_lite_path_dump_info(const vg_lite_path_t * path)312 void lv_vg_lite_path_dump_info(const vg_lite_path_t * path)
313 {
314 LV_ASSERT(path != NULL);
315 LV_ASSERT(path->path != NULL);
316 uint8_t fmt_len = lv_vg_lite_path_format_len(path->format);
317 size_t len = path->path_length / fmt_len;
318
319 LV_ASSERT(len > 0);
320
321 LV_LOG_USER("address: %p", (void *)path->path);
322 LV_LOG_USER("length: %d", (int)len);
323 LV_LOG_USER("bounding box: (%0.2f, %0.2f) - (%0.2f, %0.2f)",
324 path->bounding_box[0], path->bounding_box[1],
325 path->bounding_box[2], path->bounding_box[3]);
326 LV_LOG_USER("format: %d", (int)path->format);
327 LV_LOG_USER("quality: %d", (int)path->quality);
328 LV_LOG_USER("path_changed: %d", (int)path->path_changed);
329 LV_LOG_USER("pdata_internal: %d", (int)path->pdata_internal);
330 LV_LOG_USER("type: %d", (int)path->path_type);
331 LV_LOG_USER("add_end: %d", (int)path->add_end);
332
333 lv_vg_lite_path_for_each_data(path, path_data_print_cb, NULL);
334
335 if(path->stroke) {
336 LV_LOG_USER("stroke_path: %p", (void *)path->stroke_path);
337 LV_LOG_USER("stroke_size: %d", (int)path->stroke_size);
338 LV_LOG_USER("stroke_color: 0x%X", (int)path->stroke_color);
339 lv_vg_lite_stroke_dump_info(path->stroke);
340 }
341 }
342
lv_vg_lite_stroke_dump_info(const vg_lite_stroke_t * stroke)343 void lv_vg_lite_stroke_dump_info(const vg_lite_stroke_t * stroke)
344 {
345 LV_ASSERT(stroke != NULL);
346 LV_LOG_USER("stroke: %p", (void *)stroke);
347
348 /* Stroke parameters */
349 LV_LOG_USER("cap_style: 0x%X", (int)stroke->cap_style);
350 LV_LOG_USER("join_style: 0x%X", (int)stroke->join_style);
351 LV_LOG_USER("line_width: %f", stroke->line_width);
352 LV_LOG_USER("miter_limit: %f", stroke->miter_limit);
353
354 LV_LOG_USER("dash_pattern: %p", (void *)stroke->dash_pattern);
355 LV_LOG_USER("pattern_count: %d", (int)stroke->pattern_count);
356 if(stroke->dash_pattern) {
357 for(int i = 0; i < (int)stroke->pattern_count; i++) {
358 LV_LOG_USER("dash_pattern[%d]: %f", i, stroke->dash_pattern[i]);
359 }
360 }
361
362 LV_LOG_USER("dash_phase: %f", stroke->dash_phase);
363 LV_LOG_USER("dash_length: %f", stroke->dash_length);
364 LV_LOG_USER("dash_index: %d", (int)stroke->dash_index);
365 LV_LOG_USER("half_width: %f", stroke->half_width);
366
367 /* Total length of stroke dash patterns. */
368 LV_LOG_USER("pattern_length: %f", stroke->pattern_length);
369
370 /* For fast checking. */
371 LV_LOG_USER("miter_square: %f", stroke->miter_square);
372
373 /* Temp storage of stroke subPath. */
374 LV_LOG_USER("path_points: %p", (void *)stroke->path_points);
375 LV_LOG_USER("path_end: %p", (void *)stroke->path_end);
376 LV_LOG_USER("point_count: %d", (int)stroke->point_count);
377
378 LV_LOG_USER("left_point: %p", (void *)stroke->left_point);
379 LV_LOG_USER("right_point: %p", (void *)stroke->right_point);
380 LV_LOG_USER("stroke_points: %p", (void *)stroke->stroke_points);
381 LV_LOG_USER("stroke_end: %p", (void *)stroke->stroke_end);
382 LV_LOG_USER("stroke_count: %d", (int)stroke->stroke_count);
383
384 /* Divide stroke path according to move or move_rel for avoiding implicit closure. */
385 LV_LOG_USER("path_list_divide: %p", (void *)stroke->path_list_divide);
386
387 /* pointer to current divided path data. */
388 LV_LOG_USER("cur_list: %p", (void *)stroke->cur_list);
389
390 /* Flag that add end_path in driver. */
391 LV_LOG_USER("add_end: %d", (int)stroke->add_end);
392 LV_LOG_USER("dash_reset: %d", (int)stroke->dash_reset);
393
394 /* Sub path list. */
395 LV_LOG_USER("stroke_paths: %p", (void *)stroke->stroke_paths);
396
397 /* Last sub path. */
398 LV_LOG_USER("last_stroke: %p", (void *)stroke->last_stroke);
399
400 /* Swing area handling. */
401 LV_LOG_USER("swing_handling: %d", (int)stroke->swing_handling);
402 LV_LOG_USER("swing_deltax: %f", stroke->swing_deltax);
403 LV_LOG_USER("swing_deltay: %f", stroke->swing_deltay);
404 LV_LOG_USER("swing_start: %p", (void *)stroke->swing_start);
405 LV_LOG_USER("swing_stroke: %p", (void *)stroke->swing_stroke);
406 LV_LOG_USER("swing_length: %f", stroke->swing_length);
407 LV_LOG_USER("swing_centlen: %f", stroke->swing_centlen);
408 LV_LOG_USER("swing_count: %d", (int)stroke->swing_count);
409 LV_LOG_USER("need_swing: %d", (int)stroke->need_swing);
410 LV_LOG_USER("swing_ccw: %d", (int)stroke->swing_ccw);
411
412 LV_LOG_USER("stroke_length: %f", stroke->stroke_length);
413 LV_LOG_USER("stroke_size: %d", (int)stroke->stroke_size);
414
415 LV_LOG_USER("fattened: %d", (int)stroke->fattened);
416 LV_LOG_USER("closed: %d", (int)stroke->closed);
417 }
418
lv_vg_lite_buffer_dump_info(const vg_lite_buffer_t * buffer)419 void lv_vg_lite_buffer_dump_info(const vg_lite_buffer_t * buffer)
420 {
421 LV_LOG_USER("memory: %p", (buffer)->memory);
422 LV_LOG_USER("address: 0x%08x", (int)(buffer)->address);
423 LV_LOG_USER("size: W%d x H%d", (int)((buffer)->width), (int)((buffer)->height));
424 LV_LOG_USER("stride: %d", (int)((buffer)->stride));
425 LV_LOG_USER("format: %d (%s)",
426 (int)((buffer)->format),
427 lv_vg_lite_buffer_format_string((buffer)->format));
428 LV_LOG_USER("tiled: %d", (int)((buffer)->tiled));
429 }
430
lv_vg_lite_matrix_dump_info(const vg_lite_matrix_t * matrix)431 void lv_vg_lite_matrix_dump_info(const vg_lite_matrix_t * matrix)
432 {
433 for(int i = 0; i < 3; i++) {
434 LV_LOG_USER("| %f, %f, %f |",
435 (matrix)->m[i][0], (matrix)->m[i][1], (matrix)->m[i][2]);
436 }
437 }
438
lv_vg_lite_is_dest_cf_supported(lv_color_format_t cf)439 bool lv_vg_lite_is_dest_cf_supported(lv_color_format_t cf)
440 {
441 switch(cf) {
442 case LV_COLOR_FORMAT_A8:
443 case LV_COLOR_FORMAT_L8:
444 case LV_COLOR_FORMAT_RGB565:
445 case LV_COLOR_FORMAT_ARGB8888:
446 case LV_COLOR_FORMAT_XRGB8888:
447 case LV_COLOR_FORMAT_ARGB1555:
448 case LV_COLOR_FORMAT_ARGB4444:
449 case LV_COLOR_FORMAT_ARGB2222:
450 return true;
451
452 case LV_COLOR_FORMAT_ARGB8565:
453 case LV_COLOR_FORMAT_RGB888:
454 return vg_lite_query_feature(gcFEATURE_BIT_VG_24BIT) ? true : false;
455
456 default:
457 break;
458 }
459
460 return false;
461 }
462
lv_vg_lite_is_src_cf_supported(lv_color_format_t cf)463 bool lv_vg_lite_is_src_cf_supported(lv_color_format_t cf)
464 {
465 switch(cf) {
466 case LV_COLOR_FORMAT_A4:
467 case LV_COLOR_FORMAT_A8:
468 case LV_COLOR_FORMAT_L8:
469 case LV_COLOR_FORMAT_RGB565:
470 case LV_COLOR_FORMAT_ARGB8888:
471 case LV_COLOR_FORMAT_XRGB8888:
472 case LV_COLOR_FORMAT_ARGB1555:
473 case LV_COLOR_FORMAT_ARGB4444:
474 case LV_COLOR_FORMAT_ARGB2222:
475 return true;
476
477 case LV_COLOR_FORMAT_I1:
478 case LV_COLOR_FORMAT_I2:
479 case LV_COLOR_FORMAT_I4:
480 return vg_lite_query_feature(gcFEATURE_BIT_VG_INDEX_ENDIAN) ? true : false;
481
482 case LV_COLOR_FORMAT_I8:
483 return vg_lite_query_feature(gcFEATURE_BIT_VG_IM_INDEX_FORMAT) ? true : false;
484
485 case LV_COLOR_FORMAT_ARGB8565:
486 case LV_COLOR_FORMAT_RGB888:
487 return vg_lite_query_feature(gcFEATURE_BIT_VG_24BIT) ? true : false;
488
489 case LV_COLOR_FORMAT_NV12:
490 return vg_lite_query_feature(gcFEATURE_BIT_VG_YUV_INPUT) ? true : false;
491
492 case LV_COLOR_FORMAT_YUY2:
493 return vg_lite_query_feature(gcFEATURE_BIT_VG_YUY2_INPUT) ? true : false;
494
495 default:
496 break;
497 }
498
499 return false;
500 }
501
lv_vg_lite_vg_fmt(lv_color_format_t cf)502 vg_lite_buffer_format_t lv_vg_lite_vg_fmt(lv_color_format_t cf)
503 {
504 switch(cf) {
505 case LV_COLOR_FORMAT_A4:
506 return VG_LITE_A4;
507
508 case LV_COLOR_FORMAT_A8:
509 return VG_LITE_A8;
510
511 case LV_COLOR_FORMAT_L8:
512 return VG_LITE_L8;
513
514 case LV_COLOR_FORMAT_I1:
515 return VG_LITE_INDEX_1;
516
517 case LV_COLOR_FORMAT_I2:
518 return VG_LITE_INDEX_2;
519
520 case LV_COLOR_FORMAT_I4:
521 return VG_LITE_INDEX_4;
522
523 case LV_COLOR_FORMAT_I8:
524 return VG_LITE_INDEX_8;
525
526 case LV_COLOR_FORMAT_ARGB1555:
527 return VG_LITE_BGRA5551;
528
529 case LV_COLOR_FORMAT_ARGB4444:
530 return VG_LITE_BGRA4444;
531
532 case LV_COLOR_FORMAT_ARGB2222:
533 return VG_LITE_BGRA2222;
534
535 case LV_COLOR_FORMAT_RGB565:
536 return VG_LITE_BGR565;
537
538 case LV_COLOR_FORMAT_ARGB8565:
539 return VG_LITE_BGRA5658;
540
541 case LV_COLOR_FORMAT_RGB888:
542 return VG_LITE_BGR888;
543
544 case LV_COLOR_FORMAT_ARGB8888:
545 return VG_LITE_BGRA8888;
546
547 case LV_COLOR_FORMAT_XRGB8888:
548 return VG_LITE_BGRX8888;
549
550 case LV_COLOR_FORMAT_NV12:
551 return VG_LITE_NV12;
552
553 case LV_COLOR_FORMAT_YUY2:
554 return VG_LITE_YUY2;
555
556 default:
557 LV_LOG_ERROR("unsupported color format: %d", cf);
558 break;
559 }
560
561 LV_ASSERT(false);
562 return 0;
563 }
564
lv_vg_lite_buffer_format_bytes(vg_lite_buffer_format_t format,uint32_t * mul,uint32_t * div,uint32_t * bytes_align)565 void lv_vg_lite_buffer_format_bytes(
566 vg_lite_buffer_format_t format,
567 uint32_t * mul,
568 uint32_t * div,
569 uint32_t * bytes_align)
570 {
571 /* Get the bpp information of a color format. */
572 *mul = *div = 1;
573 *bytes_align = 4;
574 switch(format) {
575 case VG_LITE_L8:
576 case VG_LITE_A8:
577 case VG_LITE_RGBA8888_ETC2_EAC:
578 break;
579 case VG_LITE_A4:
580 *div = 2;
581 break;
582 case VG_LITE_ABGR1555:
583 case VG_LITE_ARGB1555:
584 case VG_LITE_BGRA5551:
585 case VG_LITE_RGBA5551:
586 case VG_LITE_RGBA4444:
587 case VG_LITE_BGRA4444:
588 case VG_LITE_ABGR4444:
589 case VG_LITE_ARGB4444:
590 case VG_LITE_RGB565:
591 case VG_LITE_BGR565:
592 case VG_LITE_YUYV:
593 case VG_LITE_YUY2:
594 case VG_LITE_YUY2_TILED:
595 /* AYUY2 buffer memory = YUY2 + alpha. */
596 case VG_LITE_AYUY2:
597 case VG_LITE_AYUY2_TILED:
598 *mul = 2;
599 break;
600 case VG_LITE_RGBA8888:
601 case VG_LITE_BGRA8888:
602 case VG_LITE_ABGR8888:
603 case VG_LITE_ARGB8888:
604 case VG_LITE_RGBX8888:
605 case VG_LITE_BGRX8888:
606 case VG_LITE_XBGR8888:
607 case VG_LITE_XRGB8888:
608 *mul = 4;
609 break;
610 case VG_LITE_NV12:
611 case VG_LITE_NV12_TILED:
612 *mul = 1;
613 break;
614 case VG_LITE_ANV12:
615 case VG_LITE_ANV12_TILED:
616 *mul = 4;
617 break;
618 case VG_LITE_INDEX_1:
619 *div = 8;
620 *bytes_align = 8;
621 break;
622 case VG_LITE_INDEX_2:
623 *div = 4;
624 *bytes_align = 8;
625 break;
626 case VG_LITE_INDEX_4:
627 *div = 2;
628 *bytes_align = 8;
629 break;
630 case VG_LITE_INDEX_8:
631 *bytes_align = 1;
632 break;
633 case VG_LITE_RGBA2222:
634 case VG_LITE_BGRA2222:
635 case VG_LITE_ABGR2222:
636 case VG_LITE_ARGB2222:
637 *mul = 1;
638 break;
639 case VG_LITE_RGB888:
640 case VG_LITE_BGR888:
641 case VG_LITE_ABGR8565:
642 case VG_LITE_BGRA5658:
643 case VG_LITE_ARGB8565:
644 case VG_LITE_RGBA5658:
645 *mul = 3;
646 break;
647 default:
648 LV_LOG_ERROR("unsupported color format: 0x%" PRIx32, (uint32_t)format);
649 LV_ASSERT(false);
650 break;
651 }
652 }
653
lv_vg_lite_width_to_stride(uint32_t w,vg_lite_buffer_format_t color_format)654 uint32_t lv_vg_lite_width_to_stride(uint32_t w, vg_lite_buffer_format_t color_format)
655 {
656 w = lv_vg_lite_width_align(w);
657
658 uint32_t mul, div, align;
659 lv_vg_lite_buffer_format_bytes(color_format, &mul, &div, &align);
660 return LV_VG_LITE_ALIGN(((w * mul + div - 1) / div), align);
661 }
662
lv_vg_lite_width_align(uint32_t w)663 uint32_t lv_vg_lite_width_align(uint32_t w)
664 {
665 if(lv_vg_lite_16px_align()) {
666 w = LV_VG_LITE_ALIGN(w, 16);
667 }
668
669 return w;
670 }
671
lv_vg_lite_buffer_init(vg_lite_buffer_t * buffer,const void * ptr,int32_t width,int32_t height,uint32_t stride,vg_lite_buffer_format_t format,bool tiled)672 void lv_vg_lite_buffer_init(
673 vg_lite_buffer_t * buffer,
674 const void * ptr,
675 int32_t width,
676 int32_t height,
677 uint32_t stride,
678 vg_lite_buffer_format_t format,
679 bool tiled)
680 {
681 uint32_t mul;
682 uint32_t div;
683 uint32_t align;
684 LV_ASSERT_NULL(buffer);
685 LV_ASSERT_NULL(ptr);
686
687 lv_memzero(buffer, sizeof(vg_lite_buffer_t));
688
689 buffer->format = format;
690 if(tiled || format == VG_LITE_RGBA8888_ETC2_EAC) {
691 buffer->tiled = VG_LITE_TILED;
692 }
693 else {
694 buffer->tiled = VG_LITE_LINEAR;
695 }
696 buffer->image_mode = VG_LITE_NORMAL_IMAGE_MODE;
697 buffer->transparency_mode = VG_LITE_IMAGE_OPAQUE;
698 buffer->width = width;
699 buffer->height = height;
700 if(stride == LV_STRIDE_AUTO) {
701 lv_vg_lite_buffer_format_bytes(buffer->format, &mul, &div, &align);
702 buffer->stride = LV_VG_LITE_ALIGN((buffer->width * mul / div), align);
703 }
704 else {
705 buffer->stride = stride;
706 }
707
708 if(format == VG_LITE_NV12) {
709 lv_yuv_buf_t * frame_p = (lv_yuv_buf_t *)ptr;
710 buffer->memory = (void *)frame_p->semi_planar.y.buf;
711 buffer->address = (uintptr_t)frame_p->semi_planar.y.buf;
712 buffer->yuv.swizzle = VG_LITE_SWIZZLE_UV;
713 buffer->yuv.alpha_stride = buffer->stride;
714 buffer->yuv.uv_height = buffer->height / 2;
715 buffer->yuv.uv_memory = (void *)frame_p->semi_planar.uv.buf;
716 buffer->yuv.uv_planar = (uint32_t)(uintptr_t)frame_p->semi_planar.uv.buf;
717 buffer->yuv.uv_stride = frame_p->semi_planar.uv.stride;
718 }
719 else {
720 buffer->memory = (void *)ptr;
721 buffer->address = (uintptr_t)ptr;
722 }
723 }
724
lv_vg_lite_buffer_from_draw_buf(vg_lite_buffer_t * buffer,const lv_draw_buf_t * draw_buf)725 void lv_vg_lite_buffer_from_draw_buf(vg_lite_buffer_t * buffer, const lv_draw_buf_t * draw_buf)
726 {
727 LV_ASSERT_NULL(buffer);
728 LV_ASSERT_NULL(draw_buf);
729
730 const uint8_t * ptr = draw_buf->data;
731 int32_t width = draw_buf->header.w;
732 int32_t height = draw_buf->header.h;
733 uint32_t stride = draw_buf->header.stride;
734 vg_lite_buffer_format_t format = lv_vg_lite_vg_fmt(draw_buf->header.cf);
735
736 if(LV_COLOR_FORMAT_IS_INDEXED(draw_buf->header.cf)) {
737 uint32_t palette_size_bytes = LV_COLOR_INDEXED_PALETTE_SIZE(draw_buf->header.cf) * sizeof(uint32_t);
738
739 /* Skip palette */
740 ptr += LV_VG_LITE_ALIGN(palette_size_bytes, LV_DRAW_BUF_ALIGN);
741 }
742
743 width = lv_vg_lite_width_align(width);
744
745 lv_vg_lite_buffer_init(buffer, ptr, width, height, stride, format, false);
746
747 /* Alpha image need to be multiplied by color */
748 if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(draw_buf->header.cf)) {
749 buffer->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE;
750 }
751 }
752
lv_vg_lite_image_matrix(vg_lite_matrix_t * matrix,int32_t x,int32_t y,const lv_draw_image_dsc_t * dsc)753 void lv_vg_lite_image_matrix(vg_lite_matrix_t * matrix, int32_t x, int32_t y, const lv_draw_image_dsc_t * dsc)
754 {
755 LV_ASSERT_NULL(matrix);
756 LV_ASSERT_NULL(dsc);
757
758 int32_t rotation = dsc->rotation;
759 int32_t scale_x = dsc->scale_x;
760 int32_t scale_y = dsc->scale_y;
761
762 vg_lite_translate(x, y, matrix);
763
764 if(rotation != 0 || scale_x != LV_SCALE_NONE || scale_y != LV_SCALE_NONE) {
765 lv_point_t pivot = dsc->pivot;
766 vg_lite_translate(pivot.x, pivot.y, matrix);
767
768 if(rotation != 0) {
769 vg_lite_rotate(rotation * 0.1f, matrix);
770 }
771
772 if(scale_x != LV_SCALE_NONE || scale_y != LV_SCALE_NONE) {
773 vg_lite_scale(
774 (vg_lite_float_t)scale_x / LV_SCALE_NONE,
775 (vg_lite_float_t)scale_y / LV_SCALE_NONE,
776 matrix);
777 }
778
779 vg_lite_translate(-pivot.x, -pivot.y, matrix);
780 }
781 }
782
lv_vg_lite_image_recolor(vg_lite_buffer_t * buffer,const lv_draw_image_dsc_t * dsc)783 vg_lite_color_t lv_vg_lite_image_recolor(vg_lite_buffer_t * buffer, const lv_draw_image_dsc_t * dsc)
784 {
785 LV_ASSERT_NULL(buffer);
786 LV_ASSERT_NULL(dsc);
787
788 if((buffer->format == VG_LITE_A4 || buffer->format == VG_LITE_A8) || dsc->recolor_opa > LV_OPA_TRANSP) {
789 /* alpha image and image recolor */
790 buffer->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE;
791 return lv_vg_lite_color(dsc->recolor, LV_OPA_MIX2(dsc->opa, dsc->recolor_opa), true);
792 }
793
794 if(dsc->opa < LV_OPA_COVER) {
795 /* normal image opa */
796 buffer->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE;
797 vg_lite_color_t color;
798 lv_memset(&color, dsc->opa, sizeof(color));
799 return color;
800 }
801
802 return 0;
803 }
804
lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer,lv_image_decoder_dsc_t * decoder_dsc,const void * src,bool no_cache,bool premultiply)805 bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_dsc_t * decoder_dsc, const void * src,
806 bool no_cache, bool premultiply)
807 {
808 LV_ASSERT_NULL(buffer);
809 LV_ASSERT_NULL(decoder_dsc);
810 LV_ASSERT_NULL(src);
811
812 lv_image_decoder_args_t args;
813 lv_memzero(&args, sizeof(lv_image_decoder_args_t));
814 args.premultiply = premultiply;
815 args.stride_align = true;
816 args.use_indexed = true;
817 args.no_cache = no_cache;
818 args.flush_cache = true;
819
820 lv_result_t res = lv_image_decoder_open(decoder_dsc, src, &args);
821 if(res != LV_RESULT_OK) {
822 LV_LOG_ERROR("Failed to open image");
823 return false;
824 }
825
826 const lv_draw_buf_t * decoded = decoder_dsc->decoded;
827 if(decoded == NULL || decoded->data == NULL) {
828 lv_image_decoder_close(decoder_dsc);
829 LV_LOG_ERROR("image data is NULL");
830 return false;
831 }
832
833 if(!lv_vg_lite_is_src_cf_supported(decoded->header.cf)) {
834 LV_LOG_ERROR("unsupported color format: %d", decoded->header.cf);
835 lv_image_decoder_close(decoder_dsc);
836 return false;
837 }
838
839 if(LV_COLOR_FORMAT_IS_INDEXED(decoded->header.cf)) {
840 uint32_t palette_size = LV_COLOR_INDEXED_PALETTE_SIZE(decoded->header.cf);
841 LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_set_CLUT");
842 LV_VG_LITE_CHECK_ERROR(vg_lite_set_CLUT(palette_size, (vg_lite_uint32_t *)decoded->data));
843 LV_PROFILER_DRAW_END_TAG("vg_lite_set_CLUT");
844 }
845
846 lv_vg_lite_buffer_from_draw_buf(buffer, decoded);
847 return true;
848 }
849
lv_vg_lite_image_dsc_init(struct _lv_draw_vg_lite_unit_t * unit)850 void lv_vg_lite_image_dsc_init(struct _lv_draw_vg_lite_unit_t * unit)
851 {
852 unit->image_dsc_pending = lv_vg_lite_pending_create(sizeof(lv_image_decoder_dsc_t), 4);
853 lv_vg_lite_pending_set_free_cb(unit->image_dsc_pending, image_dsc_free_cb, NULL);
854 }
855
lv_vg_lite_image_dsc_deinit(struct _lv_draw_vg_lite_unit_t * unit)856 void lv_vg_lite_image_dsc_deinit(struct _lv_draw_vg_lite_unit_t * unit)
857 {
858 lv_vg_lite_pending_destroy(unit->image_dsc_pending);
859 unit->image_dsc_pending = NULL;
860 }
861
lv_vg_lite_rect(vg_lite_rectangle_t * rect,const lv_area_t * area)862 void lv_vg_lite_rect(vg_lite_rectangle_t * rect, const lv_area_t * area)
863 {
864 rect->x = area->x1;
865 rect->y = area->y1;
866 rect->width = lv_area_get_width(area);
867 rect->height = lv_area_get_height(area);
868 }
869
lv_vg_lite_get_palette_size(vg_lite_buffer_format_t format)870 uint32_t lv_vg_lite_get_palette_size(vg_lite_buffer_format_t format)
871 {
872 uint32_t size = 0;
873 switch(format) {
874 case VG_LITE_INDEX_1:
875 size = 1 << 1;
876 break;
877 case VG_LITE_INDEX_2:
878 size = 1 << 2;
879 break;
880 case VG_LITE_INDEX_4:
881 size = 1 << 4;
882 break;
883 case VG_LITE_INDEX_8:
884 size = 1 << 8;
885 break;
886 default:
887 break;
888 }
889 return size;
890 }
891
lv_vg_lite_color(lv_color_t color,lv_opa_t opa,bool pre_mul)892 vg_lite_color_t lv_vg_lite_color(lv_color_t color, lv_opa_t opa, bool pre_mul)
893 {
894 if(pre_mul && opa < LV_OPA_COVER) {
895 color.red = LV_UDIV255(color.red * opa);
896 color.green = LV_UDIV255(color.green * opa);
897 color.blue = LV_UDIV255(color.blue * opa);
898 }
899 return (uint32_t)opa << 24 | (uint32_t)color.blue << 16 | (uint32_t)color.green << 8 | color.red;
900 }
901
lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode,bool has_pre_mul)902 vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode, bool has_pre_mul)
903 {
904 if(!has_pre_mul && vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT)) {
905 switch(blend_mode) {
906 case LV_BLEND_MODE_NORMAL: /**< Simply mix according to the opacity value*/
907 return VG_LITE_BLEND_NORMAL_LVGL;
908
909 case LV_BLEND_MODE_ADDITIVE: /**< Add the respective color channels*/
910 return VG_LITE_BLEND_ADDITIVE_LVGL;
911
912 case LV_BLEND_MODE_SUBTRACTIVE: /**< Subtract the foreground from the background*/
913 return VG_LITE_BLEND_SUBTRACT_LVGL;
914
915 case LV_BLEND_MODE_MULTIPLY: /**< Multiply the foreground and background*/
916 return VG_LITE_BLEND_MULTIPLY_LVGL;
917
918 default:
919 return VG_LITE_BLEND_NONE;
920 }
921 }
922
923 switch(blend_mode) {
924 case LV_BLEND_MODE_NORMAL: /**< Simply mix according to the opacity value*/
925 if(!has_pre_mul && vg_lite_query_feature(gcFEATURE_BIT_VG_HW_PREMULTIPLY)) {
926 return VG_LITE_BLEND_PREMULTIPLY_SRC_OVER;
927 }
928 return VG_LITE_BLEND_SRC_OVER;
929
930 case LV_BLEND_MODE_ADDITIVE: /**< Add the respective color channels*/
931 return VG_LITE_BLEND_ADDITIVE;
932
933 case LV_BLEND_MODE_SUBTRACTIVE: /**< Subtract the foreground from the background*/
934 return VG_LITE_BLEND_SUBTRACT;
935
936 case LV_BLEND_MODE_MULTIPLY: /**< Multiply the foreground and background*/
937 return VG_LITE_BLEND_MULTIPLY;
938
939 default:
940 return VG_LITE_BLEND_NONE;
941 }
942 }
943
lv_vg_lite_buffer_check(const vg_lite_buffer_t * buffer,bool is_src)944 bool lv_vg_lite_buffer_check(const vg_lite_buffer_t * buffer, bool is_src)
945 {
946 uint32_t mul;
947 uint32_t div;
948 uint32_t align;
949 int32_t stride;
950
951 if(!buffer) {
952 LV_LOG_ERROR("buffer is NULL");
953 return false;
954 }
955
956 if(buffer->width < 1) {
957 LV_LOG_ERROR("buffer width(%d) < 1", (int)buffer->width);
958 return false;
959 }
960
961 if(buffer->height < 1) {
962 LV_LOG_ERROR("buffer height(%d) < 1", (int)buffer->height);
963 return false;
964 }
965
966 if(!(buffer->tiled == VG_LITE_LINEAR || buffer->tiled == VG_LITE_TILED)) {
967 LV_LOG_ERROR("buffer tiled(%d) is invalid", (int)buffer->tiled);
968 return false;
969 }
970
971 if(buffer->memory == NULL) {
972 LV_LOG_ERROR("buffer memory is NULL");
973 return false;
974 }
975
976 if(is_src && buffer->width != (vg_lite_int32_t)lv_vg_lite_width_align(buffer->width)) {
977 LV_LOG_ERROR("buffer width(%d) is not aligned", (int)buffer->width);
978 return false;
979 }
980
981 if(!LV_VG_LITE_IS_ALIGNED(buffer->memory, LV_DRAW_BUF_ALIGN)) {
982 LV_LOG_ERROR("buffer address(%p) is not aligned to %d", buffer->memory, LV_DRAW_BUF_ALIGN);
983 return false;
984 }
985
986 lv_vg_lite_buffer_format_bytes(buffer->format, &mul, &div, &align);
987 stride = LV_VG_LITE_ALIGN((buffer->width * mul / div), align);
988
989 if(buffer->stride != stride) {
990 LV_LOG_ERROR("buffer stride(%d) != %d", (int)buffer->stride, (int)stride);
991 return false;
992 }
993
994 switch(buffer->image_mode) {
995 case VG_LITE_ZERO:
996 case VG_LITE_NORMAL_IMAGE_MODE:
997 case VG_LITE_MULTIPLY_IMAGE_MODE:
998 case VG_LITE_STENCIL_MODE:
999 case VG_LITE_NONE_IMAGE_MODE:
1000 case VG_LITE_RECOLOR_MODE:
1001 break;
1002 default:
1003 LV_LOG_ERROR("buffer image_mode(%d) is invalid", (int)buffer->image_mode);
1004 return false;
1005 }
1006
1007 switch(buffer->transparency_mode) {
1008 case VG_LITE_IMAGE_OPAQUE:
1009 case VG_LITE_IMAGE_TRANSPARENT:
1010 break;
1011 default:
1012 LV_LOG_ERROR("buffer transparency_mode(%d) is invalid",
1013 (int)buffer->transparency_mode);
1014 return false;
1015 }
1016
1017 return true;
1018 }
1019
lv_vg_lite_path_check(const vg_lite_path_t * path)1020 bool lv_vg_lite_path_check(const vg_lite_path_t * path)
1021 {
1022 if(path == NULL) {
1023 LV_LOG_ERROR("path is NULL");
1024 return false;
1025 }
1026
1027 if(path->path == NULL) {
1028 LV_LOG_ERROR("path->path is NULL");
1029 return false;
1030 }
1031
1032 uint8_t fmt_len = lv_vg_lite_path_format_len(path->format);
1033 if(!fmt_len) {
1034 LV_LOG_ERROR("path format(%d) is invalid", (int)path->format);
1035 return false;
1036 }
1037
1038 size_t len = path->path_length / fmt_len;
1039
1040 if(len < 1) {
1041 LV_LOG_ERROR("path length(%d) error", (int)path->path_length);
1042 return false;
1043 }
1044
1045 const uint8_t * cur = path->path;
1046 const uint8_t * end = cur + path->path_length;
1047
1048 while(cur < end) {
1049 /* get op code */
1050 uint8_t op_code = LV_VG_LITE_PATH_GET_OP_CODE(cur);
1051
1052 /* get arguments length */
1053 uint8_t arg_len = lv_vg_lite_vlc_op_arg_len(op_code);
1054
1055 /* get next op code */
1056 cur += (fmt_len * (1 + arg_len)) ;
1057
1058 /* break if end */
1059 if(op_code == VLC_OP_END) {
1060 break;
1061 }
1062 }
1063
1064 if(cur != end) {
1065 LV_LOG_ERROR("path length(%d) error", (int)path->path_length);
1066 return false;
1067 }
1068
1069 switch(path->path_type) {
1070 case VG_LITE_DRAW_ZERO:
1071 case VG_LITE_DRAW_FILL_PATH:
1072 case VG_LITE_DRAW_FILL_STROKE_PATH: {
1073 /* Check end op code */
1074 uint8_t end_op_code = LV_VG_LITE_PATH_GET_OP_CODE(end - fmt_len);
1075 if(end_op_code != VLC_OP_END) {
1076 LV_LOG_ERROR("%d (%s) -> is NOT VLC_OP_END", end_op_code, lv_vg_lite_vlc_op_string(end_op_code));
1077 return false;
1078 }
1079 }
1080 break;
1081
1082 case VG_LITE_DRAW_STROKE_PATH:
1083 /* No need to check stroke path end */
1084 break;
1085
1086 default:
1087 LV_LOG_ERROR("path type(%d) is invalid", (int)path->path_type);
1088 return false;
1089 }
1090
1091 return true;
1092 }
1093
lv_vg_lite_matrix_check(const vg_lite_matrix_t * matrix)1094 bool lv_vg_lite_matrix_check(const vg_lite_matrix_t * matrix)
1095 {
1096 if(matrix == NULL) {
1097 LV_LOG_ERROR("matrix is NULL");
1098 return false;
1099 }
1100
1101 vg_lite_matrix_t result;
1102 if(!lv_vg_lite_matrix_inverse(&result, matrix)) {
1103 LV_LOG_ERROR("matrix is not invertible");
1104 lv_vg_lite_matrix_dump_info(matrix);
1105 return false;
1106 }
1107
1108 return true;
1109 }
1110
lv_vg_lite_support_blend_normal(void)1111 bool lv_vg_lite_support_blend_normal(void)
1112 {
1113 if(vg_lite_query_feature(gcFEATURE_BIT_VG_HW_PREMULTIPLY)) {
1114 return true;
1115 }
1116
1117 if(vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT)) {
1118 return true;
1119 }
1120
1121 return false;
1122 }
1123
lv_vg_lite_16px_align(void)1124 bool lv_vg_lite_16px_align(void)
1125 {
1126 return vg_lite_query_feature(gcFEATURE_BIT_VG_16PIXELS_ALIGN);
1127 }
1128
lv_vg_lite_matrix_multiply(vg_lite_matrix_t * matrix,const vg_lite_matrix_t * mult)1129 void lv_vg_lite_matrix_multiply(vg_lite_matrix_t * matrix, const vg_lite_matrix_t * mult)
1130 {
1131 vg_lite_matrix_t temp;
1132 int row, column;
1133 vg_lite_float_t (*m)[3] = matrix->m;
1134
1135 /* Process all rows. */
1136 for(row = 0; row < 3; row++) {
1137 /* Process all columns. */
1138 for(column = 0; column < 3; column++) {
1139 /* Compute matrix entry. */
1140 temp.m[row][column] = (m[row][0] * mult->m[0][column])
1141 + (m[row][1] * mult->m[1][column])
1142 + (m[row][2] * mult->m[2][column]);
1143 }
1144 }
1145
1146 /* Copy temporary matrix into result. */
1147 *matrix = temp;
1148 }
1149
lv_vg_lite_matrix_inverse(vg_lite_matrix_t * result,const vg_lite_matrix_t * matrix)1150 bool lv_vg_lite_matrix_inverse(vg_lite_matrix_t * result, const vg_lite_matrix_t * matrix)
1151 {
1152 vg_lite_float_t det00, det01, det02;
1153 vg_lite_float_t d;
1154 bool is_affine;
1155
1156 /* Test for identity matrix. */
1157 if(matrix == NULL) {
1158 result->m[0][0] = 1.0f;
1159 result->m[0][1] = 0.0f;
1160 result->m[0][2] = 0.0f;
1161 result->m[1][0] = 0.0f;
1162 result->m[1][1] = 1.0f;
1163 result->m[1][2] = 0.0f;
1164 result->m[2][0] = 0.0f;
1165 result->m[2][1] = 0.0f;
1166 result->m[2][2] = 1.0f;
1167
1168 /* Success. */
1169 return true;
1170 }
1171
1172 const vg_lite_float_t (*m)[3] = matrix->m;
1173
1174 det00 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
1175 det01 = m[2][0] * m[1][2] - m[1][0] * m[2][2];
1176 det02 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
1177
1178 /* Compute determinant. */
1179 d = m[0][0] * det00 + m[0][1] * det01 + m[0][2] * det02;
1180
1181 /* Return 0 if there is no inverse matrix. */
1182 if(d == 0.0f)
1183 return false;
1184
1185 /* Compute reciprocal. */
1186 d = 1.0f / d;
1187
1188 /* Determine if the matrix is affine. */
1189 is_affine = (m[2][0] == 0.0f) && (m[2][1] == 0.0f) && (m[2][2] == 1.0f);
1190
1191 result->m[0][0] = d * det00;
1192 result->m[0][1] = d * ((m[2][1] * m[0][2]) - (m[0][1] * m[2][2]));
1193 result->m[0][2] = d * ((m[0][1] * m[1][2]) - (m[1][1] * m[0][2]));
1194 result->m[1][0] = d * det01;
1195 result->m[1][1] = d * ((m[0][0] * m[2][2]) - (m[2][0] * m[0][2]));
1196 result->m[1][2] = d * ((m[1][0] * m[0][2]) - (m[0][0] * m[1][2]));
1197 result->m[2][0] = is_affine ? 0.0f : d * det02;
1198 result->m[2][1] = is_affine ? 0.0f : d * ((m[2][0] * m[0][1]) - (m[0][0] * m[2][1]));
1199 result->m[2][2] = is_affine ? 1.0f : d * ((m[0][0] * m[1][1]) - (m[1][0] * m[0][1]));
1200
1201 /* Success. */
1202 return true;
1203 }
1204
lv_vg_lite_matrix_transform_point(const vg_lite_matrix_t * matrix,const lv_point_precise_t * point)1205 lv_point_precise_t lv_vg_lite_matrix_transform_point(const vg_lite_matrix_t * matrix, const lv_point_precise_t * point)
1206 {
1207 lv_point_precise_t p;
1208 const vg_lite_float_t (*m)[3] = matrix->m;
1209 p.x = (lv_value_precise_t)roundf(point->x * m[0][0] + point->y * m[0][1] + m[0][2]);
1210 p.y = (lv_value_precise_t)roundf(point->x * m[1][0] + point->y * m[1][1] + m[1][2]);
1211 return p;
1212 }
1213
lv_vg_lite_set_scissor_area(const lv_area_t * area)1214 void lv_vg_lite_set_scissor_area(const lv_area_t * area)
1215 {
1216 LV_PROFILER_DRAW_BEGIN;
1217 #if VGLITE_RELEASE_VERSION <= VGLITE_MAKE_VERSION(4,0,57)
1218 /**
1219 * In the new version of VG-Lite, vg_lite_set_scissor no longer needs to call vg_lite_enable_scissor and
1220 * vg_lite_disable_scissor APIs.
1221 *
1222 * Original description in the manual:
1223 * Description: This is a legacy scissor API function that can be used to set and enable a single scissor rectangle
1224 * for the render target. This scissor API is supported by a different hardware mechanism other than the mask layer,
1225 * and it is not enabled/disabled by vg_lite_enable_scissor and vg_lite_disable_scissor APIs.
1226 */
1227 LV_VG_LITE_CHECK_ERROR(vg_lite_enable_scissor());
1228 #endif
1229 LV_VG_LITE_CHECK_ERROR(vg_lite_set_scissor(
1230 area->x1,
1231 area->y1,
1232 area->x2 + 1,
1233 area->y2 + 1));
1234 LV_PROFILER_DRAW_END;
1235 }
1236
lv_vg_lite_disable_scissor(void)1237 void lv_vg_lite_disable_scissor(void)
1238 {
1239 LV_PROFILER_DRAW_BEGIN;
1240 /* Restore full screen scissor */
1241 LV_VG_LITE_CHECK_ERROR(vg_lite_set_scissor(
1242 0,
1243 0,
1244 LV_HOR_RES,
1245 LV_VER_RES));
1246 LV_PROFILER_DRAW_END;
1247 }
1248
lv_vg_lite_flush(struct _lv_draw_vg_lite_unit_t * u)1249 void lv_vg_lite_flush(struct _lv_draw_vg_lite_unit_t * u)
1250 {
1251 LV_ASSERT_NULL(u);
1252 LV_PROFILER_DRAW_BEGIN;
1253
1254 u->flush_count++;
1255 u->letter_count = 0;
1256
1257 #if LV_VG_LITE_FLUSH_MAX_COUNT
1258 if(u->flush_count < LV_VG_LITE_FLUSH_MAX_COUNT) {
1259 /* Do not flush too often */
1260 LV_PROFILER_DRAW_END;
1261 return;
1262 }
1263 #else
1264 vg_lite_uint32_t is_gpu_idle = 0;
1265 LV_VG_LITE_CHECK_ERROR(vg_lite_get_parameter(VG_LITE_GPU_IDLE_STATE, 1, (vg_lite_pointer)&is_gpu_idle));
1266 if(!is_gpu_idle) {
1267 /* Do not flush if GPU is busy */
1268 LV_PROFILER_DRAW_END;
1269 return;
1270 }
1271 #endif
1272
1273 LV_VG_LITE_CHECK_ERROR(vg_lite_flush());
1274 u->flush_count = 0;
1275 LV_PROFILER_DRAW_END;
1276 }
1277
lv_vg_lite_finish(struct _lv_draw_vg_lite_unit_t * u)1278 void lv_vg_lite_finish(struct _lv_draw_vg_lite_unit_t * u)
1279 {
1280 LV_ASSERT_NULL(u);
1281 LV_PROFILER_DRAW_BEGIN;
1282
1283 LV_VG_LITE_CHECK_ERROR(vg_lite_finish());
1284
1285 /* Clear all gradient caches reference */
1286 if(u->grad_pending) {
1287 lv_vg_lite_pending_remove_all(u->grad_pending);
1288 }
1289
1290 /* Clear image decoder dsc reference */
1291 lv_vg_lite_pending_remove_all(u->image_dsc_pending);
1292 u->flush_count = 0;
1293 u->letter_count = 0;
1294 LV_PROFILER_DRAW_END;
1295 }
1296
1297 /**********************
1298 * STATIC FUNCTIONS
1299 **********************/
1300
image_dsc_free_cb(void * dsc,void * user_data)1301 static void image_dsc_free_cb(void * dsc, void * user_data)
1302 {
1303 LV_UNUSED(user_data);
1304 lv_image_decoder_close(dsc);
1305 }
1306
1307 #endif /*LV_USE_DRAW_VG_LITE*/
1308