1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

feat(draw_buf): use lv_draw_buf_t as argument of API lv_draw_buf_clear/copy (#5322)

Signed-off-by: Xu Xingliang <xuxingliang@xiaomi.com>
This commit is contained in:
Neo Xu 2024-01-15 18:37:38 +08:00 committed by GitHub
parent adfd8c2e8b
commit 57cda3b91c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 95 additions and 118 deletions

View File

@ -478,8 +478,6 @@ static void refr_sync_areas(void)
*So the active buffer is the off screen buffer where LVGL will render*/
lv_draw_buf_t * on_screen = disp_refr->buf_act;
lv_draw_buf_t * off_screen = disp_refr->buf_act == disp_refr->buf_1 ? disp_refr->buf_2 : disp_refr->buf_1;
void * buf_off_screen = on_screen->data;
void * buf_on_screen = off_screen->data;
uint32_t hor_res = lv_display_get_horizontal_resolution(disp_refr);
uint32_t ver_res = lv_display_get_vertical_resolution(disp_refr);
@ -527,11 +525,7 @@ static void refr_sync_areas(void)
* @todo Resize SDL window will trigger crash because of sync_area is larger than disp_area
*/
_lv_area_intersect(sync_area, sync_area, &disp_area);
lv_draw_buf_copy(
buf_off_screen, hor_res, ver_res, sync_area,
buf_on_screen, hor_res, ver_res, sync_area,
lv_display_get_color_format(disp_refr)
);
lv_draw_buf_copy(off_screen, sync_area, on_screen, sync_area);
}
/*Clear sync areas*/
@ -686,9 +680,7 @@ static void refr_area_part(lv_layer_t * layer)
}
/*If the screen is transparent initialize it when the flushing is ready*/
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->draw_buf->data, w, h, layer->draw_buf->header.cf, &disp_refr->refreshed_area);
lv_draw_buf_clear(layer->draw_buf, &disp_refr->refreshed_area);
}
lv_obj_t * top_act_scr = NULL;

View File

@ -384,7 +384,7 @@ void * lv_draw_layer_alloc_buf(lv_layer_t * layer)
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);
lv_draw_buf_clear(layer->draw_buf, &a);
}
return layer->draw_buf->data;

View File

@ -84,54 +84,73 @@ void lv_draw_buf_invalidate_cache(void * buf, uint32_t stride, lv_color_format_t
if(handlers.invalidate_cache_cb) handlers.invalidate_cache_cb(buf, stride, color_format, area);
}
void lv_draw_buf_clear(void * buf, uint32_t w, uint32_t h, lv_color_format_t color_format, const lv_area_t * a)
void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a)
{
LV_UNUSED(h);
if(lv_area_get_width(a) < 0) return;
if(lv_area_get_height(a) < 0) return;
LV_ASSERT_NULL(draw_buf);
if(a && lv_area_get_width(a) < 0) return;
if(a && lv_area_get_height(a) < 0) return;
uint8_t px_size = lv_color_format_get_size(color_format);
uint32_t stride = lv_draw_buf_width_to_stride(w, color_format);
uint8_t * bufc = buf;
const lv_image_header_t * header = &draw_buf->header;
uint32_t stride = header->stride;
/*Got the first pixel of each buffer*/
bufc += stride * a->y1;
bufc += a->x1 * px_size;
uint32_t line_length = lv_area_get_width(a) * px_size;
int32_t y;
for(y = a->y1; y <= a->y2; y++) {
lv_memzero(bufc, line_length);
bufc += stride;
if(a == NULL) {
lv_memzero(draw_buf->data, header->h * stride);
}
else {
uint8_t * bufc;
uint32_t line_length;
int32_t start_y, end_y;
uint8_t px_size = lv_color_format_get_size(header->cf);
bufc = lv_draw_buf_goto_xy(draw_buf, a->x1, a->y1);
line_length = lv_area_get_width(a) * px_size;
start_y = a->y1;
end_y = a->y2;
for(; start_y <= end_y; start_y++) {
lv_memzero(bufc, line_length);
bufc += stride;
}
}
}
void lv_draw_buf_copy(void * dest_buf, uint32_t dest_w, uint32_t dest_h, const lv_area_t * dest_area_to_copy,
void * src_buf, uint32_t src_w, uint32_t src_h, const lv_area_t * src_area_to_copy,
lv_color_format_t color_format)
void lv_draw_buf_copy(lv_draw_buf_t * dest, const lv_area_t * dest_area,
const lv_draw_buf_t * src, const lv_area_t * src_area)
{
LV_UNUSED(dest_h);
LV_UNUSED(src_h);
uint8_t * dest_bufc;
uint8_t * src_bufc;
int32_t line_width;
uint8_t px_size = lv_color_format_get_size(color_format);
uint8_t * dest_bufc = dest_buf;
uint8_t * src_bufc = src_buf;
if(dest_area == NULL) line_width = dest->header.w;
else line_width = lv_area_get_width(dest_area);
uint32_t dest_stride = lv_draw_buf_width_to_stride(dest_w, color_format);
uint32_t src_stride = lv_draw_buf_width_to_stride(src_w, color_format);
/*Check source and dest area have same width*/
if((src_area == NULL && line_width != src->header.w) || \
(src_area != NULL && line_width != lv_area_get_width(src_area))) {
LV_ASSERT_MSG(0, "Source and destination areas have different width");
return;
}
/*Got the first pixel of each buffer*/
dest_bufc += dest_stride * dest_area_to_copy->y1;
dest_bufc += dest_area_to_copy->x1 * px_size;
if(src_area) src_bufc = lv_draw_buf_goto_xy(src, src_area->x1, src_area->y1);
else src_bufc = src->data;
src_bufc += src_stride * src_area_to_copy->y1;
src_bufc += src_area_to_copy->x1 * px_size;
if(dest_area) dest_bufc = lv_draw_buf_goto_xy(dest, dest_area->x1, dest_area->y1);
else dest_bufc = dest->data;
uint32_t line_length = lv_area_get_width(dest_area_to_copy) * px_size;
int32_t y;
for(y = dest_area_to_copy->y1; y <= dest_area_to_copy->y2; y++) {
lv_memcpy(dest_bufc, src_bufc, line_length);
int32_t start_y, end_y;
if(dest_area) {
start_y = dest_area->y1;
end_y = dest_area->y2;
}
else {
start_y = 0;
end_y = dest->header.h - 1;
}
uint32_t dest_stride = dest->header.stride;
uint32_t src_stride = src->header.stride;
line_width *= lv_color_format_get_size(dest->header.cf); /*Pixel to bytes*/
for(; start_y <= end_y; start_y++) {
lv_memcpy(dest_bufc, src_bufc, line_width);
dest_bufc += dest_stride;
src_bufc += src_stride;
}
@ -246,7 +265,7 @@ void lv_draw_buf_destroy(lv_draw_buf_t * buf)
}
}
void * lv_draw_buf_goto_xy(lv_draw_buf_t * buf, uint32_t x, uint32_t y)
void * lv_draw_buf_goto_xy(const lv_draw_buf_t * buf, uint32_t x, uint32_t y)
{
LV_ASSERT_NULL(buf);
if(buf == NULL) return NULL;

View File

@ -146,29 +146,21 @@ uint32_t lv_draw_buf_width_to_stride(uint32_t w, lv_color_format_t color_format)
/**
* Clear an area on the buffer
* @param draw_buf pointer to draw buffer
* @param w width of the buffer
* @param h height of the buffer
* @param color_format color format of the buffer
* @param a the area to clear, or NULL to clear the whole buffer
*/
void lv_draw_buf_clear(void * buf, uint32_t w, uint32_t h, lv_color_format_t color_format, const lv_area_t * a);
void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a);
/**
* Copy an area from a buffer to an other
* @param dest_buf pointer to the destination buffer)
* @param dest_w width of the destination buffer in pixels
* @param dest_h height of the destination buffer in pixels
* @param dest_area_to_copy the area to copy from the destination buffer
* @param src_buf pointer to the source buffer
* @param src_w width of the source buffer in pixels
* @param src_h height of the source buffer in pixels
* @param src_area_to_copy the area to copy from the destination buffer
* @param color_format the color format, should be the same for both buffers
* @note `dest_area_to_copy` and `src_area_to_copy` should have the same width and height
* @param dest pointer to the destination draw buffer
* @param dest_area the area to copy from the destination buffer, if NULL, use the whole buffer
* @param src pointer to the source draw buffer
* @param src_area the area to copy from the destination buffer, if NULL, use the whole buffer
* @note `dest_area` and `src_area` should have the same width and height
* @note `dest` and `src` should have same color format. Color converting is not supported fow now.
*/
void lv_draw_buf_copy(void * dest_buf, uint32_t dest_w, uint32_t dest_h, const lv_area_t * dest_area_to_copy,
void * src_buf, uint32_t src_w, uint32_t src_h, const lv_area_t * src_area_to_copy,
lv_color_format_t color_format);
void lv_draw_buf_copy(lv_draw_buf_t * dest, const lv_area_t * dest_area,
const lv_draw_buf_t * src, const lv_area_t * src_area);
/**
* Note: Eventually, lv_draw_buf_malloc/free will be kept as private.
@ -227,7 +219,7 @@ void lv_draw_buf_destroy(lv_draw_buf_t * buf);
/**
* Return pointer to the buffer at the given coordinates
*/
void * lv_draw_buf_goto_xy(lv_draw_buf_t * buf, uint32_t x, uint32_t y);
void * lv_draw_buf_goto_xy(const lv_draw_buf_t * buf, uint32_t x, uint32_t y);
/**
* Adjust the stride of a draw buf.

View File

@ -51,34 +51,32 @@ void lv_draw_sw_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_rect_ds
}
lv_layer_t * target_layer = draw_unit->target_layer;
int32_t buf_w = lv_area_get_width(&target_layer->buf_area);
int32_t buf_h = lv_area_get_height(&target_layer->buf_area);
lv_area_t * buf_area = &target_layer->buf_area;
lv_area_t clear_area;
void * buf = target_layer->draw_buf->data;
void * draw_buf = target_layer->draw_buf;
/*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(buf, buf_w, buf_h, target_layer->color_format, &clear_area);
lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1);
lv_draw_buf_clear(draw_buf, &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(buf, buf_w, buf_h, target_layer->color_format, &clear_area);
lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1);
lv_draw_buf_clear(draw_buf, &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(buf, buf_w, buf_h, target_layer->color_format, &clear_area);
lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1);
lv_draw_buf_clear(draw_buf, &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(buf, buf_w, buf_h, target_layer->color_format, &clear_area);
lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1);
lv_draw_buf_clear(draw_buf, &clear_area);
lv_draw_sw_mask_radius_param_t param;
lv_draw_sw_mask_radius_init(&param, &dsc->area, dsc->radius, false);
@ -95,8 +93,8 @@ void lv_draw_sw_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_rect_ds
lv_draw_sw_mask_res_t res = lv_draw_sw_mask_apply(masks, mask_buf, draw_area.x1, y, area_w);
if(res == LV_DRAW_SW_MASK_RES_FULL_COVER) continue;
lv_color32_t * c32_buf = lv_draw_layer_go_to_xy(target_layer, draw_area.x1 - target_layer->buf_area.x1,
y - target_layer->buf_area.y1);
lv_color32_t * c32_buf = lv_draw_layer_go_to_xy(target_layer, draw_area.x1 - buf_area->x1,
y - buf_area->y1);
if(res == LV_DRAW_SW_MASK_RES_TRANSP) {
uint32_t i;

View File

@ -355,13 +355,9 @@ static bool tiny_ttf_cache_create_cb(tiny_ttf_cache_data_t * node, void * user_d
return false;
}
lv_image_header_t * header = &draw_buf->header;
uint32_t stride = header->stride;
lv_draw_buf_clear(draw_buf, NULL);
/**
* @todo use `lv_draw_buf_clear` instead.
*/
memset(draw_buf->data, 0, h * stride);
uint32_t stride = draw_buf->header.stride;
stbtt_MakeGlyphBitmap(info, draw_buf->data, w, h, stride, dsc->scale, dsc->scale, g1);
node->draw_buf = draw_buf;

View File

@ -246,36 +246,18 @@ const void * lv_canvas_get_buf(lv_obj_t * obj)
* Other functions
*====================*/
void lv_canvas_copy_buf(lv_obj_t * obj, const void * to_copy, int32_t x, int32_t y, int32_t w, int32_t h)
void lv_canvas_copy_buf(lv_obj_t * obj, const lv_area_t * canvas_area, lv_draw_buf_t * dest_buf,
const lv_area_t * dest_area)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
LV_ASSERT_NULL(to_copy);
LV_ASSERT_NULL(canvas_area && dest_buf);
lv_canvas_t * canvas = (lv_canvas_t *)obj;
if(canvas->draw_buf == NULL) return;
lv_image_header_t * header = &canvas->draw_buf->header;
if(x + w - 1 >= (int32_t)header->w || y + h - 1 >= (int32_t)header->h) {
LV_LOG_WARN("x or y out of the canvas");
return;
}
LV_ASSERT_MSG(canvas->draw_buf->header.cf != dest_buf->header.cf, "Color formats must be the same");
lv_area_t src_area_to_copy;
lv_area_set(&src_area_to_copy, 0, 0, w - 1, h - 1);
lv_area_t dest_area_to_copy;
lv_area_set(&dest_area_to_copy, x, y, x + w - 1, y + h - 1);
lv_draw_buf_copy(
canvas->draw_buf->data,
header->w,
header->h,
&dest_area_to_copy,
(void *)to_copy,
w,
h,
&src_area_to_copy,
header->cf);
lv_draw_buf_copy(canvas->draw_buf, canvas_area, dest_buf, dest_area);
}
void lv_canvas_fill_bg(lv_obj_t * obj, lv_color_t color, lv_opa_t opa)

View File

@ -138,16 +138,14 @@ const void * lv_canvas_get_buf(lv_obj_t * canvas);
/**
* Copy a buffer to the canvas
* @param canvas pointer to a canvas object
* @param to_copy buffer to copy. The color format has to match with the canvas's buffer color
* format
* @param x left side of the destination position
* @param y top side of the destination position
* @param w width of the buffer to copy
* @param h height of the buffer to copy
* @param canvas pointer to a canvas object
* @param canvas_area the area of the canvas to copy
* @param dest_buf pointer to a buffer to store the copied data
* @param dest_area the area of the destination buffer to copy to. If omitted NULL, copy to the whole `dest_buf`
*/
void lv_canvas_copy_buf(lv_obj_t * canvas, const void * to_copy, int32_t x, int32_t y, int32_t w,
int32_t h);
void lv_canvas_copy_buf(lv_obj_t * obj, const lv_area_t * canvas_area, lv_draw_buf_t * dest_buf,
const lv_area_t * dest_area);
/**
* Fill the canvas with color
* @param canvas pointer to a canvas