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