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