App:Library:LVGL:docs:Porting:Add custom GPU
https://docs.lvgl.io/8.2/porting/gpu.html
Add custom GPU
LVGL has a flexible and extendable draw pipeline.
You can hook it to do some rendering with a GPU or even completely replace the built-in software renderer.
Draw context
The core structure of drawing is lv_draw_ctx_t. It contains a pointer to a buffer where drawing should happen and a couple of callbacks to draw rectangles, texts, and other primitives.
Fields
lv_draw_ctx_t has the following fields:
void * bufPointer to a buffer to draw intolv_area_t * buf_areaThe position and size ofbuf(absolute coordinates)const lv_area_t * clip_areaThe current clip area with absolute coordinates, always the same or smaller thanbuf_area. All drawings should be clipped to this area.void (*draw_rect)()Draw a rectangle with shadow, gradient, border, etc.void (*draw_arc)()Draw an arcvoid (*draw_img_decoded)()Draw an (A)RGB image that is already decoded by LVGL.lv_res_t (*draw_img)()Draw an image before decoding it (it bypasses LVGL's internal image decoders)void (*draw_letter)()Draw a lettervoid (*draw_line)()Draw a linevoid (*draw_polygon)()Draw a polygonvoid (*draw_bg)()Replace the buffer with a rect without decoration like radius or borders.void (*wait_for_finish)()Wait until all background operation are finished. (E.g. GPU operations)void * user_dataCustom user data for arbitrary purpose
(For the sake of simplicity the parameters of the callbacks are not shown here.)
All draw_* callbacks receive a pointer to the current draw_ctx as their first parameter. Among the other parameters there is a descriptor that tells what to draw, e.g. for draw_rect it's called lv_draw_rect_dsc_t, for lv_draw_line it's called lv_draw_line_dsc_t, etc.
To correctly render according to a draw_dsc you need to be familiar with the Boxing model of LVGL and the meanings of the fields. The name and meaning of the fields are identical to name and meaning of the Style properties.
Initialization
The lv_disp_drv_t has 4 fields related to the draw context:
lv_draw_ctx_t * draw_ctxPointer to thedraw_ctxof this displayvoid (*draw_ctx_init)(struct _lv_disp_drv_t * disp_drv, lv_draw_ctx_t * draw_ctx)Callback to initialize adraw_ctxvoid (*draw_ctx_deinit)(struct _lv_disp_drv_t * disp_drv, lv_draw_ctx_t * draw_ctx)Callback to de-initialize adraw_ctxsize_t draw_ctx_sizeSize of the draw context structure. E.g.sizeof(lv_draw_sw_ctx_t)
When you ignore these fields, LVGL will set default values for callbacks and size in lv_disp_drv_init() based on the configuration in lv_conf.h. lv_disp_drv_register() will allocate a draw_ctx based on draw_ctx_size and call draw_ctx_init() on it.
However, you can overwrite the callbacks and the size values before calling lv_disp_drv_register(). It makes it possible to use your own draw_ctx with your own callbacks.