1 /**
2  * @file lv_hal_disp.h
3  *
4  * @description Display Driver HAL interface header file
5  *
6  */
7 
8 #ifndef LV_HAL_DISP_H
9 #define LV_HAL_DISP_H
10 
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14 
15 /*********************
16  *      INCLUDES
17  *********************/
18 #include <stdint.h>
19 #include <stdbool.h>
20 #include "lv_hal.h"
21 #include "../lv_misc/lv_color.h"
22 #include "../lv_misc/lv_area.h"
23 #include "../lv_misc/lv_ll.h"
24 #include "../lv_misc/lv_task.h"
25 
26 /*********************
27  *      DEFINES
28  *********************/
29 #ifndef LV_INV_BUF_SIZE
30 #define LV_INV_BUF_SIZE 32 /*Buffer size for invalid areas */
31 #endif
32 
33 #ifndef LV_ATTRIBUTE_FLUSH_READY
34 #define LV_ATTRIBUTE_FLUSH_READY
35 #endif
36 
37 /**********************
38  *      TYPEDEFS
39  **********************/
40 
41 struct _disp_t;
42 struct _disp_drv_t;
43 
44 /**
45  * Structure for holding display buffer information.
46  */
47 typedef struct
48 {
49     void * buf1; /**< First display buffer. */
50     void * buf2; /**< Second display buffer. */
51 
52     /*Internal, used by the library*/
53     void * buf_act;
54     uint32_t size; /*In pixel count*/
55     lv_area_t area;
56     volatile uint32_t flushing : 1;
57 } lv_disp_buf_t;
58 
59 /**
60  * Display Driver structure to be registered by HAL
61  */
62 typedef struct _disp_drv_t
63 {
64 
65     lv_coord_t hor_res; /**< Horizontal resolution. */
66     lv_coord_t ver_res; /**< Vertical resolution. */
67 
68     /** Pointer to a buffer initialized with `lv_disp_buf_init()`.
69      * LittlevGL will use this buffer(s) to draw the screens contents */
70     lv_disp_buf_t * buffer;
71 
72 #if LV_ANTIALIAS
73     uint32_t antialiasing : 1; /**< 1: antialiasing is enabled on this display. */
74 #endif
75     uint32_t rotated : 1; /**< 1: turn the display by 90 degree. @warning Does not update coordinates for you!*/
76 
77 #if LV_COLOR_SCREEN_TRANSP
78     /**Handle if the the screen doesn't have a solid (opa == LV_OPA_COVER) background.
79      * Use only if required because it's slower.*/
80     uint32_t screen_transp : 1;
81 #endif
82 
83     /** MANDATORY: Write the internal buffer (VDB) to the display. 'lv_disp_flush_ready()' has to be
84      * called when finished */
85     void (*flush_cb)(struct _disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
86 
87     /** OPTIONAL: Extend the invalidated areas to match with the display drivers requirements
88      * E.g. round `y` to, 8, 16 ..) on a monochrome display*/
89     void (*rounder_cb)(struct _disp_drv_t * disp_drv, lv_area_t * area);
90 
91     /** OPTIONAL: Set a pixel in a buffer according to the special requirements of the display
92      * Can be used for color format not supported in LittelvGL. E.g. 2 bit -> 4 gray scales
93      * @note Much slower then drawing with supported color formats. */
94     void (*set_px_cb)(struct _disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
95                       lv_color_t color, lv_opa_t opa);
96 
97     /** OPTIONAL: Called after every refresh cycle to tell the rendering and flushing time + the
98      * number of flushed pixels */
99     void (*monitor_cb)(struct _disp_drv_t * disp_drv, uint32_t time, uint32_t px);
100 
101 #if LV_USE_GPU
102     /** OPTIONAL: Blend two memories using opacity (GPU only)*/
103     void (*gpu_blend_cb)(struct _disp_drv_t * disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length,
104                          lv_opa_t opa);
105 
106     /** OPTIONAL: Fill a memory with a color (GPU only)*/
107     void (*gpu_fill_cb)(struct _disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
108                         const lv_area_t * fill_area, lv_color_t color);
109 #endif
110 
111     /** On CHROMA_KEYED images this color will be transparent.
112      * `LV_COLOR_TRANSP` by default. (lv_conf.h)*/
113     lv_color_t color_chroma_key;
114 
115 #if LV_USE_USER_DATA
116     lv_disp_drv_user_data_t user_data; /**< Custom display driver user data */
117 #endif
118 
119 } lv_disp_drv_t;
120 
121 struct _lv_obj_t;
122 
123 /**
124  * Display structure.
125  * ::lv_disp_drv_t is the first member of the structure.
126  */
127 typedef struct _disp_t
128 {
129     /**< Driver to the display*/
130     lv_disp_drv_t driver;
131 
132     /**< A task which periodically checks the dirty areas and refreshes them*/
133     lv_task_t * refr_task;
134 
135     /** Screens of the display*/
136     lv_ll_t scr_ll;
137     struct _lv_obj_t * act_scr; /**< Currently active screen on this display */
138     struct _lv_obj_t * top_layer; /**< @see lv_disp_get_layer_top */
139     struct _lv_obj_t * sys_layer; /**< @see lv_disp_get_layer_sys */
140 
141     /** Invalidated (marked to redraw) areas*/
142     lv_area_t inv_areas[LV_INV_BUF_SIZE];
143     uint8_t inv_area_joined[LV_INV_BUF_SIZE];
144     uint32_t inv_p : 10;
145 
146     /*Miscellaneous data*/
147     uint32_t last_activity_time; /**< Last time there was activity on this display */
148 } lv_disp_t;
149 
150 /**********************
151  * GLOBAL PROTOTYPES
152  **********************/
153 
154 /**
155  * Initialize a display driver with default values.
156  * It is used to have known values in the fields and not junk in memory.
157  * After it you can safely set only the fields you need.
158  * @param driver pointer to driver variable to initialize
159  */
160 void lv_disp_drv_init(lv_disp_drv_t * driver);
161 
162 /**
163  * Initialize a display buffer
164  * @param disp_buf pointer `lv_disp_buf_t` variable to initialize
165  * @param buf1 A buffer to be used by LittlevGL to draw the image.
166  *             Always has to specified and can't be NULL.
167  *             Can be an array allocated by the user. E.g. `static lv_color_t disp_buf1[1024 * 10]`
168  *             Or a memory address e.g. in external SRAM
169  * @param buf2 Optionally specify a second buffer to make image rendering and image flushing
170  *             (sending to the display) parallel.
171  *             In the `disp_drv->flush` you should use DMA or similar hardware to send
172  *             the image to the display in the background.
173  *             It lets LittlevGL to render next frame into the other buffer while previous is being
174  * sent. Set to `NULL` if unused.
175  * @param size_in_px_cnt size of the `buf1` and `buf2` in pixel count.
176  */
177 void lv_disp_buf_init(lv_disp_buf_t * disp_buf, void * buf1, void * buf2, uint32_t size_in_px_cnt);
178 
179 /**
180  * Register an initialized display driver.
181  * Automatically set the first display as active.
182  * @param driver pointer to an initialized 'lv_disp_drv_t' variable (can be local variable)
183  * @return pointer to the new display or NULL on error
184  */
185 lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver);
186 
187 /**
188  * Update the driver in run time.
189  * @param disp pointer to a display. (return value of `lv_disp_drv_register`)
190  * @param new_drv pointer to the new driver
191  */
192 void lv_disp_drv_update(lv_disp_t * disp, lv_disp_drv_t * new_drv);
193 
194 /**
195  * Remove a display
196  * @param disp pointer to display
197  */
198 void lv_disp_remove(lv_disp_t * disp);
199 
200 /**
201  * Set a default screen. The new screens will be created on it by default.
202  * @param disp pointer to a display
203  */
204 void lv_disp_set_default(lv_disp_t * disp);
205 
206 /**
207  * Get the default display
208  * @return pointer to the default display
209  */
210 lv_disp_t * lv_disp_get_default(void);
211 
212 /**
213  * Get the horizontal resolution of a display
214  * @param disp pointer to a display (NULL to use the default display)
215  * @return the horizontal resolution of the display
216  */
217 lv_coord_t lv_disp_get_hor_res(lv_disp_t * disp);
218 
219 /**
220  * Get the vertical resolution of a display
221  * @param disp pointer to a display (NULL to use the default display)
222  * @return the vertical resolution of the display
223  */
224 lv_coord_t lv_disp_get_ver_res(lv_disp_t * disp);
225 
226 /**
227  * Get if anti-aliasing is enabled for a display or not
228  * @param disp pointer to a display (NULL to use the default display)
229  * @return true: anti-aliasing is enabled; false: disabled
230  */
231 bool lv_disp_get_antialiasing(lv_disp_t * disp);
232 
233 //! @cond Doxygen_Suppress
234 
235 /**
236  * Call in the display driver's `flush_cb` function when the flushing is finished
237  * @param disp_drv pointer to display driver in `flush_cb` where this function is called
238  */
239 LV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_drv_t * disp_drv);
240 
241 //! @endcond
242 
243 /**
244  * Get the next display.
245  * @param disp pointer to the current display. NULL to initialize.
246  * @return the next display or NULL if no more. Give the first display when the parameter is NULL
247  */
248 lv_disp_t * lv_disp_get_next(lv_disp_t * disp);
249 
250 /**
251  * Get the internal buffer of a display
252  * @param disp pointer to a display
253  * @return pointer to the internal buffers
254  */
255 lv_disp_buf_t * lv_disp_get_buf(lv_disp_t * disp);
256 
257 /**
258  * Get the number of areas in the buffer
259  * @return number of invalid areas
260  */
261 uint16_t lv_disp_get_inv_buf_size(lv_disp_t * disp);
262 
263 /**
264  * Pop (delete) the last 'num' invalidated areas from the buffer
265  * @param num number of areas to delete
266  */
267 void lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num);
268 
269 /**
270  * Check the driver configuration if it's double buffered (both `buf1` and `buf2` are set)
271  * @param disp pointer to to display to check
272  * @return true: double buffered; false: not double buffered
273  */
274 bool lv_disp_is_double_buf(lv_disp_t * disp);
275 
276 /**
277  * Check the driver configuration if it's TRUE double buffered (both `buf1` and `buf2` are set and
278  * `size` is screen sized)
279  * @param disp pointer to to display to check
280  * @return true: double buffered; false: not double buffered
281  */
282 bool lv_disp_is_true_double_buf(lv_disp_t * disp);
283 
284 /**********************
285  *      MACROS
286  **********************/
287 
288 #ifdef __cplusplus
289 } /* extern "C" */
290 #endif
291 
292 #endif
293