LVGL 9 lv_canvas_copy_buf confusion

Description

What LVGL version are you using?

9.2.0

What do you want to achieve?

Copy data into lv_canvas, as could do in LVGL 8.x.x

The latest documentation for Canvas in v9.2.0 states:

An array of pixels can be copied to the canvas with lv_canvas_copy_buf(canvas, buffer_to_copy, x, y, width, height). The color format of the buffer and the canvas need to match

However, that is the function signature from v8.x.x and has now changed to:

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)

So the documentation is incorrect, but I am confused by the dest_buf and dest_area attributes. canvas.h states dest_buf is “pointer to a buffer to store the copied data”, but surely the canvas obj is the destination buffer to store the copied data? The usage in 8.x.x was to copy to the canvas (destination) from somewhere else (source), but this description appears to be the opposite?

This is used to copy the buffer data FROM the canvas to another buffer. Not to copy an external buffer onto the canvas.

the canvas_area parameter is the area of the canvas buffer you wish to copy. if you want to copy the entire canvas buffer then you would need to supply an area where

x1 = 0
y1 = 0
x2 = width
y2 = height

The dest_area parameter is where in the destination buffer you want to copy the data to. The size of the dest_area must match the size of the canvas_area. The last piece to the puzzle is dest_buf. This is not an array that gets supplied. you need to supply a pointer to lv_draw_buf_t and in that is the array and there are also other pieces of information like the size and the color format. The size must be large enough to hold the data you are wanting to copy and the color format must match the color format the canvas is set to.

Are you sure it is to copy FROM the canvas? In LVGL 8 it copied an external buffer TO the canvas and as I mention below, it copies TO the canvas in LVGL 9.x.x

The implementation of lv_canvas_copy_buf basically calls lv_draw_buf_copy like so:

lv_draw_buf_copy(canvas->draw_buf, canvas_area, dest_buf, dest_area);

which is described as:

/**
 * Copy an area from a buffer to another
 * @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(lv_draw_buf_t * dest, const lv_area_t * dest_area,
                      const lv_draw_buf_t * src, const lv_area_t * src_area);

So, this is how lv_draw_buf_copy is called:

dest: canvas->draw_buf
dest_area: canvas_area
src:  dest_buf
src_area: dest_area

The destination is the canvas, and the source is the buffer.

I actually figured out the creation of lv_draw_buf_t to contain my data and used lv_canvas_copy_buf(canvas, &canvas_area, &draw_buf, &canvas_area); and it copied draw_buf TO the canvas, as it did in LVGL 8.x.x (I used the same co-ords for source and dest as they are the same)

So, by the actual execution result, the header documentation of lv_draw_buf_copy and how that is called, and the written documentation for lv_canvas_copy_buf, the parameters for lv_canvas_copy_buf named as dest are actually src, and the canvas is the dest

That is incorrect. The names are correctm because lv_canvas_copy_buf copies data from the canvas to an external buffer. the external buffer is the destination.

You did exactly what is supposed to be done to copy a buffer to the the canvas. the canvas widget no longer has the ability to render anything. everything is handled by using layers and the lv_draw_* functions. This was done to get the benefits of graphics acceleration that some MCU’s have.

If the function is actually copying data from an external buffer to the canvas then the parameter names are incorrect and you should open an issue on LVGL’s GitHub repository to have it fixed.

I’ll do that, eventually. I posted a forum question wanting to clarify my understanding as I hadn’t been able to port my code to LVGL 9 at the time, so wasn’t sure. Now I have it working, it’s clearly incorrectly named. I’ve found a good 15-20 documentation issues, so I’ll gather them up and mention them on GitHub.