refact(layer): use draw_buf to replace raw pointers (#5254)

Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com>
Signed-off-by: Xu Xingliang <xuxingliang@xiaomi.com>
Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
Co-authored-by: Xu Xingliang <xuxingliang@xiaomi.com>
This commit is contained in:
_VIFEXTech
2024-01-14 20:47:20 +08:00
committed by GitHub
parent 4dd7773e25
commit 8701dece65
14 changed files with 98 additions and 118 deletions

View File

@@ -578,6 +578,21 @@ static void refr_invalid_areas(void)
LV_PROFILER_END;
}
/**
* Reshape the draw buffer if required
* @param layer pointer to a layer which will be drawn
*/
static void layer_reshape_draw_buf(lv_layer_t * layer)
{
LV_ASSERT(lv_draw_buf_reshape(
layer->draw_buf,
layer->color_format,
lv_area_get_width(&layer->buf_area),
lv_area_get_height(&layer->buf_area),
0)
!= NULL);
}
/**
* Refresh an area if there is Virtual Display Buffer
* @param area_p pointer to an area to refresh
@@ -586,7 +601,7 @@ static void refr_area(const lv_area_t * area_p)
{
LV_PROFILER_BEGIN;
lv_layer_t * layer = disp_refr->layer_head;
layer->buf = disp_refr->buf_act->data;
layer->draw_buf = disp_refr->buf_act;
/*With full refresh just redraw directly into the buffer*/
/*In direct mode draw directly on the absolute coordinates of the buffer*/
@@ -595,7 +610,7 @@ static void refr_area(const lv_area_t * area_p)
layer->buf_area.y1 = 0;
layer->buf_area.x2 = lv_display_get_horizontal_resolution(disp_refr) - 1;
layer->buf_area.y2 = lv_display_get_vertical_resolution(disp_refr) - 1;
layer->buf_stride = lv_draw_buf_width_to_stride(lv_area_get_width(&layer->buf_area), layer->color_format);
layer_reshape_draw_buf(layer);
lv_area_t disp_area;
lv_area_set(&disp_area, 0, 0, lv_display_get_horizontal_resolution(disp_refr) - 1,
lv_display_get_vertical_resolution(disp_refr) - 1);
@@ -632,10 +647,10 @@ static void refr_area(const lv_area_t * area_p)
sub_area.x2 = area_p->x2;
sub_area.y1 = row;
sub_area.y2 = row + max_row - 1;
layer->buf = disp_refr->buf_act->data;
layer->draw_buf = disp_refr->buf_act;
layer->buf_area = sub_area;
layer->buf_stride = lv_draw_buf_width_to_stride(lv_area_get_width(&layer->buf_area), layer->color_format);
layer->_clip_area = sub_area;
layer_reshape_draw_buf(layer);
if(sub_area.y2 > y2) sub_area.y2 = y2;
row_last = sub_area.y2;
if(y2 == row_last) disp_refr->last_part = 1;
@@ -649,9 +664,10 @@ static void refr_area(const lv_area_t * area_p)
sub_area.x2 = area_p->x2;
sub_area.y1 = row;
sub_area.y2 = y2;
layer->buf = disp_refr->buf_act->data;
layer->draw_buf = disp_refr->buf_act;
layer->buf_area = sub_area;
layer->_clip_area = sub_area;
layer_reshape_draw_buf(layer);
disp_refr->last_part = 1;
refr_area_part(layer);
}
@@ -672,7 +688,7 @@ static void refr_area_part(lv_layer_t * layer)
if(lv_color_format_has_alpha(disp_refr->color_format)) {
uint32_t w = lv_area_get_width(&layer->buf_area);
uint32_t h = lv_area_get_height(&layer->buf_area);
lv_draw_buf_clear(layer->buf, w, h, layer->color_format, &disp_refr->refreshed_area);
lv_draw_buf_clear(layer->draw_buf->data, w, h, layer->draw_buf->header.cf, &disp_refr->refreshed_area);
}
lv_obj_t * top_act_scr = NULL;
@@ -1010,7 +1026,7 @@ static void draw_buf_flush(lv_display_t * disp)
bool flushing_last = disp->flushing_last;
if(disp->flush_cb) {
call_flush_cb(disp, &disp->refreshed_area, layer->buf);
call_flush_cb(disp, &disp->refreshed_area, layer->draw_buf->data);
}
/*If there are 2 buffers swap them. With direct mode swap only on the last area*/
if(lv_display_is_double_buffered(disp) && (disp->render_mode != LV_DISPLAY_RENDER_MODE_DIRECT || flushing_last)) {

View File

@@ -81,7 +81,6 @@ lv_display_t * lv_display_create(int32_t hor_res, int32_t ver_res)
disp->layer_head->buf_area.y1 = 0;
disp->layer_head->buf_area.x2 = hor_res - 1;
disp->layer_head->buf_area.y2 = ver_res - 1;
disp->layer_head->buf_stride = lv_draw_buf_width_to_stride(hor_res, LV_COLOR_FORMAT_NATIVE);
disp->layer_head->color_format = disp->color_format;
disp->inv_en_cnt = 1;

View File

@@ -187,14 +187,15 @@ bool lv_draw_dispatch_layer(lv_display_t * disp, lv_layer_t * layer)
lv_draw_image_dsc_t * draw_image_dsc = t->draw_dsc;
lv_layer_t * layer_drawn = (lv_layer_t *)draw_image_dsc->src;
if(layer_drawn->buf) {
if(layer_drawn->draw_buf) {
int32_t h = lv_area_get_height(&layer_drawn->buf_area);
int32_t w = lv_area_get_width(&layer_drawn->buf_area);
uint32_t layer_size_byte = h * lv_draw_buf_width_to_stride(w, layer_drawn->color_format);
_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);
lv_draw_buf_free(layer_drawn->buf_unaligned);
lv_draw_buf_destroy(layer_drawn->draw_buf);
layer_drawn->draw_buf = NULL;
}
/*Remove the layer from the display's*/
@@ -345,7 +346,6 @@ lv_layer_t * lv_draw_layer_create(lv_layer_t * parent_layer, lv_color_format_t c
new_layer->parent = parent_layer;
new_layer->_clip_area = *area;
new_layer->buf_area = *area;
new_layer->buf_stride = lv_draw_buf_width_to_stride(lv_area_get_width(area), color_format);
new_layer->color_format = color_format;
if(disp->layer_head) {
@@ -362,51 +362,37 @@ lv_layer_t * lv_draw_layer_create(lv_layer_t * parent_layer, lv_color_format_t c
void * lv_draw_layer_alloc_buf(lv_layer_t * layer)
{
int32_t w = lv_area_get_width(&layer->buf_area);
uint32_t stride = lv_draw_buf_width_to_stride(w, layer->color_format);
/*If the buffer of the layer is not allocated yet, allocate it now*/
if(layer->buf == NULL) {
int32_t h = lv_area_get_height(&layer->buf_area);
uint32_t layer_size_byte = h * stride;
layer->buf_unaligned = lv_draw_buf_malloc(layer_size_byte, layer->color_format);
if(layer->buf_unaligned == NULL) {
LV_LOG_WARN("Allocating %"LV_PRIu32" bytes of layer buffer failed. Try later", layer_size_byte);
return NULL;
}
layer->buf = lv_draw_buf_align(layer->buf_unaligned, layer->color_format);
_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(lv_color_format_has_alpha(layer->color_format)) {
lv_area_t a;
a.x1 = 0;
a.y1 = 0;
a.x2 = w - 1;
a.y2 = h - 1;
lv_draw_buf_clear(layer->buf, w, h, layer->color_format, &a);
}
/*If the buffer of the layer is already allocated return it*/
if(layer->draw_buf != NULL) {
return layer->draw_buf->data;
}
/*Set the stride also for static allocated buffers as well as for new dynamically allocated*/
if(layer->buf_stride == 0) layer->buf_stride = stride;
/*If the buffer of the layer is not allocated yet, allocate it now*/
int32_t w = lv_area_get_width(&layer->buf_area);
int32_t h = lv_area_get_height(&layer->buf_area);
/*Make sure the buffer address is aligned in case of already allocated buffers*/
return lv_draw_buf_align(layer->buf, layer->color_format);
layer->draw_buf = lv_draw_buf_create(w, h, layer->color_format, 0);
if(layer->draw_buf == NULL) {
LV_LOG_WARN("Allocating layer buffer failed. Try later");
return NULL;
}
if(lv_color_format_has_alpha(layer->color_format)) {
lv_area_t a;
a.x1 = 0;
a.y1 = 0;
a.x2 = w - 1;
a.y2 = h - 1;
lv_draw_buf_clear(layer->draw_buf->data, w, h, layer->color_format, &a);
}
return layer->draw_buf->data;
}
void * lv_draw_layer_go_to_xy(lv_layer_t * layer, int32_t x, int32_t y)
{
lv_draw_buf_t tmp;
tmp.data = layer->buf;
tmp.header.stride = layer->buf_stride;
tmp.header.cf = layer->color_format;
tmp.header.w = lv_area_get_width(&layer->buf_area);
tmp.header.h = lv_area_get_height(&layer->buf_area);
return lv_draw_buf_goto_xy(&tmp, x, y);
return lv_draw_buf_goto_xy(layer->draw_buf, x, y);
}
/**********************

View File

@@ -146,13 +146,8 @@ struct _lv_draw_unit_t {
struct _lv_layer_t {
/** The unaligned buffer where drawing will happen*/
void * buf_unaligned;
/** The aligned buffer, result of lv_draw_buf_align(layer->buf_unaligned)*/
void * buf;
uint32_t buf_stride;
/** Target draw buffer of the layer*/
lv_draw_buf_t * draw_buf;
/** The absolute coordinates of the buffer */
lv_area_t buf_area;

View File

@@ -416,10 +416,5 @@ static uint32_t _calculate_draw_buf_size(uint32_t w, uint32_t h, lv_color_format
size += LV_COLOR_INDEXED_PALETTE_SIZE(cf) * 4;
}
/*RLE decompression operates on pixel unit, thus add padding to make sure memory is enough*/
uint8_t bpp = lv_color_format_get_bpp(cf);
bpp = (bpp + 7) >> 3;
size += bpp;
return size;
}

View File

@@ -73,22 +73,11 @@ void lv_draw_sw_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dr
/*It can happen that nothing was draw on a layer and therefore its buffer is not allocated.
*In this case just return. */
if(layer_to_draw->buf == NULL) return;
lv_image_dsc_t img_dsc = { 0 };
img_dsc.header.w = lv_area_get_width(&layer_to_draw->buf_area);
img_dsc.header.h = lv_area_get_height(&layer_to_draw->buf_area);
img_dsc.header.cf = layer_to_draw->color_format;
img_dsc.header.stride = layer_to_draw->buf_stride;
img_dsc.data = layer_to_draw->buf;
lv_draw_image_dsc_t new_draw_dsc;
lv_memcpy(&new_draw_dsc, draw_dsc, sizeof(lv_draw_image_dsc_t));
new_draw_dsc.src = &img_dsc;
if(layer_to_draw->draw_buf == NULL) return;
lv_draw_image_dsc_t new_draw_dsc = *draw_dsc;
new_draw_dsc.src = layer_to_draw->draw_buf;
lv_draw_sw_image(draw_unit, &new_draw_dsc, coords);
lv_image_cache_drop(&img_dsc);
#if LV_USE_LAYER_DEBUG || LV_USE_PARALLEL_DRAW_DEBUG
lv_area_t area_rot;
lv_area_copy(&area_rot, coords);

View File

@@ -56,27 +56,29 @@ void lv_draw_sw_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_rect_ds
int32_t buf_h = lv_area_get_height(&target_layer->buf_area);
lv_area_t clear_area;
void * buf = target_layer->draw_buf->data;
/*Clear the top part*/
lv_area_set(&clear_area, draw_unit->clip_area->x1, draw_unit->clip_area->y1, draw_unit->clip_area->x2,
dsc->area.y1 - 1);
lv_area_move(&clear_area, -target_layer->buf_area.x1, -target_layer->buf_area.y1);
lv_draw_buf_clear(target_layer->buf, buf_w, buf_h, target_layer->color_format, &clear_area);
lv_draw_buf_clear(buf, buf_w, buf_h, target_layer->color_format, &clear_area);
/*Clear the bottom part*/
lv_area_set(&clear_area, draw_unit->clip_area->x1, dsc->area.y2 + 1, draw_unit->clip_area->x2,
draw_unit->clip_area->y2);
lv_area_move(&clear_area, -target_layer->buf_area.x1, -target_layer->buf_area.y1);
lv_draw_buf_clear(target_layer->buf, buf_w, buf_h, target_layer->color_format, &clear_area);
lv_draw_buf_clear(buf, buf_w, buf_h, target_layer->color_format, &clear_area);
/*Clear the left part*/
lv_area_set(&clear_area, draw_unit->clip_area->x1, dsc->area.y1, dsc->area.x1 - 1, dsc->area.y2);
lv_area_move(&clear_area, -target_layer->buf_area.x1, -target_layer->buf_area.y1);
lv_draw_buf_clear(target_layer->buf, buf_w, buf_h, target_layer->color_format, &clear_area);
lv_draw_buf_clear(buf, buf_w, buf_h, target_layer->color_format, &clear_area);
/*Clear the right part*/
lv_area_set(&clear_area, dsc->area.x2 + 1, dsc->area.y1, draw_unit->clip_area->x2, dsc->area.y2);
lv_area_move(&clear_area, -target_layer->buf_area.x1, -target_layer->buf_area.y1);
lv_draw_buf_clear(target_layer->buf, buf_w, buf_h, target_layer->color_format, &clear_area);
lv_draw_buf_clear(buf, buf_w, buf_h, target_layer->color_format, &clear_area);
lv_draw_sw_mask_radius_param_t param;
lv_draw_sw_mask_radius_init(&param, &dsc->area, dsc->radius, false);

View File

@@ -427,22 +427,24 @@ void lv_draw_sw_vector(lv_draw_unit_t * draw_unit, const lv_draw_vector_task_dsc
return;
lv_layer_t * layer = dsc->base.layer;
if(layer->buf == NULL)
lv_draw_buf_t * draw_buf = layer->draw_buf;
if(draw_buf == NULL)
return;
if(layer->color_format != LV_COLOR_FORMAT_ARGB8888 && \
layer->color_format != LV_COLOR_FORMAT_XRGB8888) {
LV_LOG_ERROR("unsupported layer color: %d", layer->color_format);
lv_color_format_t cf = draw_buf->header.cf;
if(cf != LV_COLOR_FORMAT_ARGB8888 && \
cf != LV_COLOR_FORMAT_XRGB8888) {
LV_LOG_ERROR("unsupported layer color: %d", cf);
return;
}
void * buf = layer->buf;
void * buf = draw_buf->data;
int32_t width = lv_area_get_width(&layer->buf_area);
int32_t height = lv_area_get_height(&layer->buf_area);
uint32_t stride = layer->buf_stride;
stride /= 4;
uint32_t stride = draw_buf->header.stride;
Tvg_Canvas * canvas = tvg_swcanvas_create();
tvg_swcanvas_set_target(canvas, buf, stride, width, height, TVG_COLORSPACE_ARGB8888);
tvg_swcanvas_set_target(canvas, buf, stride / 4, width, height, TVG_COLORSPACE_ARGB8888);
lv_ll_t * task_list = dsc->task_list;
_lv_vector_for_each_destroy_tasks(task_list, _task_draw_cb, canvas);

View File

@@ -89,15 +89,7 @@ static void draw_execute(lv_draw_vg_lite_unit_t * u)
lv_layer_t * layer = u->base_unit.target_layer;
lv_draw_buf_t draw_buf = { 0 };
uint32_t w, h, stride;
w = lv_area_get_width(&layer->buf_area);
h = lv_area_get_height(&layer->buf_area);
stride = lv_draw_buf_width_to_stride(w, layer->color_format);
lv_image_header_init(&draw_buf.header, w, h, layer->color_format, stride, 0);
draw_buf.data = layer->buf;
lv_vg_lite_buffer_from_draw_buf(&u->target_buffer, &draw_buf);
lv_vg_lite_buffer_from_draw_buf(&u->target_buffer, layer->draw_buf);
vg_lite_identity(&u->global_matrix);
vg_lite_translate(-layer->buf_area.x1, -layer->buf_area.y1, &u->global_matrix);
@@ -160,11 +152,6 @@ static int32_t draw_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer)
return 0;
}
/* Return if target buffer format is not supported. */
if(!lv_vg_lite_is_dest_cf_supported(layer->color_format)) {
return -1;
}
/* Try to get an ready to draw. */
lv_draw_task_t * t = lv_draw_get_next_available_task(layer, NULL, VG_LITE_DRAW_UNIT_ID);
@@ -178,6 +165,11 @@ static int32_t draw_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer)
return -1;
}
/* Return if target buffer format is not supported. */
if(!lv_vg_lite_is_dest_cf_supported(layer->draw_buf->header.cf)) {
return -1;
}
t->state = LV_DRAW_TASK_STATE_IN_PROGRESS;
draw_vg_lite_unit->base_unit.target_layer = layer;
draw_vg_lite_unit->base_unit.clip_area = &t->clip_area;

View File

@@ -45,24 +45,18 @@ void lv_draw_vg_lite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t
/*It can happen that nothing was draw on a layer and therefore its buffer is not allocated.
*In this case just return. */
if(layer->buf == NULL)
if(layer->draw_buf == NULL)
return;
lv_image_dsc_t img_dsc;
lv_memzero(&img_dsc, sizeof(lv_image_dsc_t));
img_dsc.header.w = lv_area_get_width(&layer->buf_area);
img_dsc.header.h = lv_area_get_height(&layer->buf_area);
img_dsc.header.cf = layer->color_format;
img_dsc.data = layer->buf;
/* The GPU output is premultiplied RGB */
img_dsc.header.flags = LV_IMAGE_FLAGS_PREMULTIPLIED;
/* The GPU output should already be premultiplied RGB */
if((layer->draw_buf->header.flags & LV_IMAGE_FLAGS_PREMULTIPLIED) == 0) {
LV_LOG_WARN("GPU output is not premultiplied RGB.");
layer->draw_buf->header.flags |= LV_IMAGE_FLAGS_PREMULTIPLIED;
}
lv_draw_image_dsc_t new_draw_dsc = *draw_dsc;
new_draw_dsc.src = &img_dsc;
new_draw_dsc.src = layer->draw_buf;
lv_draw_vg_lite_img(draw_unit, &new_draw_dsc, coords);
lv_image_cache_drop(&img_dsc);
}
/**********************

View File

@@ -52,7 +52,7 @@ void lv_draw_vg_lite_vector(lv_draw_unit_t * draw_unit, const lv_draw_vector_tas
return;
lv_layer_t * layer = dsc->base.layer;
if(layer->buf == NULL)
if(layer->draw_buf == NULL)
return;
_lv_vector_for_each_destroy_tasks(dsc->task_list, task_draw_cb, draw_unit);

View File

@@ -1039,6 +1039,13 @@ static lv_result_t decompress_image(lv_image_decoder_dsc_t * dsc, const lv_image
uint32_t out_len = compressed->decompressed_size;
uint32_t input_len = compressed->compressed_size;
LV_UNUSED(input_len);
/**
* @todo
* FIXME, RLE compressed image needs extra memory because decompression operates on
* pixel unit not byte unit. Should optimize RLE decompress to not write to extra memory.
*/
dsc->header.h += 1;
lv_draw_buf_t * decompressed = lv_draw_buf_create(dsc->header.w, dsc->header.h, dsc->header.cf,
dsc->header.stride);
if(decompressed == NULL) {
@@ -1046,6 +1053,7 @@ static lv_result_t decompress_image(lv_image_decoder_dsc_t * dsc, const lv_image
return LV_RESULT_INVALID;
}
dsc->header.h -= 1; /*Change it back*/
if(decompressed->data_size < out_len) {
LV_LOG_WARN("decompressed size mismatch: %" LV_PRIu32 ", %" LV_PRIu32, decompressed->data_size, out_len);
lv_draw_buf_destroy(decompressed);

View File

@@ -111,7 +111,10 @@ lv_result_t lv_snapshot_take_to_buf(lv_obj_t * obj, lv_color_format_t cf, lv_ima
lv_layer_t layer;
lv_memzero(&layer, sizeof(layer));
layer.buf = buf;
lv_draw_buf_t draw_buf;
lv_draw_buf_from_image(&draw_buf, dsc);
layer.draw_buf = &draw_buf;
layer.buf_area.x1 = snapshot_area.x1;
layer.buf_area.y1 = snapshot_area.y1;
layer.buf_area.x2 = snapshot_area.x1 + w - 1;

View File

@@ -346,11 +346,10 @@ void lv_canvas_init_layer(lv_obj_t * obj, lv_layer_t * layer)
lv_area_t canvas_area = {0, 0, header->w - 1, header->h - 1};
lv_memzero(layer, sizeof(*layer));
layer->buf = canvas->draw_buf->data;
layer->draw_buf = canvas->draw_buf;
layer->color_format = header->cf;
layer->buf_area = canvas_area;
layer->_clip_area = canvas_area;
layer->buf_stride = header->stride;
}
void lv_canvas_finish_layer(lv_obj_t * canvas, lv_layer_t * layer)