1 /**
2  * @file lv_draw.h
3  *
4  */
5 
6 /**
7  * Modified by NXP in 2024
8  */
9 
10 #ifndef LV_DRAW_H
11 #define LV_DRAW_H
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 /*********************
18  *      INCLUDES
19  *********************/
20 #include "../lv_conf_internal.h"
21 
22 #include "../misc/lv_types.h"
23 #include "../misc/lv_style.h"
24 #include "../misc/lv_text.h"
25 #include "../misc/lv_profiler.h"
26 #include "../misc/lv_matrix.h"
27 #include "lv_image_decoder.h"
28 #include "lv_draw_buf.h"
29 
30 /*********************
31  *      DEFINES
32  *********************/
33 #define LV_DRAW_UNIT_NONE  0
34 #define LV_DRAW_UNIT_IDLE  -1   /**< The draw unit is idle, new dispatching might be requested to try again */
35 
36 #if LV_DRAW_TRANSFORM_USE_MATRIX
37 #if !LV_USE_MATRIX
38 #error "LV_DRAW_TRANSFORM_USE_MATRIX requires LV_USE_MATRIX = 1"
39 #endif
40 #endif
41 
42 /**********************
43  *      TYPEDEFS
44  **********************/
45 
46 typedef enum {
47     LV_DRAW_TASK_TYPE_NONE = 0,
48     LV_DRAW_TASK_TYPE_FILL,
49     LV_DRAW_TASK_TYPE_BORDER,
50     LV_DRAW_TASK_TYPE_BOX_SHADOW,
51     LV_DRAW_TASK_TYPE_LETTER,
52     LV_DRAW_TASK_TYPE_LABEL,
53     LV_DRAW_TASK_TYPE_IMAGE,
54     LV_DRAW_TASK_TYPE_LAYER,
55     LV_DRAW_TASK_TYPE_LINE,
56     LV_DRAW_TASK_TYPE_ARC,
57     LV_DRAW_TASK_TYPE_TRIANGLE,
58     LV_DRAW_TASK_TYPE_MASK_RECTANGLE,
59     LV_DRAW_TASK_TYPE_MASK_BITMAP,
60     LV_DRAW_TASK_TYPE_VECTOR,
61 } lv_draw_task_type_t;
62 
63 typedef enum {
64     LV_DRAW_TASK_STATE_WAITING,     /*Waiting for something to be finished. E.g. rendering a layer*/
65     LV_DRAW_TASK_STATE_QUEUED,
66     LV_DRAW_TASK_STATE_IN_PROGRESS,
67     LV_DRAW_TASK_STATE_READY,
68 } lv_draw_task_state_t;
69 
70 struct _lv_layer_t  {
71 
72     /** Target draw buffer of the layer*/
73     lv_draw_buf_t * draw_buf;
74 
75     /** The absolute coordinates of the buffer */
76     lv_area_t buf_area;
77 
78     /** The color format of the layer. LV_COLOR_FORMAT_...  */
79     lv_color_format_t color_format;
80 
81     /**
82      * NEVER USE IT DRAW UNITS. USED INTERNALLY DURING DRAW TASK CREATION.
83      * The current clip area with absolute coordinates, always the same or smaller than `buf_area`
84      * Can be set before new draw tasks are added to indicate the clip area of the draw tasks.
85      * Therefore `lv_draw_add_task()` always saves it in the new draw task to know the clip area when the draw task was added.
86      * During drawing the draw units also sees the saved clip_area and should use it during drawing.
87      * During drawing the layer's clip area shouldn't be used as it might be already changed for other draw tasks.
88      */
89     lv_area_t _clip_area;
90 
91     /**
92      * The physical clipping area relative to the display.
93      */
94     lv_area_t phy_clip_area;
95 
96 #if LV_DRAW_TRANSFORM_USE_MATRIX
97     /** Transform matrix to be applied when rendering the layer */
98     lv_matrix_t matrix;
99 #endif
100 
101     /** Opacity of the layer */
102     lv_opa_t opa;
103 
104     /** Linked list of draw tasks */
105     lv_draw_task_t * draw_task_head;
106 
107     lv_layer_t * parent;
108     lv_layer_t * next;
109     bool all_tasks_added;
110     void * user_data;
111 };
112 
113 typedef struct {
114     lv_obj_t * obj;
115     lv_part_t part;
116     uint32_t id1;
117     uint32_t id2;
118     lv_layer_t * layer;
119     size_t dsc_size;
120     void * user_data;
121 } lv_draw_dsc_base_t;
122 
123 /**********************
124  * GLOBAL PROTOTYPES
125  **********************/
126 
127 /**
128  * Used internally to initialize the drawing module
129  */
130 void lv_draw_init(void);
131 
132 /**
133  * Deinitialize the drawing module
134  */
135 void lv_draw_deinit(void);
136 
137 /**
138  * Allocate a new draw unit with the given size and appends it to the list of draw units
139  * @param size      the size to allocate. E.g. `sizeof(my_draw_unit_t)`,
140  *                  where the first element of `my_draw_unit_t` is `lv_draw_unit_t`.
141  */
142 void * lv_draw_create_unit(size_t size);
143 
144 /**
145  * Add an empty draw task to the draw task list of a layer.
146  * @param layer     pointer to a layer
147  * @param coords    the coordinates of the draw task
148  * @return          the created draw task which needs to be
149  *                  further configured e.g. by added a draw descriptor
150  */
151 lv_draw_task_t * lv_draw_add_task(lv_layer_t * layer, const lv_area_t * coords);
152 
153 /**
154  * Needs to be called when a draw task is created and configured.
155  * It will send an event about the new draw task to the widget
156  * and assign it to a draw unit.
157  * @param layer     pointer to a layer
158  * @param t         pointer to a draw task
159  */
160 void lv_draw_finalize_task_creation(lv_layer_t * layer, lv_draw_task_t * t);
161 
162 /**
163  * Try dispatching draw tasks to draw units
164  */
165 void lv_draw_dispatch(void);
166 
167 /**
168  * Used internally to try dispatching draw tasks of a specific layer
169  * @param disp      pointer to a display on which the dispatching was requested
170  * @param layer     pointer to a layer
171  * @return          at least one draw task is being rendered (maybe it was taken earlier)
172  */
173 bool lv_draw_dispatch_layer(lv_display_t * disp, lv_layer_t * layer);
174 
175 /**
176  * Wait for a new dispatch request.
177  * It's blocking if `LV_USE_OS == 0` else it yields
178  */
179 void lv_draw_dispatch_wait_for_request(void);
180 
181 /**
182  * Wait for draw finish in case of asynchronous task execution.
183  * If `LV_USE_OS == 0` it just return.
184  */
185 void lv_draw_wait_for_finish(void);
186 
187 /**
188  * When a draw unit finished a draw task it needs to request dispatching
189  * to let LVGL assign a new draw task to it
190  */
191 void lv_draw_dispatch_request(void);
192 
193 /**
194  * Get the total number of draw units.
195   */
196 uint32_t lv_draw_get_unit_count(void);
197 
198 /**
199  * Find and available draw task
200  * @param layer             the draw ctx to search in
201  * @param t_prev            continue searching from this task
202  * @param draw_unit_id      check the task where `preferred_draw_unit_id` equals this value or `LV_DRAW_UNIT_NONE`
203  * @return                  tan available draw task or NULL if there is no any
204  */
205 lv_draw_task_t * lv_draw_get_next_available_task(lv_layer_t * layer, lv_draw_task_t * t_prev, uint8_t draw_unit_id);
206 
207 /**
208  * Tell how many draw task are waiting to be drawn on the area of `t_check`.
209  * It can be used to determine if a GPU shall combine many draw tasks into one or not.
210  * If a lot of tasks are waiting for the current ones it makes sense to draw them one-by-one
211  * to not block the dependent tasks' rendering
212  * @param t_check   the task whose dependent tasks shall be counted
213  * @return          number of tasks depending on `t_check`
214  */
215 uint32_t lv_draw_get_dependent_count(lv_draw_task_t * t_check);
216 
217 /**
218  * Initialize a layer
219  * @param layer pointer to a layer to initialize
220  */
221 void lv_layer_init(lv_layer_t * layer);
222 
223 /**
224  * Reset the layer to a drawable state
225  * @param layer pointer to a layer to reset
226  */
227 void lv_layer_reset(lv_layer_t * layer);
228 
229 /**
230  * Create (allocate) a new layer on a parent layer
231  * @param parent_layer      the parent layer to which the layer will be merged when it's rendered
232  * @param color_format      the color format of the layer
233  * @param area              the areas of the layer (absolute coordinates)
234  * @return                  the new target_layer or NULL on error
235  */
236 lv_layer_t * lv_draw_layer_create(lv_layer_t * parent_layer, lv_color_format_t color_format, const lv_area_t * area);
237 
238 /**
239  * Initialize a layer which is allocated by the user
240  * @param layer             pointer the layer to initialize (its lifetime needs to be managed by the user)
241  * @param parent_layer      the parent layer to which the layer will be merged when it's rendered
242  * @param color_format      the color format of the layer
243  * @param area              the areas of the layer (absolute coordinates)
244  * @return                  the new target_layer or NULL on error
245  */
246 void lv_draw_layer_init(lv_layer_t * layer, lv_layer_t * parent_layer, lv_color_format_t color_format,
247                         const lv_area_t * area);
248 
249 /**
250  * Try to allocate a buffer for the layer.
251  * @param layer             pointer to a layer
252  * @return                  pointer to the allocated aligned buffer or NULL on failure
253  */
254 void * lv_draw_layer_alloc_buf(lv_layer_t * layer);
255 
256 /**
257  * Got to a pixel at X and Y coordinate on a layer
258  * @param layer             pointer to a layer
259  * @param x                 the target X coordinate
260  * @param y                 the target X coordinate
261  * @return                  `buf` offset to point to the given X and Y coordinate
262  */
263 void * lv_draw_layer_go_to_xy(lv_layer_t * layer, int32_t x, int32_t y);
264 
265 /**
266  * Get the type of a draw task
267  * @param t   the draw task to get the type of
268  * @return    the draw task type
269 */
270 lv_draw_task_type_t lv_draw_task_get_type(const lv_draw_task_t * t);
271 
272 /**
273  * Get the draw descriptor of a draw task
274  * @param t   the draw task to get the draw descriptor of
275  * @return    a void pointer to the draw descriptor
276 */
277 void * lv_draw_task_get_draw_dsc(const lv_draw_task_t * t);
278 
279 /**
280  * Get the draw area of a draw task
281  * @param t      the draw task to get the draw area of
282  * @param area   the destination where the draw area will be stored
283 */
284 void lv_draw_task_get_area(const lv_draw_task_t * t, lv_area_t * area);
285 
286 /**********************
287  *  GLOBAL VARIABLES
288  **********************/
289 
290 /**********************
291  *      MACROS
292  **********************/
293 
294 #ifdef __cplusplus
295 } /*extern "C"*/
296 #endif
297 
298 #endif /*LV_DRAW_H*/
299