diff --git a/Kconfig b/Kconfig
index eac5eb9d48..ca0d8da2c6 100644
--- a/Kconfig
+++ b/Kconfig
@@ -167,6 +167,36 @@ menu "LVGL configuration"
save the continuous open/decode of images.
However the opened images might consume additional RAM.
+ config LV_GRADIENT_MAX_STOPS
+ int "Number of stops allowed per gradient."
+ default 2
+ help
+ Increase this to allow more stops.
+ This adds (sizeof(lv_color_t) + 1) bytes per additional stop
+
+ config LV_GRAD_CACHE_DEF_SIZE
+ int "Default gradient buffer size."
+ default 0
+ help
+ When LVGL calculates the gradient "maps" it can save them into a cache to avoid calculating them again.
+ LV_GRAD_CACHE_DEF_SIZE sets the size of this cache in bytes.
+ If the cache is too small the map will be allocated only while it's required for the drawing.
+ 0 mean no caching.
+
+ config LV_DITHER_GRADIENT
+ bool "Allow dithering the gradients"
+ help
+ Allow dithering the gradients (to achieve visual smooth color gradients on limited color depth display)
+ LV_DITHER_GRADIENT implies allocating one or two more lines of the object's rendering surface
+ The increase in memory consumption is (32 bits * object width) plus 24 bits * object width if using error diffusion
+
+ config LV_DITHER_ERROR_DIFFUSION
+ bool "Add support for error diffusion dithering"
+ depends on LV_DITHER_GRADIENT
+ help
+ Error diffusion dithering gets a much better visual result, but implies more CPU consumption and memory when drawing.
+ The increase in memory consumption is (24 bits * object's width)
+
config LV_DISP_ROT_MAX_BUF
int "Maximum buffer size to allocate for rotation"
default 10240
diff --git a/docs/overview/style-props.md b/docs/overview/style-props.md
index 12a4869821..3eeaa8dd01 100644
--- a/docs/overview/style-props.md
+++ b/docs/overview/style-props.md
@@ -252,8 +252,8 @@ Set the point from which the background's gradient color should start. 0 means t
Ext. draw No
-### bg_gradient
-Set the gradient definition for the body. The pointed instance must exist while the object is alive. NULL to disable
+### bg_grad
+Set the gradient definition. The pointed instance must exist while the object is alive. NULL to disable. It wraps `BG_GRAD_COLOR`, `BG_GRAD_DIR`, `BG_MAIN_STOP` and `BG_GRAD_STOP` into one descriptor and allows craeting gradients with more colors too.
- Default `NULL`
- Inherited No
diff --git a/examples/styles/lv_example_style_2.c b/examples/styles/lv_example_style_2.c
index 1ceb369edd..125fcb50c5 100644
--- a/examples/styles/lv_example_style_2.c
+++ b/examples/styles/lv_example_style_2.c
@@ -12,7 +12,7 @@ void lv_example_style_2(void)
/*Make a gradient*/
lv_style_set_bg_opa(&style, LV_OPA_COVER);
- static lv_gradient_t grad;
+ static lv_grad_dsc_t grad;
grad.dir = LV_GRAD_DIR_VER;
grad.stops_count = 2;
grad.stops[0].color = lv_palette_lighten(LV_PALETTE_GREY, 1);
@@ -22,7 +22,7 @@ void lv_example_style_2(void)
grad.stops[0].frac = 128;
grad.stops[1].frac = 192;
- lv_style_set_bg_gradient(&style, &grad);
+ lv_style_set_bg_grad(&style, &grad);
/*Create an object with the new style*/
lv_obj_t * obj = lv_obj_create(lv_scr_act());
diff --git a/lv_conf_template.h b/lv_conf_template.h
index 00a518a69a..95707e55ec 100644
--- a/lv_conf_template.h
+++ b/lv_conf_template.h
@@ -118,21 +118,6 @@
* radius * 4 bytes are used per circle (the most often used radiuses are saved)
* 0: to disable caching */
#define LV_CIRCLE_CACHE_SIZE 4
-
- /*Allow dithering gradient (to achieve visual smooth color gradients on limited color depth display)
- *LV_DITHER_GRADIENT implies allocating one or two more lines of the object's rendering surface
- *The increase in memory consumption is (32 bits * object width) plus 24 bits * object width if using error diffusion */
- #define LV_DITHER_GRADIENT 1
-
- /*Add support for error diffusion dithering.
- *Error diffusion dithering gets a much better visual result, but implies more CPU consumption and memory when drawing.
- *The increase in memory consumption is (24 bits * object's width)*/
- #define LV_DITHER_ERROR_DIFFUSION 1
-
- /**Number of stops allowed per gradient. Increase this to allow more stops.
- *This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/
- #define LV_GRADIENT_MAX_STOPS 2
-
#endif /*LV_DRAW_COMPLEX*/
/*Default image cache size. Image caching keeps the images opened.
@@ -140,9 +125,32 @@
*With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images.
*However the opened images might consume additional RAM.
*0: to disable caching*/
-#define LV_IMG_CACHE_DEF_SIZE 0
+#define LV_IMG_CACHE_DEF_SIZE 0
-/*Maximum buffer size to allocate for rotation. Only used if software rotation is enabled in the display driver.*/
+/*Number of stops allowed per gradient. Increase this to allow more stops.
+ *This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/
+#define LV_GRADIENT_MAX_STOPS 2
+
+/*Default gradient buffer size.
+ *When LVGL calculates the gradient "maps" it can save them into a cache to avoid calculating them again.
+ *LV_GRAD_CACHE_DEF_SIZE sets the size of this cache in bytes.
+ *If the cache is too small the map will be allocated only while it's required for the drawing.
+ *0 mean no caching.*/
+#define LV_GRAD_CACHE_DEF_SIZE 0
+
+/*Allow dithering the gradients (to achieve visual smooth color gradients on limited color depth display)
+ *LV_DITHER_GRADIENT implies allocating one or two more lines of the object's rendering surface
+ *The increase in memory consumption is (32 bits * object width) plus 24 bits * object width if using error diffusion */
+#define LV_DITHER_GRADIENT 0
+#if LV_DITHER_GRADIENT
+ /*Add support for error diffusion dithering.
+ *Error diffusion dithering gets a much better visual result, but implies more CPU consumption and memory when drawing.
+ *The increase in memory consumption is (24 bits * object's width)*/
+ #define LV_DITHER_ERROR_DIFFUSION 0
+#endif
+
+/*Maximum buffer size to allocate for rotation.
+ *Only used if software rotation is enabled in the display driver.*/
#define LV_DISP_ROT_MAX_BUF (10*1024)
/*-------------
diff --git a/scripts/style_api_gen.py b/scripts/style_api_gen.py
index fec31f3ac6..699fbe31bf 100755
--- a/scripts/style_api_gen.py
+++ b/scripts/style_api_gen.py
@@ -120,9 +120,9 @@ props = [
'style_type': 'num', 'var_type': 'lv_coord_t', 'default':255, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
'dsc': "Set the point from which the background's gradient color should start. 0 means to top/left side, 255 the bottom/right side, 128 the center, and so on"},
-{'name': 'BG_GRADIENT',
- 'style_type': 'ptr', 'var_type': 'const lv_gradient_t *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
- 'dsc': "Set the gradient definition for the body. The pointed instance must exist while the object is alive. NULL to disable"},
+{'name': 'BG_GRAD',
+ 'style_type': 'ptr', 'var_type': 'const lv_grad_dsc_t *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
+ 'dsc': "Set the gradient definition. The pointed instance must exist while the object is alive. NULL to disable. It wraps `BG_GRAD_COLOR`, `BG_GRAD_DIR`, `BG_MAIN_STOP` and `BG_GRAD_STOP` into one descriptor and allows creating gradients with more colors too."},
{'name': 'BG_DITHER_MODE',
'style_type': 'num', 'var_type': 'lv_dither_mode_t', 'default':'`LV_DITHER_NONE`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
diff --git a/src/core/lv_obj_draw.c b/src/core/lv_obj_draw.c
index ccfd207a5a..db7c6ea54b 100644
--- a/src/core/lv_obj_draw.c
+++ b/src/core/lv_obj_draw.c
@@ -58,7 +58,7 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint32_t part, lv_draw_rect_dsc_t
draw_dsc->bg_opa = lv_obj_get_style_bg_opa(obj, part);
if(draw_dsc->bg_opa > LV_OPA_MIN) {
draw_dsc->bg_color = lv_obj_get_style_bg_color_filtered(obj, part);
- const lv_gradient_t * grad = lv_obj_get_style_bg_gradient(obj, part);
+ const lv_grad_dsc_t * grad = lv_obj_get_style_bg_grad(obj, part);
if(grad && grad->dir != LV_GRAD_DIR_NONE) {
lv_memcpy(&draw_dsc->bg_grad, grad, sizeof(*grad));
}
diff --git a/src/core/lv_obj_style_gen.c b/src/core/lv_obj_style_gen.c
index acf7effb33..8eb7ebe6d0 100644
--- a/src/core/lv_obj_style_gen.c
+++ b/src/core/lv_obj_style_gen.c
@@ -232,12 +232,12 @@ void lv_obj_set_style_bg_grad_stop(struct _lv_obj_t * obj, lv_coord_t value, lv_
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_GRAD_STOP, v, selector);
}
-void lv_obj_set_style_bg_gradient(struct _lv_obj_t * obj, const lv_gradient_t * value, lv_style_selector_t selector)
+void lv_obj_set_style_bg_grad(struct _lv_obj_t * obj, const lv_grad_dsc_t * value, lv_style_selector_t selector)
{
lv_style_value_t v = {
.ptr = value
};
- lv_obj_set_local_style_prop(obj, LV_STYLE_BG_GRADIENT, v, selector);
+ lv_obj_set_local_style_prop(obj, LV_STYLE_BG_GRAD, v, selector);
}
void lv_obj_set_style_bg_dither_mode(struct _lv_obj_t * obj, lv_dither_mode_t value, lv_style_selector_t selector)
diff --git a/src/core/lv_obj_style_gen.h b/src/core/lv_obj_style_gen.h
index 4790040793..e4383d5ce6 100644
--- a/src/core/lv_obj_style_gen.h
+++ b/src/core/lv_obj_style_gen.h
@@ -172,10 +172,10 @@ static inline lv_coord_t lv_obj_get_style_bg_grad_stop(const struct _lv_obj_t *
return (lv_coord_t)v.num;
}
-static inline const lv_gradient_t * lv_obj_get_style_bg_gradient(const struct _lv_obj_t * obj, uint32_t part)
+static inline const lv_grad_dsc_t * lv_obj_get_style_bg_grad(const struct _lv_obj_t * obj, uint32_t part)
{
- lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRADIENT);
- return (const lv_gradient_t *)v.ptr;
+ lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD);
+ return (const lv_grad_dsc_t *)v.ptr;
}
static inline lv_dither_mode_t lv_obj_get_style_bg_dither_mode(const struct _lv_obj_t * obj, uint32_t part)
@@ -574,7 +574,7 @@ void lv_obj_set_style_bg_grad_color_filtered(struct _lv_obj_t * obj, lv_color_t
void lv_obj_set_style_bg_grad_dir(struct _lv_obj_t * obj, lv_grad_dir_t value, lv_style_selector_t selector);
void lv_obj_set_style_bg_main_stop(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
void lv_obj_set_style_bg_grad_stop(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
-void lv_obj_set_style_bg_gradient(struct _lv_obj_t * obj, const lv_gradient_t * value, lv_style_selector_t selector);
+void lv_obj_set_style_bg_grad(struct _lv_obj_t * obj, const lv_grad_dsc_t * value, lv_style_selector_t selector);
void lv_obj_set_style_bg_dither_mode(struct _lv_obj_t * obj, lv_dither_mode_t value, lv_style_selector_t selector);
void lv_obj_set_style_bg_img_src(struct _lv_obj_t * obj, const void * value, lv_style_selector_t selector);
void lv_obj_set_style_bg_img_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
diff --git a/src/draw/lv_draw_rect.h b/src/draw/lv_draw_rect.h
index 55d9708df4..efa630cf24 100644
--- a/src/draw/lv_draw_rect.h
+++ b/src/draw/lv_draw_rect.h
@@ -39,7 +39,7 @@ typedef struct {
union {
#endif
lv_color_t bg_color; /**< First element of a gradient is a color, so it maps well here*/
- lv_gradient_t bg_grad;
+ lv_grad_dsc_t bg_grad;
#if __STDC_VERSION__ >= 201112L
};
#endif
diff --git a/src/draw/sw/lv_draw_sw_dither.c b/src/draw/sw/lv_draw_sw_dither.c
index eb4553d39c..ff9ebf3d35 100644
--- a/src/draw/sw/lv_draw_sw_dither.c
+++ b/src/draw/sw/lv_draw_sw_dither.c
@@ -17,7 +17,7 @@
#if _DITHER_GRADIENT
-LV_ATTRIBUTE_FAST_MEM void lv_dither_none(lv_gradient_cache_t * grad, lv_coord_t x, lv_coord_t y, lv_coord_t w)
+LV_ATTRIBUTE_FAST_MEM void lv_dither_none(lv_grad_t * grad, lv_coord_t x, lv_coord_t y, lv_coord_t w)
{
LV_UNUSED(x);
LV_UNUSED(y);
@@ -40,7 +40,7 @@ static const uint8_t dither_ordered_threshold_matrix[8 * 8] = {
}; /* Shift by 6 to normalize */
-LV_ATTRIBUTE_FAST_MEM void lv_dither_ordered_hor(lv_gradient_cache_t * grad, lv_coord_t x, lv_coord_t y, lv_coord_t w)
+LV_ATTRIBUTE_FAST_MEM void lv_dither_ordered_hor(lv_grad_t * grad, lv_coord_t x, lv_coord_t y, lv_coord_t w)
{
LV_UNUSED(x);
/* For vertical dithering, the error is spread on the next column (and not next line).
@@ -63,7 +63,7 @@ LV_ATTRIBUTE_FAST_MEM void lv_dither_ordered_hor(lv_gradient_cache_t * grad, lv_
grad->map[j] = lv_color_hex(t.full);
}
}
-LV_ATTRIBUTE_FAST_MEM void lv_dither_ordered_ver(lv_gradient_cache_t * grad, lv_coord_t x, lv_coord_t y, lv_coord_t w)
+LV_ATTRIBUTE_FAST_MEM void lv_dither_ordered_ver(lv_grad_t * grad, lv_coord_t x, lv_coord_t y, lv_coord_t w)
{
/* For vertical dithering, the error is spread on the next column (and not next line).
Since the renderer is scanline based, it's not obvious what could be used to perform the rendering efficiently.
@@ -99,7 +99,7 @@ LV_ATTRIBUTE_FAST_MEM void lv_dither_ordered_ver(lv_gradient_cache_t * grad, lv_
#if LV_DITHER_ERROR_DIFFUSION == 1
-LV_ATTRIBUTE_FAST_MEM void lv_dither_err_diff_hor(lv_gradient_cache_t * grad, lv_coord_t xs, lv_coord_t y, lv_coord_t w)
+LV_ATTRIBUTE_FAST_MEM void lv_dither_err_diff_hor(lv_grad_t * grad, lv_coord_t xs, lv_coord_t y, lv_coord_t w)
{
LV_UNUSED(xs);
LV_UNUSED(y);
@@ -153,7 +153,7 @@ LV_ATTRIBUTE_FAST_MEM void lv_dither_err_diff_hor(lv_gradient_cache_t * grad, lv
grad->map[grad->size - 1] = lv_color_hex(grad->hmap[grad->size - 1].full);
}
-LV_ATTRIBUTE_FAST_MEM void lv_dither_err_diff_ver(lv_gradient_cache_t * grad, lv_coord_t xs, lv_coord_t y, lv_coord_t w)
+LV_ATTRIBUTE_FAST_MEM void lv_dither_err_diff_ver(lv_grad_t * grad, lv_coord_t xs, lv_coord_t y, lv_coord_t w)
{
/* Try to implement error diffusion on a vertical gradient and an horizontal map using those tricks:
Since the given hi-resolution gradient (in src) is vertical, the Floyd Steinberg algorithm pass need to be rotated,
diff --git a/src/draw/sw/lv_draw_sw_dither.h b/src/draw/sw/lv_draw_sw_dither.h
index 2c2243d1db..6362c5ac42 100644
--- a/src/draw/sw/lv_draw_sw_dither.h
+++ b/src/draw/sw/lv_draw_sw_dither.h
@@ -19,13 +19,12 @@ extern "C" {
/*********************
* DEFINES
*********************/
-#if LV_COLOR_DEPTH < 32 && LV_DRAW_COMPLEX == 1 && LV_DITHER_GRADIENT == 1
+#if LV_COLOR_DEPTH < 32 && LV_DITHER_GRADIENT == 1
#define _DITHER_GRADIENT 1
#else
#define _DITHER_GRADIENT 0
#endif
-
/**********************
* TYPEDEFS
**********************/
diff --git a/src/draw/sw/lv_draw_sw_gradient.c b/src/draw/sw/lv_draw_sw_gradient.c
index 1ed2b2574d..c5b32073ed 100644
--- a/src/draw/sw/lv_draw_sw_gradient.c
+++ b/src/draw/sw/lv_draw_sw_gradient.c
@@ -8,6 +8,7 @@
*********************/
#include "lv_draw_sw_gradient.h"
#include "../../misc/lv_gc.h"
+#include "../../misc/lv_types.h"
/*********************
* DEFINES
@@ -20,6 +21,12 @@
#define GRAD_CONV(t, x) t = x
#endif
+#if defined(LV_ARCH_64)
+ #define ALIGN(X) (((X) + 7) & ~7)
+#else
+ #define ALIGN(X) (((X) + 3) & ~3)
+#endif
+
#define MAX_WIN_RES 1024 /**TODO: Find a way to get this information: max(horz_res, vert_res)*/
#if _DITHER_GRADIENT
@@ -35,17 +42,17 @@
/**********************
* STATIC PROTOTYPES
**********************/
-static lv_gradient_cache_t * next_in_cache(lv_gradient_cache_t * first);
+static lv_grad_t * next_in_cache(lv_grad_t * item);
-typedef lv_res_t (*op_cache_t)(lv_gradient_cache_t * c, void * ctx);
-static lv_res_t iterate_cache(op_cache_t func, void * ctx, lv_gradient_cache_t ** out);
-static size_t get_cache_item_size(lv_gradient_cache_t * c);
-static lv_gradient_cache_t * allocate_item(const lv_gradient_t * g, lv_coord_t w, lv_coord_t h);
-static lv_res_t find_oldest_item_life(lv_gradient_cache_t * c, void * ctx);
-static lv_res_t kill_oldest_item(lv_gradient_cache_t * c, void * ctx);
-static lv_res_t find_item(lv_gradient_cache_t * c, void * ctx);
-static void free_item(lv_gradient_cache_t * c);
-static uint32_t compute_key(const lv_gradient_t * g, lv_coord_t w, lv_coord_t h);
+typedef lv_res_t (*op_cache_t)(lv_grad_t * c, void * ctx);
+static lv_res_t iterate_cache(op_cache_t func, void * ctx, lv_grad_t ** out);
+static size_t get_cache_item_size(lv_grad_t * c);
+static lv_grad_t * allocate_item(const lv_grad_dsc_t * g, lv_coord_t w, lv_coord_t h);
+static lv_res_t find_oldest_item_life(lv_grad_t * c, void * ctx);
+static lv_res_t kill_oldest_item(lv_grad_t * c, void * ctx);
+static lv_res_t find_item(lv_grad_t * c, void * ctx);
+static void free_item(lv_grad_t * c);
+static uint32_t compute_key(const lv_grad_dsc_t * g, lv_coord_t w, lv_coord_t h);
/**********************
@@ -62,45 +69,44 @@ union void_cast {
const uint32_t value;
};
-static uint32_t compute_key(const lv_gradient_t * g, lv_coord_t size, lv_coord_t w)
+static uint32_t compute_key(const lv_grad_dsc_t * g, lv_coord_t size, lv_coord_t w)
{
union void_cast v;
v.ptr = g;
return (v.value ^ size ^ (w >> 1)); /*Yes, this is correct, it's like a hash that changes if the width changes*/
}
-
-static size_t get_cache_item_size(lv_gradient_cache_t * c)
+static size_t get_cache_item_size(lv_grad_t * c)
{
- size_t s = sizeof(*c) + c->alloc_size * sizeof(lv_color_t)
+ size_t s = ALIGN(sizeof(*c)) + ALIGN(c->alloc_size * sizeof(lv_color_t));
#if _DITHER_GRADIENT
- + c->size * sizeof(lv_color32_t)
+ s += ALIGN(c->size * sizeof(lv_color32_t));
#if LV_DITHER_ERROR_DIFFUSION == 1
- + c->w * sizeof(lv_scolor24_t)
+ s += ALIGN(c->w * sizeof(lv_scolor24_t));
#endif
#endif
- ;
- return s; /* TODO: Should we align this ? */
+ return s;
}
-static lv_gradient_cache_t * next_in_cache(lv_gradient_cache_t * first)
+static lv_grad_t * next_in_cache(lv_grad_t * item)
{
- if(first == NULL)
- return (lv_gradient_cache_t *)LV_GC_ROOT(_lv_grad_cache_mem);
- if(first == NULL)
+ if(grad_cache_size == 0) return NULL;
+
+ if(item == NULL)
+ return (lv_grad_t *)LV_GC_ROOT(_lv_grad_cache_mem);
+ if(item == NULL)
return NULL;
- size_t s = get_cache_item_size(first);
+ size_t s = get_cache_item_size(item);
/*Compute the size for this cache item*/
- if((uint8_t *)first + s > grad_cache_end)
- return NULL;
- return (lv_gradient_cache_t *)((uint8_t *)first + s);
+ if((uint8_t *)item + s >= grad_cache_end) return NULL;
+ else return (lv_grad_t *)((uint8_t *)item + s);
}
-static lv_res_t iterate_cache(op_cache_t func, void * ctx, lv_gradient_cache_t ** out)
+static lv_res_t iterate_cache(op_cache_t func, void * ctx, lv_grad_t ** out)
{
- lv_gradient_cache_t * first = next_in_cache(NULL);
- while(first != NULL) {
+ lv_grad_t * first = next_in_cache(NULL);
+ while(first != NULL && first->life) {
if((*func)(first, ctx) == LV_RES_OK) {
if(out != NULL) *out = first;
return LV_RES_OK;
@@ -110,19 +116,20 @@ static lv_res_t iterate_cache(op_cache_t func, void * ctx, lv_gradient_cache_t *
return LV_RES_INV;
}
-static lv_res_t find_oldest_item_life(lv_gradient_cache_t * c, void * ctx)
+static lv_res_t find_oldest_item_life(lv_grad_t * c, void * ctx)
{
uint32_t * min_life = (uint32_t *)ctx;
if(c->life < *min_life) *min_life = c->life;
return LV_RES_INV;
}
-static void free_item(lv_gradient_cache_t * c)
+static void free_item(lv_grad_t * c)
{
size_t size = get_cache_item_size(c);
size_t next_items_size = (size_t)(grad_cache_end - (uint8_t *)c) - size;
grad_cache_end -= size;
if(next_items_size) {
+ uint8_t * old = (uint8_t *)c;
lv_memcpy(c, ((uint8_t *)c) + size, next_items_size);
/* Then need to fix all internal pointers too */
while((uint8_t *)c != grad_cache_end) {
@@ -133,12 +140,13 @@ static void free_item(lv_gradient_cache_t * c)
c->error_acc = (lv_scolor24_t *)(((uint8_t *)c->error_acc) - size);
#endif
#endif
- c = (lv_gradient_cache_t *)(((uint8_t *)c) + get_cache_item_size(c));
+ c = (lv_grad_t *)(((uint8_t *)c) + get_cache_item_size(c));
}
+ lv_memset_00(old + next_items_size, size);
}
}
-static lv_res_t kill_oldest_item(lv_gradient_cache_t * c, void * ctx)
+static lv_res_t kill_oldest_item(lv_grad_t * c, void * ctx)
{
uint32_t * min_life = (uint32_t *)ctx;
if(c->life == *min_life) {
@@ -148,58 +156,84 @@ static lv_res_t kill_oldest_item(lv_gradient_cache_t * c, void * ctx)
}
return LV_RES_INV;
}
-static lv_res_t find_item(lv_gradient_cache_t * c, void * ctx)
+
+static lv_res_t find_item(lv_grad_t * c, void * ctx)
{
uint32_t * k = (uint32_t *)ctx;
if(c->key == *k) return LV_RES_OK;
return LV_RES_INV;
}
-
-static lv_gradient_cache_t * allocate_item(const lv_gradient_t * g, lv_coord_t w, lv_coord_t h)
+static lv_grad_t * allocate_item(const lv_grad_dsc_t * g, lv_coord_t w, lv_coord_t h)
{
lv_coord_t size = g->dir == LV_GRAD_DIR_HOR ? w : h;
lv_coord_t map_size = LV_MAX(w, h); /* The map is being used horizontally (width) unless
no dithering is selected where it's used vertically */
- size_t req_size = sizeof(lv_gradient_cache_t) + map_size * sizeof(lv_color_t)
+
+ size_t req_size = ALIGN(sizeof(lv_grad_t)) + ALIGN(map_size * sizeof(lv_color_t));
#if _DITHER_GRADIENT
- + size * sizeof(lv_color32_t)
+ req_size += ALIGN(size * sizeof(lv_color32_t));
#if LV_DITHER_ERROR_DIFFUSION == 1
- + w * sizeof(lv_scolor24_t)
+ req_size += ALIGN(w * sizeof(lv_scolor24_t));
#endif
#endif
- ;
+
size_t act_size = (size_t)(grad_cache_end - LV_GC_ROOT(_lv_grad_cache_mem));
- if(req_size + act_size > grad_cache_size) {
- /*Need to evict items from cache until we find enough space to allocate this one */
- if(req_size > grad_cache_size) {
- LV_LOG_WARN("Gradient cache too small, failed to allocate");
- return NULL; /*No magic here, if the empty cache is still too small*/
- }
- while(act_size + req_size < grad_cache_size) {
- uint32_t oldest_life = UINT32_MAX;
- iterate_cache(&find_oldest_item_life, &oldest_life, NULL);
- iterate_cache(&kill_oldest_item, &oldest_life, NULL);
- act_size = (size_t)(grad_cache_end - LV_GC_ROOT(_lv_grad_cache_mem));
- }
- /*Ok, now we have space to allocate*/
+ lv_grad_t * item = NULL;
+ if(req_size + act_size < grad_cache_size) {
+ item = (lv_grad_t *)grad_cache_end;
+ item->not_cached = 0;
}
- lv_gradient_cache_t * item = (lv_gradient_cache_t *)grad_cache_end;
+ else {
+ /*Need to evict items from cache until we find enough space to allocate this one */
+ if(req_size <= grad_cache_size) {
+ while(act_size + req_size > grad_cache_size) {
+ uint32_t oldest_life = UINT32_MAX;
+ iterate_cache(&find_oldest_item_life, &oldest_life, NULL);
+ iterate_cache(&kill_oldest_item, &oldest_life, NULL);
+ act_size = (size_t)(grad_cache_end - LV_GC_ROOT(_lv_grad_cache_mem));
+ }
+ item = (lv_grad_t *)grad_cache_end;
+ item->not_cached = 0;
+ }
+ else {
+ /*The cache is too small. Allocate the item manually and free it later.*/
+ item = lv_mem_alloc(req_size);
+ LV_ASSERT_MALLOC(item);
+ if(item == NULL) return NULL;
+ item->not_cached = 1;
+ }
+ }
+
item->key = compute_key(g, size, w);
item->life = 1;
item->filled = 0;
item->alloc_size = map_size;
item->size = size;
- item->map = (lv_color_t *)(grad_cache_end + sizeof(*item));
+ if(item->not_cached) {
+ uint8_t * p = (uint8_t *)item;
+ item->map = (lv_color_t *)(p + ALIGN(sizeof(*item)));
#if _DITHER_GRADIENT
- item->hmap = (lv_color32_t *)(grad_cache_end + sizeof(*item) + map_size * sizeof(lv_color_t));
+ item->hmap = (lv_color32_t *)(p + ALIGN(sizeof(*item)) + ALIGN(map_size * sizeof(lv_color_t)));
#if LV_DITHER_ERROR_DIFFUSION == 1
- item->error_acc = (lv_scolor24_t *)(grad_cache_end + sizeof(*item) + size * sizeof(lv_grad_color_t) +
- map_size * sizeof(lv_color_t));
- item->w = w;
+ item->error_acc = (lv_scolor24_t *)(p + ALIGN(sizeof(*item)) + ALIGN(size * sizeof(lv_grad_color_t)) +
+ ALIGN(map_size * sizeof(lv_color_t)));
+ item->w = w;
#endif
#endif
- grad_cache_end += req_size;
+ }
+ else {
+ item->map = (lv_color_t *)(grad_cache_end + ALIGN(sizeof(*item)));
+#if _DITHER_GRADIENT
+ item->hmap = (lv_color32_t *)(grad_cache_end + ALIGN(sizeof(*item)) + ALIGN(map_size * sizeof(lv_color_t)));
+#if LV_DITHER_ERROR_DIFFUSION == 1
+ item->error_acc = (lv_scolor24_t *)(grad_cache_end + ALIGN(sizeof(*item)) + ALIGN(size * sizeof(lv_grad_color_t)) +
+ ALIGN(map_size * sizeof(lv_color_t)));
+ item->w = w;
+#endif
+#endif
+ grad_cache_end += req_size;
+ }
return item;
}
@@ -207,35 +241,38 @@ static lv_gradient_cache_t * allocate_item(const lv_gradient_t * g, lv_coord_t w
/**********************
* FUNCTIONS
**********************/
-void lv_grad_free_cache()
+void lv_gradient_free_cache(void)
{
lv_mem_free(LV_GC_ROOT(_lv_grad_cache_mem));
LV_GC_ROOT(_lv_grad_cache_mem) = grad_cache_end = NULL;
grad_cache_size = 0;
}
-void lv_grad_set_cache_size(size_t max_bytes)
+void lv_gradient_set_cache_size(size_t max_bytes)
{
lv_mem_free(LV_GC_ROOT(_lv_grad_cache_mem));
grad_cache_end = LV_GC_ROOT(_lv_grad_cache_mem) = lv_mem_alloc(max_bytes);
LV_ASSERT_MALLOC(LV_GC_ROOT(_lv_grad_cache_mem));
+ lv_memset_00(LV_GC_ROOT(_lv_grad_cache_mem), max_bytes);
grad_cache_size = max_bytes;
}
-lv_gradient_cache_t * lv_grad_get_from_cache(const lv_gradient_t * g, lv_coord_t w, lv_coord_t h)
+lv_grad_t * lv_gradient_get(const lv_grad_dsc_t * g, lv_coord_t w, lv_coord_t h)
{
/* No gradient, no cache */
if(g->dir == LV_GRAD_DIR_NONE) return NULL;
/* Step 0: Check if the cache exist (else create it) */
- if(!grad_cache_size) {
- lv_grad_set_cache_size(LV_DEFAULT_GRAD_CACHE_SIZE);
+ static bool inited = false;
+ if(!inited) {
+ lv_gradient_set_cache_size(LV_GRAD_CACHE_DEF_SIZE);
+ inited = true;
}
/* Step 1: Search cache for the given key */
lv_coord_t size = g->dir == LV_GRAD_DIR_HOR ? w : h;
uint32_t key = compute_key(g, size, w);
- lv_gradient_cache_t * item = NULL;
+ lv_grad_t * item = NULL;
if(iterate_cache(&find_item, &key, &item) == LV_RES_OK) {
item->life++; /* Don't forget to bump the counter */
return item;
@@ -243,39 +280,30 @@ lv_gradient_cache_t * lv_grad_get_from_cache(const lv_gradient_t * g, lv_coord_t
/* Step 2: Need to allocate an item for it */
item = allocate_item(g, w, h);
- if(item == NULL) return item;
+ if(item == NULL) {
+ LV_LOG_WARN("Faild to allcoate item for teh gradient");
+ return item;
+ }
/* Step 3: Fill it with the gradient, as expected */
#if _DITHER_GRADIENT
for(lv_coord_t i = 0; i < item->size; i++) {
- item->hmap[i] = lv_grad_get(g, item->size, i);
+ item->hmap[i] = lv_gradient_calculate(g, item->size, i);
}
#if LV_DITHER_ERROR_DIFFUSION == 1
lv_memset_00(item->error_acc, w * sizeof(lv_scolor24_t));
#endif
#else
for(lv_coord_t i = 0; i < item->size; i++) {
- item->map[i] = lv_grad_get(g, item->size, i);
+ item->map[i] = lv_gradient_calculate(g, item->size, i);
}
#endif
return item;
}
-
-void lv_grad_pop_from_cache(const lv_gradient_t * g, lv_coord_t w, lv_coord_t h)
-{
- lv_coord_t size = g->dir == LV_GRAD_DIR_HOR ? w : h;
- uint32_t key = compute_key(g, size, w);
- lv_gradient_cache_t * item = NULL;
- if(iterate_cache(&find_item, &key, &item) == LV_RES_OK) {
- free_item(item);
- }
-}
-
-
-
-LV_ATTRIBUTE_FAST_MEM lv_grad_color_t lv_grad_get(const lv_gradient_t * dsc, lv_coord_t range, lv_coord_t frac)
+LV_ATTRIBUTE_FAST_MEM lv_grad_color_t lv_gradient_calculate(const lv_grad_dsc_t * dsc, lv_coord_t range,
+ lv_coord_t frac)
{
lv_grad_color_t tmp;
lv_color32_t one, two;
@@ -316,3 +344,10 @@ LV_ATTRIBUTE_FAST_MEM lv_grad_color_t lv_grad_get(const lv_gradient_t * dsc, lv_
LV_UDIV255(two.ch.blue * mix + one.ch.blue * imix));
return r;
}
+
+void lv_gradient_cleanup(lv_grad_t * grad)
+{
+ if(grad->not_cached) {
+ lv_mem_free(grad);
+ }
+}
diff --git a/src/draw/sw/lv_draw_sw_gradient.h b/src/draw/sw/lv_draw_sw_gradient.h
index 262240874f..f5f3215ced 100644
--- a/src/draw/sw/lv_draw_sw_gradient.h
+++ b/src/draw/sw/lv_draw_sw_gradient.h
@@ -40,9 +40,10 @@ typedef lv_color_t lv_grad_color_t;
typedef struct _lv_gradient_cache_t {
uint32_t key; /**< A discriminating key that's built from the drawing operation.
* If the key does not match, the cache item is not used */
- uint32_t life : 31; /**< A life counter that's incremented on usage. Higher counter is
+ uint32_t life : 30; /**< A life counter that's incremented on usage. Higher counter is
* less likely to be evicted from the cache */
uint32_t filled : 1; /**< Used to skip dithering in it if already done */
+ uint32_t not_cached: 1; /**< The cache was too small so this item is not managed by the cache*/
lv_color_t * map; /**< The computed gradient low bitdepth color map, points into the
* cache's buffer, no free needed */
lv_coord_t alloc_size; /**< The map allocated size in colors */
@@ -56,7 +57,7 @@ typedef struct _lv_gradient_cache_t {
lv_coord_t w; /**< The error array width in pixels */
#endif
#endif
-} lv_gradient_cache_t;
+} lv_grad_t;
/**********************
@@ -68,22 +69,26 @@ typedef struct _lv_gradient_cache_t {
* @param range The range to use in computation.
* @param frac The current part used in the range. frac is in [0; range]
*/
-LV_ATTRIBUTE_FAST_MEM lv_grad_color_t lv_grad_get(const lv_gradient_t * dsc, lv_coord_t range, lv_coord_t frac);
+LV_ATTRIBUTE_FAST_MEM lv_grad_color_t lv_gradient_calculate(const lv_grad_dsc_t * dsc, lv_coord_t range,
+ lv_coord_t frac);
-/** Set the gradient cache size */
-void lv_grad_set_cache_size(size_t max_bytes);
-
-/** Get a gradient cache from the given parameters */
-lv_gradient_cache_t * lv_grad_get_from_cache(const lv_gradient_t * gradient, lv_coord_t w, lv_coord_t h);
-
-/** Evict item from the gradient cache (not used anymore).
- * This bypass the life counter on the item to remove this item.
+/**
+ * Set the gradient cache size
+ * @param max_bytes Max cahce size
*/
-void lv_grad_pop_from_cache(const lv_gradient_t * gradient, lv_coord_t w, lv_coord_t h);
+void lv_gradient_set_cache_size(size_t max_bytes);
/** Free the gradient cache */
-void lv_grad_free_cache(void);
+void lv_gradient_free_cache(void);
+/** Get a gradient cache from the given parameters */
+lv_grad_t * lv_gradient_get(const lv_grad_dsc_t * gradient, lv_coord_t w, lv_coord_t h);
+
+/**
+ * Clean up the gradient item after it was get with `lv_grad_get_from_cache`.
+ * @param grad pointer to a gradient
+ */
+void lv_gradient_cleanup(lv_grad_t * grad);
#ifdef __cplusplus
} /*extern "C"*/
diff --git a/src/draw/sw/lv_draw_sw_rect.c b/src/draw/sw/lv_draw_sw_rect.c
index 18f23bd44d..d94431b0c0 100644
--- a/src/draw/sw/lv_draw_sw_rect.c
+++ b/src/draw/sw/lv_draw_sw_rect.c
@@ -169,7 +169,7 @@ static void draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, co
/*Get gradient if appropriate*/
- lv_gradient_cache_t * grad = lv_grad_get_from_cache(&dsc->bg_grad, coords_bg_w, coords_bg_h);
+ lv_grad_t * grad = lv_gradient_get(&dsc->bg_grad, coords_bg_w, coords_bg_h);
if(grad && grad_dir == LV_GRAD_DIR_HOR) {
blend_dsc.src_buf = grad->map + clipped_coords.x1 - bg_coords.x1;
}
@@ -192,10 +192,29 @@ static void draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, co
#if LV_DITHER_ERROR_DIFFUSION
if(dither_mode == LV_DITHER_ORDERED)
#endif
- dither_func = grad_dir == LV_GRAD_DIR_HOR ? &lv_dither_ordered_hor : &lv_dither_ordered_ver;
+ switch(grad_dir) {
+ case LV_GRAD_DIR_HOR:
+ dither_func = lv_dither_ordered_hor;
+ break;
+ case LV_GRAD_DIR_VER:
+ dither_func = lv_dither_ordered_ver;
+ break;
+ default:
+ dither_func = NULL;
+ }
+
#if LV_DITHER_ERROR_DIFFUSION
else if(dither_mode == LV_DITHER_ERR_DIFF)
- dither_func = grad_dir == LV_GRAD_DIR_HOR ? &lv_dither_err_diff_hor : &lv_dither_err_diff_ver;
+ switch(grad_dir) {
+ case LV_GRAD_DIR_HOR:
+ dither_func = lv_dither_err_diff_hor;
+ break;
+ case LV_GRAD_DIR_VER:
+ dither_func = lv_dither_err_diff_ver;
+ break;
+ default:
+ dither_func = NULL;
+ }
#endif
#endif
@@ -212,7 +231,7 @@ static void draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, co
if(blend_dsc.mask_res == LV_DRAW_MASK_RES_FULL_COVER) blend_dsc.mask_res = LV_DRAW_MASK_RES_CHANGED;
#if _DITHER_GRADIENT
- dither_func(grad, blend_area.x1, h - bg_coords.y1, grad_size);
+ if(dither_func) dither_func(grad, blend_area.x1, h - bg_coords.y1, grad_size);
#endif
if(grad_dir == LV_GRAD_DIR_VER) blend_dsc.color = grad->map[h - bg_coords.y1];
lv_draw_sw_blend(draw_ctx, &blend_dsc);
@@ -238,7 +257,7 @@ static void draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, co
blend_area.y2 = top_y;
#if _DITHER_GRADIENT
- dither_func(grad, blend_area.x1, top_y - bg_coords.y1, grad_size);
+ if(dither_func) dither_func(grad, blend_area.x1, top_y - bg_coords.y1, grad_size);
#endif
if(grad_dir == LV_GRAD_DIR_VER) blend_dsc.color = grad->map[top_y - bg_coords.y1];
lv_draw_sw_blend(draw_ctx, &blend_dsc);
@@ -249,7 +268,7 @@ static void draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, co
blend_area.y2 = bottom_y;
#if _DITHER_GRADIENT
- dither_func(grad, blend_area.x1, bottom_y - bg_coords.y1, grad_size);
+ if(dither_func) dither_func(grad, blend_area.x1, bottom_y - bg_coords.y1, grad_size);
#endif
if(grad_dir == LV_GRAD_DIR_VER) blend_dsc.color = grad->map[bottom_y - bg_coords.y1];
lv_draw_sw_blend(draw_ctx, &blend_dsc);
@@ -288,7 +307,7 @@ static void draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, co
blend_area.y2 = h;
#if _DITHER_GRADIENT
- dither_func(grad, blend_area.x1, h - bg_coords.y1, grad_size);
+ if(dither_func) dither_func(grad, blend_area.x1, h - bg_coords.y1, grad_size);
#endif
if(grad_dir == LV_GRAD_DIR_VER) blend_dsc.color = grad->map[h - bg_coords.y1];
lv_draw_sw_blend(draw_ctx, &blend_dsc);
@@ -302,6 +321,9 @@ bg_clean_up:
lv_draw_mask_remove_id(mask_rout_id);
lv_draw_mask_free_param(&mask_rout_param);
}
+ if(grad) {
+ lv_gradient_cleanup(grad);
+ }
#endif
}
diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h
index 00c31367d7..ccfab5497f 100644
--- a/src/lv_conf_internal.h
+++ b/src/lv_conf_internal.h
@@ -293,47 +293,6 @@
#define LV_CIRCLE_CACHE_SIZE 4
#endif
#endif
-
- /*Allow dithering gradient (to achieve visual smooth color gradients on limited color depth display)
- *LV_DITHER_GRADIENT implies allocating one or two more lines of the object's rendering surface
- *The increase in memory consumption is (32 bits * object width) plus 24 bits * object width if using error diffusion */
- #ifndef LV_DITHER_GRADIENT
- #ifdef _LV_KCONFIG_PRESENT
- #ifdef CONFIG_LV_DITHER_GRADIENT
- #define LV_DITHER_GRADIENT CONFIG_LV_DITHER_GRADIENT
- #else
- #define LV_DITHER_GRADIENT 0
- #endif
- #else
- #define LV_DITHER_GRADIENT 1
- #endif
- #endif
-
- /*Add support for error diffusion dithering.
- *Error diffusion dithering gets a much better visual result, but implies more CPU consumption and memory when drawing.
- *The increase in memory consumption is (24 bits * object's width)*/
- #ifndef LV_DITHER_ERROR_DIFFUSION
- #ifdef _LV_KCONFIG_PRESENT
- #ifdef CONFIG_LV_DITHER_ERROR_DIFFUSION
- #define LV_DITHER_ERROR_DIFFUSION CONFIG_LV_DITHER_ERROR_DIFFUSION
- #else
- #define LV_DITHER_ERROR_DIFFUSION 0
- #endif
- #else
- #define LV_DITHER_ERROR_DIFFUSION 1
- #endif
- #endif
-
- /**Number of stops allowed per gradient. Increase this to allow more stops.
- *This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/
- #ifndef LV_GRADIENT_MAX_STOPS
- #ifdef CONFIG_LV_GRADIENT_MAX_STOPS
- #define LV_GRADIENT_MAX_STOPS CONFIG_LV_GRADIENT_MAX_STOPS
- #else
- #define LV_GRADIENT_MAX_STOPS 2
- #endif
- #endif
-
#endif /*LV_DRAW_COMPLEX*/
/*Default image cache size. Image caching keeps the images opened.
@@ -345,11 +304,58 @@
#ifdef CONFIG_LV_IMG_CACHE_DEF_SIZE
#define LV_IMG_CACHE_DEF_SIZE CONFIG_LV_IMG_CACHE_DEF_SIZE
#else
- #define LV_IMG_CACHE_DEF_SIZE 0
+ #define LV_IMG_CACHE_DEF_SIZE 0
#endif
#endif
-/*Maximum buffer size to allocate for rotation. Only used if software rotation is enabled in the display driver.*/
+/*Number of stops allowed per gradient. Increase this to allow more stops.
+ *This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/
+#ifndef LV_GRADIENT_MAX_STOPS
+ #ifdef CONFIG_LV_GRADIENT_MAX_STOPS
+ #define LV_GRADIENT_MAX_STOPS CONFIG_LV_GRADIENT_MAX_STOPS
+ #else
+ #define LV_GRADIENT_MAX_STOPS 2
+ #endif
+#endif
+
+/*Default gradient buffer size.
+ *When LVGL calculates the gradient "maps" it can save them into a cache to avoid calculating them again.
+ *LV_GRAD_CACHE_DEF_SIZE sets the size of this cache in bytes.
+ *If the cache is too small the map will be allocated only while it's required for the drawing.
+ *0 mean no caching.*/
+#ifndef LV_GRAD_CACHE_DEF_SIZE
+ #ifdef CONFIG_LV_GRAD_CACHE_DEF_SIZE
+ #define LV_GRAD_CACHE_DEF_SIZE CONFIG_LV_GRAD_CACHE_DEF_SIZE
+ #else
+ #define LV_GRAD_CACHE_DEF_SIZE 0
+ #endif
+#endif
+
+/*Allow dithering the gradients (to achieve visual smooth color gradients on limited color depth display)
+ *LV_DITHER_GRADIENT implies allocating one or two more lines of the object's rendering surface
+ *The increase in memory consumption is (32 bits * object width) plus 24 bits * object width if using error diffusion */
+#ifndef LV_DITHER_GRADIENT
+ #ifdef CONFIG_LV_DITHER_GRADIENT
+ #define LV_DITHER_GRADIENT CONFIG_LV_DITHER_GRADIENT
+ #else
+ #define LV_DITHER_GRADIENT 0
+ #endif
+#endif
+#if LV_DITHER_GRADIENT
+ /*Add support for error diffusion dithering.
+ *Error diffusion dithering gets a much better visual result, but implies more CPU consumption and memory when drawing.
+ *The increase in memory consumption is (24 bits * object's width)*/
+ #ifndef LV_DITHER_ERROR_DIFFUSION
+ #ifdef CONFIG_LV_DITHER_ERROR_DIFFUSION
+ #define LV_DITHER_ERROR_DIFFUSION CONFIG_LV_DITHER_ERROR_DIFFUSION
+ #else
+ #define LV_DITHER_ERROR_DIFFUSION 0
+ #endif
+ #endif
+#endif
+
+/*Maximum buffer size to allocate for rotation.
+ *Only used if software rotation is enabled in the display driver.*/
#ifndef LV_DISP_ROT_MAX_BUF
#ifdef CONFIG_LV_DISP_ROT_MAX_BUF
#define LV_DISP_ROT_MAX_BUF CONFIG_LV_DISP_ROT_MAX_BUF
diff --git a/src/misc/lv_style.h b/src/misc/lv_style.h
index 2a81559d45..6ec97cb57e 100644
--- a/src/misc/lv_style.h
+++ b/src/misc/lv_style.h
@@ -140,7 +140,7 @@ typedef struct {
* Any of LV_GRAD_DIR_HOR, LV_GRAD_DIR_VER, LV_GRAD_DIR_NONE */
lv_dither_mode_t dither : 3; /**< Whether to dither the gradient or not.
* Any of LV_DITHER_NONE, LV_DITHER_ORDERED, LV_DITHER_ERR_DIFF */
-} lv_gradient_t;
+} lv_grad_dsc_t;
/**
* A common type to handle all the property types in the same way.
@@ -191,7 +191,7 @@ typedef enum {
LV_STYLE_BG_GRAD_DIR = 35,
LV_STYLE_BG_MAIN_STOP = 36,
LV_STYLE_BG_GRAD_STOP = 37,
- LV_STYLE_BG_GRADIENT = 38,
+ LV_STYLE_BG_GRAD = 38,
LV_STYLE_BG_DITHER_MODE = 39,
diff --git a/src/misc/lv_style_gen.c b/src/misc/lv_style_gen.c
index 3602ba7e1d..b806a996bb 100644
--- a/src/misc/lv_style_gen.c
+++ b/src/misc/lv_style_gen.c
@@ -232,12 +232,12 @@ void lv_style_set_bg_grad_stop(lv_style_t * style, lv_coord_t value)
lv_style_set_prop(style, LV_STYLE_BG_GRAD_STOP, v);
}
-void lv_style_set_bg_gradient(lv_style_t * style, const lv_gradient_t * value)
+void lv_style_set_bg_grad(lv_style_t * style, const lv_grad_dsc_t * value)
{
lv_style_value_t v = {
.ptr = value
};
- lv_style_set_prop(style, LV_STYLE_BG_GRADIENT, v);
+ lv_style_set_prop(style, LV_STYLE_BG_GRAD, v);
}
void lv_style_set_bg_dither_mode(lv_style_t * style, lv_dither_mode_t value)
diff --git a/src/misc/lv_style_gen.h b/src/misc/lv_style_gen.h
index 5c4e98f4f6..04e1f1a520 100644
--- a/src/misc/lv_style_gen.h
+++ b/src/misc/lv_style_gen.h
@@ -27,7 +27,7 @@ void lv_style_set_bg_grad_color_filtered(lv_style_t * style, lv_color_t value);
void lv_style_set_bg_grad_dir(lv_style_t * style, lv_grad_dir_t value);
void lv_style_set_bg_main_stop(lv_style_t * style, lv_coord_t value);
void lv_style_set_bg_grad_stop(lv_style_t * style, lv_coord_t value);
-void lv_style_set_bg_gradient(lv_style_t * style, const lv_gradient_t * value);
+void lv_style_set_bg_grad(lv_style_t * style, const lv_grad_dsc_t * value);
void lv_style_set_bg_dither_mode(lv_style_t * style, lv_dither_mode_t value);
void lv_style_set_bg_img_src(lv_style_t * style, const void * value);
void lv_style_set_bg_img_opa(lv_style_t * style, lv_opa_t value);
@@ -235,9 +235,9 @@ void lv_style_set_base_dir(lv_style_t * style, lv_base_dir_t value);
.prop = LV_STYLE_BG_GRAD_STOP, .value = { .num = (int32_t)val } \
}
-#define LV_STYLE_CONST_BG_GRADIENT(val) \
+#define LV_STYLE_CONST_BG_GRAD(val) \
{ \
- .prop = LV_STYLE_BG_GRADIENT, .value = { .ptr = val } \
+ .prop = LV_STYLE_BG_GRAD, .value = { .ptr = val } \
}
#define LV_STYLE_CONST_BG_DITHER_MODE(val) \
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 0dfab12431..6ea91bc455 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -68,6 +68,7 @@ set(LVGL_TEST_OPTIONS_16BIT
-DLV_MEM_SIZE=65536
-DLV_DPI_DEF=40
-DLV_DRAW_COMPLEX=1
+ -DLV_DITHER_GRADIENT=1
-DLV_USE_LOG=1
-DLV_USE_ASSERT_NULL=0
-DLV_USE_ASSERT_MALLOC=0
@@ -94,6 +95,9 @@ set(LVGL_TEST_OPTIONS_16BIT_SWAP
-DLV_MEM_SIZE=65536
-DLV_DPI_DEF=40
-DLV_DRAW_COMPLEX=1
+ -DLV_DITHER_GRADIENT=1
+ -DLV_DITHER_ERROR_DIFFUSION=1
+ -DLV_GRAD_CACHE_DEF_SIZE=8*1024
-DLV_USE_LOG=1
-DLV_USE_ASSERT_NULL=0
-DLV_USE_ASSERT_MALLOC=0
@@ -185,6 +189,9 @@ set(LVGL_TEST_OPTIONS_TEST_COMMON
-DLV_MEM_SIZE=2097152
-DLV_SHADOW_CACHE_SIZE=10240
-DLV_IMG_CACHE_DEF_SIZE=32
+ -DLV_DITHER_GRADIENT=1
+ -DLV_DITHER_ERROR_DIFFUSION=1
+ -DLV_GRAD_CACHE_DEF_SIZE=8*1024
-DLV_USE_LOG=1
-DLV_LOG_PRINTF=1
-DLV_USE_FONT_SUBPX=1
@@ -228,6 +235,7 @@ set(LVGL_TEST_OPTIONS_TEST_DEFHEAP
${LVGL_TEST_OPTIONS_TEST_COMMON}
-DLVGL_CI_USING_DEF_HEAP
-DLV_MEM_SIZE=2097152
+ -fsanitize=address
)
if (OPTIONS_MINIMAL_MONOCHROME)
@@ -245,7 +253,7 @@ elseif (OPTIONS_TEST_SYSHEAP)
set (TEST_LIBS --coverage -fsanitize=address)
elseif (OPTIONS_TEST_DEFHEAP)
set (BUILD_OPTIONS ${LVGL_TEST_OPTIONS_TEST_DEFHEAP})
- set (TEST_LIBS --coverage)
+ set (TEST_LIBS --coverage -fsanitize=address)
else()
message(FATAL_ERROR "Must provide a known options value (check main.py?).")
endif()
diff --git a/tests/src/test_cases/test_style.c b/tests/src/test_cases/test_style.c
index 3d0033451a..4ad5ad2be6 100644
--- a/tests/src/test_cases/test_style.c
+++ b/tests/src/test_cases/test_style.c
@@ -2,6 +2,7 @@
#include "../lvgl.h"
#include "unity/unity.h"
+#include
static void obj_set_height_helper(void * obj, int32_t height)
{
@@ -30,6 +31,13 @@ void test_gradient_vertical_misalignment(void)
lv_anim_set_repeat_count(&a, 100);
lv_anim_set_values(&a, 0, 300);
lv_anim_start(&a);
+
+ uint32_t i;
+ for(i = 0; i < 1000; i++) {
+ lv_timer_handler();
+ lv_tick_inc(100);
+ usleep(1000);
+ }
}
#endif