diff --git a/src/core/lv_refr.c b/src/core/lv_refr.c index ca78f4445..d692ebb8c 100644 --- a/src/core/lv_refr.c +++ b/src/core/lv_refr.c @@ -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; diff --git a/src/draw/lv_draw.c b/src/draw/lv_draw.c index e5e6573c5..b4c9b4abd 100644 --- a/src/draw/lv_draw.c +++ b/src/draw/lv_draw.c @@ -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; diff --git a/src/draw/lv_draw_buf.c b/src/draw/lv_draw_buf.c index b0be35072..fc9a8675f 100644 --- a/src/draw/lv_draw_buf.c +++ b/src/draw/lv_draw_buf.c @@ -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; diff --git a/src/draw/lv_draw_buf.h b/src/draw/lv_draw_buf.h index 12d442a63..4c1126959 100644 --- a/src/draw/lv_draw_buf.h +++ b/src/draw/lv_draw_buf.h @@ -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. diff --git a/src/draw/sw/lv_draw_sw_mask_rect.c b/src/draw/sw/lv_draw_sw_mask_rect.c index acd629413..019cc7fa0 100644 --- a/src/draw/sw/lv_draw_sw_mask_rect.c +++ b/src/draw/sw/lv_draw_sw_mask_rect.c @@ -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(¶m, &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; diff --git a/src/libs/tiny_ttf/lv_tiny_ttf.c b/src/libs/tiny_ttf/lv_tiny_ttf.c index 45ba8f770..1053637a0 100644 --- a/src/libs/tiny_ttf/lv_tiny_ttf.c +++ b/src/libs/tiny_ttf/lv_tiny_ttf.c @@ -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; diff --git a/src/widgets/canvas/lv_canvas.c b/src/widgets/canvas/lv_canvas.c index 5c0c14d33..0fe0e43c9 100644 --- a/src/widgets/canvas/lv_canvas.c +++ b/src/widgets/canvas/lv_canvas.c @@ -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) diff --git a/src/widgets/canvas/lv_canvas.h b/src/widgets/canvas/lv_canvas.h index cbb73a0ae..bb39f98c4 100644 --- a/src/widgets/canvas/lv_canvas.h +++ b/src/widgets/canvas/lv_canvas.h @@ -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