mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-14 06:42:58 +08:00
feat(draw): add layer memory allocation config support (#7038)
Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com> Co-authored-by: liamHowatt <liamjmh0@gmail.com> Co-authored-by: Liam <30486941+liamHowatt@users.noreply.github.com>
This commit is contained in:
parent
c022f0896a
commit
a7adce9d1a
9
Kconfig
9
Kconfig
@ -202,6 +202,15 @@ menu "LVGL configuration"
|
||||
it is buffered into a "simple" layer before rendering. The widget can be buffered in smaller chunks.
|
||||
"Transformed layers" (if `transform_angle/zoom` are set) use larger buffers and can't be drawn in chunks.
|
||||
|
||||
config LV_DRAW_LAYER_MAX_MEMORY
|
||||
int "The maximum amount of memory that can be used for layers"
|
||||
default 0
|
||||
help
|
||||
Limit the max allocated memory for simple and transformed layers.
|
||||
It should be at least `LV_DRAW_LAYER_SIMPLE_BUF_SIZE` sized but if transformed layers are also used
|
||||
it should be enough to store the largest widget too (width x height x 4 area).
|
||||
Set it to 0 to have no limit.
|
||||
|
||||
config LV_DRAW_THREAD_STACK_SIZE
|
||||
int "Stack size of draw thread in bytes"
|
||||
default 8192
|
||||
|
@ -144,6 +144,12 @@
|
||||
/** The target buffer size for simple layer chunks. */
|
||||
#define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (24 * 1024) /**< [bytes]*/
|
||||
|
||||
/* Limit the max allocated memory for simple and transformed layers.
|
||||
* It should be at least `LV_DRAW_LAYER_SIMPLE_BUF_SIZE` sized but if transformed layers are also used
|
||||
* it should be enough to store the largest widget too (width x height x 4 area).
|
||||
* Set it to 0 to have no limit. */
|
||||
#define LV_DRAW_LAYER_MAX_MEMORY 0 /**< No limit by default [bytes]*/
|
||||
|
||||
/** Stack size of drawing thread.
|
||||
* NOTE: If FreeType or ThorVG is enabled, it is recommended to set it to 32KB or more.
|
||||
*/
|
||||
|
@ -36,7 +36,7 @@ static void lv_cleanup_task(lv_draw_task_t * t, lv_display_t * disp);
|
||||
|
||||
static inline uint32_t get_layer_size_kb(uint32_t size_byte)
|
||||
{
|
||||
return size_byte < 1024 ? 1 : size_byte >> 10;
|
||||
return (size_byte + 1023) >> 10;
|
||||
}
|
||||
|
||||
/**********************
|
||||
@ -448,6 +448,15 @@ void * lv_draw_layer_alloc_buf(lv_layer_t * layer)
|
||||
int32_t h = lv_area_get_height(&layer->buf_area);
|
||||
uint32_t layer_size_byte = h * lv_draw_buf_width_to_stride(w, layer->color_format);
|
||||
|
||||
#if LV_DRAW_LAYER_MAX_MEMORY > 0
|
||||
/* Do not allocate the layer if the sum of allocated layer sizes
|
||||
* will exceed `LV_DRAW_LAYER_MAX_MEMORY` */
|
||||
if((_draw_info.used_memory_for_layers + layer_size_byte) > LV_DRAW_LAYER_MAX_MEMORY) {
|
||||
LV_LOG_WARN("LV_DRAW_LAYER_MAX_MEMORY was reached when allocating the layer.");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
layer->draw_buf = lv_draw_buf_create(w, h, layer->color_format, 0);
|
||||
|
||||
if(layer->draw_buf == NULL) {
|
||||
@ -456,8 +465,8 @@ void * lv_draw_layer_alloc_buf(lv_layer_t * layer)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_draw_info.used_memory_for_layers_kb += get_layer_size_kb(layer_size_byte);
|
||||
LV_LOG_INFO("Layer memory used: %" LV_PRIu32 " kB\n", _draw_info.used_memory_for_layers_kb);
|
||||
_draw_info.used_memory_for_layers += layer_size_byte;
|
||||
LV_LOG_INFO("Layer memory used: %" LV_PRIu32 " kB", get_layer_size_kb(_draw_info.used_memory_for_layers));
|
||||
|
||||
if(lv_color_format_has_alpha(layer->color_format)) {
|
||||
lv_draw_buf_clear(layer->draw_buf, NULL);
|
||||
@ -535,8 +544,14 @@ static void lv_cleanup_task(lv_draw_task_t * t, lv_display_t * disp)
|
||||
int32_t h = lv_area_get_height(&layer_drawn->buf_area);
|
||||
uint32_t layer_size_byte = h * layer_drawn->draw_buf->header.stride;
|
||||
|
||||
_draw_info.used_memory_for_layers_kb -= get_layer_size_kb(layer_size_byte);
|
||||
LV_LOG_INFO("Layer memory used: %" LV_PRIu32 " kB\n", _draw_info.used_memory_for_layers_kb);
|
||||
if(_draw_info.used_memory_for_layers >= layer_size_byte) {
|
||||
_draw_info.used_memory_for_layers -= layer_size_byte;
|
||||
}
|
||||
else {
|
||||
_draw_info.used_memory_for_layers = 0;
|
||||
LV_LOG_WARN("More layers were freed than allocated");
|
||||
}
|
||||
LV_LOG_INFO("Layer memory used: %" LV_PRIu32 " kB", get_layer_size_kb(_draw_info.used_memory_for_layers));
|
||||
lv_draw_buf_destroy(layer_drawn->draw_buf);
|
||||
layer_drawn->draw_buf = NULL;
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ struct _lv_draw_unit_t {
|
||||
typedef struct {
|
||||
lv_draw_unit_t * unit_head;
|
||||
uint32_t unit_cnt;
|
||||
uint32_t used_memory_for_layers_kb;
|
||||
uint32_t used_memory_for_layers; /* measured as bytes */
|
||||
#if LV_USE_OS
|
||||
lv_thread_sync_t sync;
|
||||
#else
|
||||
|
@ -352,6 +352,18 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Limit the max allocated memory for simple and transformed layers.
|
||||
* It should be at least `LV_DRAW_LAYER_SIMPLE_BUF_SIZE` sized but if transformed layers are also used
|
||||
* it should be enough to store the largest widget too (width x height x 4 area).
|
||||
* Set it to 0 to have no limit. */
|
||||
#ifndef LV_DRAW_LAYER_MAX_MEMORY
|
||||
#ifdef CONFIG_LV_DRAW_LAYER_MAX_MEMORY
|
||||
#define LV_DRAW_LAYER_MAX_MEMORY CONFIG_LV_DRAW_LAYER_MAX_MEMORY
|
||||
#else
|
||||
#define LV_DRAW_LAYER_MAX_MEMORY 0 /**< No limit by default [bytes]*/
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** Stack size of drawing thread.
|
||||
* NOTE: If FreeType or ThorVG is enabled, it is recommended to set it to 32KB or more.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user