Files
STM32F4-Base/Lib/lvgl/src/draw/lv_draw.h
T
2026-08-30 08:57:07 +08:00

333 lines
10 KiB
C

/**
* @file lv_draw.h
*
*/
/**
* Modified by NXP in 2024
*/
#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 "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_LETTER,
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,
#if LV_USE_VECTOR_GRAPHIC
LV_DRAW_TASK_TYPE_VECTOR,
#endif
#if LV_USE_3DTEXTURE
LV_DRAW_TASK_TYPE_3D,
#endif
} 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;
/**
* The physical clipping area relative to the display.
*/
lv_area_t phy_clip_area;
#if LV_DRAW_TRANSFORM_USE_MATRIX
/** Transform matrix to be applied when rendering the layer */
lv_matrix_t matrix;
#endif
/** Opacity of the layer */
lv_opa_t opa;
/*Recolor of the layer*/
lv_color32_t recolor;
/** Partial y offset */
int32_t partial_y_offset;
/** 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 {
/**The widget for which draw descriptor was created */
lv_obj_t * obj;
/**The widget part for which draw descriptor was created */
lv_part_t part;
/**A widget type specific ID (e.g. table row index). See the docs of the given widget.*/
uint32_t id1;
/**A widget type specific ID (e.g. table column index). See the docs of the given widget.*/
uint32_t id2;
/**The target layer */
lv_layer_t * layer;
/**Size of the specific draw descriptor into which this base descriptor is embedded*/
size_t dsc_size;
/**Any custom user data*/
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, lv_draw_task_type_t type);
/**
* 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);
/**
* Wait for draw finish in case of asynchronous task execution.
* If `LV_USE_OS == 0` it just return.
*/
void lv_draw_wait_for_finish(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);
/**
* Get the total number of draw units.
*/
uint32_t lv_draw_get_unit_count(void);
/**
* If there is only one draw unit check the first draw task if it's available.
* If there are multiple draw units call `lv_draw_get_next_available_task` to find a task.
* @param layer the draw layer 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 an available draw task or NULL if there is not any
*/
lv_draw_task_t * lv_draw_get_available_task(lv_layer_t * layer, lv_draw_task_t * t_prev, uint8_t draw_unit_id);
/**
* Find and available draw task
* @param layer the draw layer 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 an available draw task or NULL if there is not 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);
/**
* Initialize a layer
* @param layer pointer to a layer to initialize
*/
void lv_layer_init(lv_layer_t * layer);
/**
* Reset the layer to a drawable state
* @param layer pointer to a layer to reset
*/
void lv_layer_reset(lv_layer_t * layer);
/**
* Create (allocate) 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);
/**
* Initialize a layer which is allocated by the user
* @param layer pointer the layer to initialize (its lifetime needs to be managed by the user)
* @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
*/
void lv_draw_layer_init(lv_layer_t * layer, 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
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_DRAW_H*/