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