mirror of
https://github.com/lvgl/lvgl.git
synced 2025-02-04 07:13:00 +08:00
further reduce the memory usage of shadow drawing
This commit is contained in:
parent
18378e0a08
commit
d108b2e793
@ -30,8 +30,8 @@ static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, const lv_s
|
|||||||
static void draw_border(const lv_area_t * coords, const lv_area_t * clip, const lv_style_t * style, lv_opa_t opa_scale);
|
static void draw_border(const lv_area_t * coords, const lv_area_t * clip, const lv_style_t * style, lv_opa_t opa_scale);
|
||||||
static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, const lv_style_t * style, lv_opa_t opa_scale);
|
static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, const lv_style_t * style, lv_opa_t opa_scale);
|
||||||
static lv_color_t grad_get(const lv_style_t * style, lv_coord_t s, lv_coord_t i);
|
static lv_color_t grad_get(const lv_style_t * style, lv_coord_t s, lv_coord_t i);
|
||||||
static void shadow_draw_corner_buf(const lv_area_t * coords, lv_opa_t * sh_buf, lv_coord_t s, lv_coord_t r);
|
static void shadow_draw_corner_buf(const lv_area_t * coords, uint16_t * sh_buf, lv_coord_t s, lv_coord_t r);
|
||||||
static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, lv_opa_t * res_buf, uint16_t * sh_ups_buf);
|
static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, uint16_t * sh_ups_buf);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
@ -555,8 +555,8 @@ static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, const
|
|||||||
|
|
||||||
lv_coord_t corner_size = sw + r_sh;
|
lv_coord_t corner_size = sw + r_sh;
|
||||||
|
|
||||||
lv_opa_t * sh_buf = lv_mem_buf_get(corner_size * corner_size);
|
lv_opa_t * sh_buf = lv_mem_buf_get(corner_size * corner_size * sizeof(uint16_t));
|
||||||
shadow_draw_corner_buf(&sh_rect_area, sh_buf, style->body.shadow.width, r_sh);
|
shadow_draw_corner_buf(&sh_rect_area, (uint16_t *)sh_buf, style->body.shadow.width, r_sh);
|
||||||
|
|
||||||
bool simple_mode = true;
|
bool simple_mode = true;
|
||||||
if(lv_draw_mask_get_cnt() > 0) simple_mode = false;
|
if(lv_draw_mask_get_cnt() > 0) simple_mode = false;
|
||||||
@ -866,7 +866,7 @@ static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, const
|
|||||||
lv_mem_buf_release(sh_buf);
|
lv_mem_buf_release(sh_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shadow_draw_corner_buf(const lv_area_t * coords, lv_opa_t * sh_buf, lv_coord_t sw, lv_coord_t r)
|
static void shadow_draw_corner_buf(const lv_area_t * coords, uint16_t * sh_buf, lv_coord_t sw, lv_coord_t r)
|
||||||
{
|
{
|
||||||
lv_coord_t sw_ori = sw;
|
lv_coord_t sw_ori = sw;
|
||||||
lv_coord_t size = sw_ori + r;
|
lv_coord_t size = sw_ori + r;
|
||||||
@ -890,21 +890,15 @@ static void shadow_draw_corner_buf(const lv_area_t * coords, lv_opa_t * sh_buf,
|
|||||||
else sw = sw_ori >> 1;
|
else sw = sw_ori >> 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The basic idea of shadow drawing is
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
lv_draw_mask_res_t mask_res;
|
lv_draw_mask_res_t mask_res;
|
||||||
lv_coord_t y;
|
lv_coord_t y;
|
||||||
lv_opa_t * mask_line = lv_mem_buf_get(size);
|
lv_opa_t * mask_line = lv_mem_buf_get(size);
|
||||||
uint16_t * sh_ups_buf = lv_mem_buf_get(size * size * sizeof(uint16_t));
|
uint16_t * sh_ups_tmp_buf = (uint16_t *)sh_buf;
|
||||||
uint16_t * sh_ups_tmp_buf = sh_ups_buf;
|
|
||||||
for(y = 0; y < size; y++) {
|
for(y = 0; y < size; y++) {
|
||||||
memset(mask_line, 0xFF, size);
|
memset(mask_line, 0xFF, size);
|
||||||
mask_res = mask_param.dsc.cb(mask_line, 0, y, size, &mask_param);
|
mask_res = mask_param.dsc.cb(mask_line, 0, y, size, &mask_param);
|
||||||
if(mask_res == LV_DRAW_MASK_RES_FULL_TRANSP) {
|
if(mask_res == LV_DRAW_MASK_RES_FULL_TRANSP) {
|
||||||
memset(sh_ups_tmp_buf, 0x00, size * sizeof(sh_ups_buf[0]));
|
memset(sh_ups_tmp_buf, 0x00, size * sizeof(sh_ups_tmp_buf[0]));
|
||||||
} else {
|
} else {
|
||||||
lv_coord_t i;
|
lv_coord_t i;
|
||||||
sh_ups_tmp_buf[0] = (mask_line[0] << SHADOW_UPSACALE_SHIFT) / sw;
|
sh_ups_tmp_buf[0] = (mask_line[0] << SHADOW_UPSACALE_SHIFT) / sw;
|
||||||
@ -918,52 +912,53 @@ static void shadow_draw_corner_buf(const lv_area_t * coords, lv_opa_t * sh_buf,
|
|||||||
}
|
}
|
||||||
lv_mem_buf_release(mask_line);
|
lv_mem_buf_release(mask_line);
|
||||||
|
|
||||||
// uint32_t k;
|
|
||||||
// for(k = 0; k < size * size; k++) {
|
|
||||||
// sh_buf[k] = (sh_ups_buf[k] * sw) >> SHADOW_UPSACALE_SHIFT ;
|
|
||||||
// }
|
|
||||||
// return;
|
|
||||||
|
|
||||||
if(sw == 1) {
|
if(sw == 1) {
|
||||||
lv_coord_t i;
|
uint32_t i;
|
||||||
|
lv_opa_t * res_buf = (lv_opa_t *)sh_buf;
|
||||||
for(i = 0; i < size * size; i++) {
|
for(i = 0; i < size * size; i++) {
|
||||||
sh_buf[i] = (sh_ups_buf[i] >> SHADOW_UPSACALE_SHIFT);
|
res_buf[i] = (sh_buf[i] >> SHADOW_UPSACALE_SHIFT);
|
||||||
}
|
}
|
||||||
lv_mem_buf_release(sh_ups_buf);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
shadow_blur_corner(size, sw, sh_buf, sh_ups_buf);
|
shadow_blur_corner(size, sw, sh_buf);
|
||||||
|
|
||||||
#if SHADOW_ENHANCE
|
#if SHADOW_ENHANCE == 0
|
||||||
|
/*The result is required in lv_opa_t not uint16_t*/
|
||||||
|
uint32_t x;
|
||||||
|
lv_opa_t * res_buf = (lv_opa_t *)sh_buf;
|
||||||
|
for(x = 0; x < size * size; x++) {
|
||||||
|
res_buf[x] = sh_buf[x];
|
||||||
|
}
|
||||||
|
#else
|
||||||
sw = sw_ori - sw;
|
sw = sw_ori - sw;
|
||||||
if(sw <= 1) {
|
if(sw > 1) {
|
||||||
lv_mem_buf_release(sh_ups_buf);
|
uint32_t i;
|
||||||
return;
|
sh_buf[0] = (sh_buf[0] << SHADOW_UPSACALE_SHIFT) / sw;
|
||||||
}
|
for(i = 1; i < (uint32_t) size * size; i++) {
|
||||||
|
if(sh_buf[i] == sh_buf[i-1]) sh_buf[i] = sh_buf[i-1];
|
||||||
|
else sh_buf[i] = (sh_buf[i] << SHADOW_UPSACALE_SHIFT) / sw;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t i;
|
shadow_blur_corner(size, sw, sh_buf);
|
||||||
sh_ups_buf[0] = (sh_buf[0] << SHADOW_UPSACALE_SHIFT) / sw;
|
}
|
||||||
for(i = 1; i < (uint32_t) size * size; i++) {
|
uint32_t x;
|
||||||
if(sh_buf[i] == sh_buf[i-1]) sh_ups_buf[i] = sh_ups_buf[i-1];
|
lv_opa_t * res_buf = (lv_opa_t *)sh_buf;
|
||||||
else sh_ups_buf[i] = (sh_buf[i] << SHADOW_UPSACALE_SHIFT) / sw;
|
for(x = 0; x < size * size; x++) {
|
||||||
|
res_buf[x] = sh_buf[x];
|
||||||
}
|
}
|
||||||
|
|
||||||
shadow_blur_corner(size, sw, sh_buf, sh_ups_buf);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
lv_mem_buf_release(sh_ups_buf);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, lv_opa_t * res_buf, uint16_t * sh_ups_buf)
|
static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, uint16_t * sh_ups_buf)
|
||||||
{
|
{
|
||||||
lv_coord_t s_left = sw >> 1;
|
lv_coord_t s_left = sw >> 1;
|
||||||
lv_coord_t s_right = (sw >> 1);
|
lv_coord_t s_right = (sw >> 1);
|
||||||
if((sw & 1) == 0) s_left--;
|
if((sw & 1) == 0) s_left--;
|
||||||
|
|
||||||
/*Horizontal blur*/
|
/*Horizontal blur*/
|
||||||
uint16_t * sh_ups_hor_buf = lv_mem_buf_get(size * sizeof(uint16_t));
|
uint16_t * sh_ups_blur_buf = lv_mem_buf_get(size * sizeof(uint16_t));
|
||||||
|
|
||||||
lv_coord_t x;
|
lv_coord_t x;
|
||||||
lv_coord_t y;
|
lv_coord_t y;
|
||||||
@ -973,7 +968,7 @@ static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, lv_opa_t * res_bu
|
|||||||
for(y = 0; y < size; y++) {
|
for(y = 0; y < size; y++) {
|
||||||
int32_t v = sh_ups_tmp_buf[size-1] * sw;
|
int32_t v = sh_ups_tmp_buf[size-1] * sw;
|
||||||
for(x = size - 1; x >=0; x--) {
|
for(x = size - 1; x >=0; x--) {
|
||||||
sh_ups_hor_buf[x] = v;
|
sh_ups_blur_buf[x] = v;
|
||||||
|
|
||||||
/*Forget the right pixel*/
|
/*Forget the right pixel*/
|
||||||
uint32_t right_val = 0;
|
uint32_t right_val = 0;
|
||||||
@ -987,7 +982,7 @@ static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, lv_opa_t * res_bu
|
|||||||
v += left_val;
|
v += left_val;
|
||||||
|
|
||||||
}
|
}
|
||||||
memcpy(sh_ups_tmp_buf, sh_ups_hor_buf, size * sizeof(uint16_t));
|
memcpy(sh_ups_tmp_buf, sh_ups_blur_buf, size * sizeof(uint16_t));
|
||||||
sh_ups_tmp_buf += size;
|
sh_ups_tmp_buf += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1001,10 +996,9 @@ static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, lv_opa_t * res_bu
|
|||||||
|
|
||||||
for(x = 0; x < size; x++) {
|
for(x = 0; x < size; x++) {
|
||||||
sh_ups_tmp_buf = &sh_ups_buf[x];
|
sh_ups_tmp_buf = &sh_ups_buf[x];
|
||||||
lv_opa_t * sh_buf_tmp = &res_buf[x];
|
|
||||||
int32_t v = sh_ups_tmp_buf[0] * sw;
|
int32_t v = sh_ups_tmp_buf[0] * sw;
|
||||||
for(y = 0; y < size ; y++, sh_ups_tmp_buf += size, sh_buf_tmp += size) {
|
for(y = 0; y < size ; y++, sh_ups_tmp_buf += size) {
|
||||||
sh_buf_tmp[0] = v < 0 ? 0 : (v >> SHADOW_UPSACALE_SHIFT);
|
sh_ups_blur_buf[y] = v < 0 ? 0 : (v >> SHADOW_UPSACALE_SHIFT);
|
||||||
|
|
||||||
/*Forget the top pixel*/
|
/*Forget the top pixel*/
|
||||||
uint32_t top_val;
|
uint32_t top_val;
|
||||||
@ -1018,8 +1012,14 @@ static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, lv_opa_t * res_bu
|
|||||||
else bottom_val = sh_ups_buf[(size - 1) * size + x];
|
else bottom_val = sh_ups_buf[(size - 1) * size + x];
|
||||||
v += bottom_val;
|
v += bottom_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*Write back the result into `sh_ups_buf`*/
|
||||||
|
sh_ups_tmp_buf = &sh_ups_buf[x];
|
||||||
|
for(y = 0; y < size; y++, sh_ups_tmp_buf += size) {
|
||||||
|
(*sh_ups_tmp_buf) = sh_ups_blur_buf[y];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_mem_buf_release(sh_ups_hor_buf);
|
lv_mem_buf_release(sh_ups_blur_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user