1 /**
2  * @file lv_draw_private.h
3  *
4  */
5 
6 /**
7  * Modified by NXP in 2024
8  */
9 
10 #ifndef LV_DRAW_PRIVATE_H
11 #define LV_DRAW_PRIVATE_H
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 /*********************
18  *      INCLUDES
19  *********************/
20 
21 #include "lv_draw.h"
22 #include "../osal/lv_os.h"
23 #include "../misc/cache/lv_cache.h"
24 
25 /*********************
26  *      DEFINES
27  *********************/
28 
29 /**********************
30  *      TYPEDEFS
31  **********************/
32 
33 struct _lv_draw_task_t {
34     lv_draw_task_t * next;
35 
36     lv_draw_task_type_t type;
37 
38     /**
39      * The area where to draw
40      */
41     lv_area_t area;
42 
43     /**
44      * The real draw area. E.g. for shadow, outline, or transformed images it's different from `area`
45      */
46     lv_area_t _real_area;
47 
48     /** The original area which is updated*/
49     lv_area_t clip_area_original;
50 
51     /**
52      * The clip area of the layer is saved here when the draw task is created.
53      * As the clip area of the layer can be changed as new draw tasks are added its current value needs to be saved.
54      * Therefore during drawing the layer's clip area shouldn't be used as it might be already changed for other draw tasks.
55      */
56     lv_area_t clip_area;
57 
58 #if LV_DRAW_TRANSFORM_USE_MATRIX
59     /** Transform matrix to be applied when rendering the layer */
60     lv_matrix_t matrix;
61 #endif
62 
63     volatile int state;              /** int instead of lv_draw_task_state_t to be sure its atomic */
64 
65     void * draw_dsc;
66 
67     /**
68      * The ID of the draw_unit which should take this task
69      */
70     uint8_t preferred_draw_unit_id;
71 
72     /**
73      * Set to which extent `preferred_draw_unit_id` is good at this task.
74      * 80: means 20% better (faster) than software rendering
75      * 100: the default value
76      * 110: means 10% worse (slower) than software rendering
77      */
78     uint8_t preference_score;
79 
80 };
81 
82 struct _lv_draw_mask_t {
83     void * user_data;
84 };
85 
86 struct _lv_draw_unit_t {
87     lv_draw_unit_t * next;
88 
89     /**
90      * The target_layer on which drawing should happen
91      */
92     lv_layer_t * target_layer;
93 
94     const lv_area_t * clip_area;
95 
96     /**
97      * Name of the draw unit, for debugging purposes only.
98      */
99     const char * name;
100 
101     /**
102      * Called to try to assign a draw task to itself.
103      * `lv_draw_get_next_available_task` can be used to get an independent draw task.
104      * A draw task should be assign only if the draw unit can draw it too
105      * @param draw_unit     pointer to the draw unit
106      * @param layer         pointer to a layer on which the draw task should be drawn
107      * @return              >=0:    The number of taken draw task:
108      *                                  0 means the task has not yet been completed.
109      *                                  1 means a new task has been accepted.
110      *                      -1:     The draw unit wanted to work on a task but couldn't do that
111      *                              due to some errors (e.g. out of memory).
112      *                              It signals that LVGL should call the dispatcher later again
113      *                              to let draw unit try to start the rendering again.
114      */
115     int32_t (*dispatch_cb)(lv_draw_unit_t * draw_unit, lv_layer_t * layer);
116 
117     /**
118      *
119      * @param draw_unit
120      * @param task
121      * @return
122      */
123     int32_t (*evaluate_cb)(lv_draw_unit_t * draw_unit, lv_draw_task_t * task);
124 
125     /**
126      * Called to signal the unit to complete all tasks in order to return their ready status.
127      * This callback can be implemented in case of asynchronous task processing.
128      * Below is an example to show the difference between synchronous and asynchronous:
129      *
130      * Synchronous:
131      * LVGL thread              DRAW thread                 HW
132      *
133      * task1             -->    submit               -->    Receive task1
134      *                          wait_for_finish()
135      *                   <--    task1->state = READY <--    Complete task1
136      * task2             -->    submit               -->    Receive task2
137      *                          wait_for_finish()
138      *                          task2->state = READY <--    Complete task2
139      * task3             -->    submit               -->    Receive task3
140      *                          wait_for_finish()
141      *                   <--    task3->state = READY <--    Complete task3
142      * task4             -->    submit               -->    Receive task4
143      *                          wait_for_finish()
144      *                   <--    task4->state = READY <--    Complete task4
145      * NO MORE TASKS
146      *
147      *
148      * Asynchronous:
149      * LVGL thread              DRAW thread                 HW
150      *                                                      is IDLE
151      * task1             -->    queue task1
152      *                          submit               -->    Receive task1
153      * task2             -->    queue task2                 is BUSY (with task1)
154      * task3             -->    queue task3                 still BUSY (with task1)
155      * task4             -->    queue task4                 becomes IDLE
156      *                   <--    task1->state = READY <--    Complete task1
157      *                          submit               -->    Receive task2, task3, task4
158      * NO MORE TASKS
159      * wait_for_finish_cb()     wait_for_finish()
160      *                                               <--    Complete task2, task3, task4
161      *                   <--    task2->state = READY <--
162      *                   <--    task3->state = READY <--
163      *                   <--    task4->state = READY <--
164      *
165      * @param draw_unit
166      * @return
167      */
168     int32_t (*wait_for_finish_cb)(lv_draw_unit_t * draw_unit);
169 
170     /**
171      * Called to delete draw unit.
172      * @param draw_unit
173      * @return
174      */
175     int32_t (*delete_cb)(lv_draw_unit_t * draw_unit);
176 };
177 
178 typedef struct {
179     lv_draw_unit_t * unit_head;
180     uint32_t unit_cnt;
181     uint32_t used_memory_for_layers; /* measured as bytes */
182 #if LV_USE_OS
183     lv_thread_sync_t sync;
184 #else
185     volatile int dispatch_req;
186 #endif
187     lv_mutex_t circle_cache_mutex;
188     bool task_running;
189 } lv_draw_global_info_t;
190 
191 /**********************
192  * GLOBAL PROTOTYPES
193  **********************/
194 
195 /**********************
196  *      MACROS
197  **********************/
198 
199 #ifdef __cplusplus
200 } /*extern "C"*/
201 #endif
202 
203 #endif /*LV_DRAW_PRIVATE_H*/
204