Canvas is blank, regardless of what's drawn into it, SDL

Canvas is always blank

I am have been developing an application using SDL (eventually to be run on Raspi) and things were going smoothly so far, until i tried to draw a custom shape using canvas. I am seeing an empty square being rendered. I have been using the sample demo code void lv_example_canvas_1(void) that comes with lvgl/demos.

I have modified the demo code a little bit to add the border and a fixed size around the canvas just to make sure I could see where I should be looking.


    lv_obj_t *canvas = lv_canvas_create(lv_scr_act());
    lv_obj_set_style_border_color(canvas, lv_color_black(), LV_PART_MAIN);
    lv_obj_set_style_border_width(canvas, 1, LV_PART_MAIN);
    lv_obj_set_size(canvas, CANVAS_WIDTH, CANVAS_HEIGHT);

    lv_canvas_set_buffer(canvas, cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_NATIVE);
    lv_canvas_fill_bg(canvas, lv_color_black(), LV_OPA_COVER);

The border itself works as expected, however the content continues to be non-existent.

Any idea what I could be missing? What is different about how canvas works compared to other widgets that the borders have no issues showing but the content does not? Is it possible something is misconfigured in lv_conf or sdl?

I think if someone could shine some light onto how canvas is different from let’s say images (which work fine for me), may be it could point me to the right direction.

Also, i see no warnings, no errors of any sort. Application runs with nothing being painted.

What MCU/Processor/Board and compiler are you using?


What LVGL version are you using?


What do you want to achieve?

I would like to see what’s being drawn into the canvas.

Screenshot and/or video

Not sure why you are having an issue with it. It works on the CPython binding I wrote which uses SDL as well.

Double check what you have your color depth set to, it should be 32 bit. change how you are creating the buffer. Make the buffer in this manner.

I think this is correct c syntax. It might not be but it gives you the general idea.

static lv_color_t cbuf[] = (lv_color_t *) lv_malloc(sizeof(lv_color_t) * CANVAS_WIDTH * CANVAS_HEIGHT);

Tho I did port your code to the CPython binding I am working on, it uses SDL also and it appears to be working without any issue.

I am using the dark theme so I changed the border color to white for the canvas.

if you have the color depth set to 16bit then using the LV_CANVAS_BUF_SIZE_TRUE_COLOR is going to return an incorrect buffer size. This is because on 16bit color there is (technically speaking) no alpha channel. The canvas needs to be sized for an alpha channel with it. Using the LV_CANVAS_BUF_SIZE_TRUE_COLOR_ALPHA macro is better suited and it will return a proper size for the buffer.

That being said… I would have to look at the code for the canvas but I believe the canvas buffer actually needs to be set to support 32 bit color. it all depends on how the canvas writes the data to the buffer whether it is before conversion to 16 bit color or after conversion. I will look and see how it is being done.

By the means of the very sophisticated and well thought-through try-this-try-that methodology, I got the canvas to show up.

I have changed:

lv_canvas_set_buffer(canvas, cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_NATIVE);


lv_canvas_set_buffer(canvas, cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_IMG_CF_TRUE_COLOR);


I am still not exactly clear on what this does differently and would really appreciate if someone clarified what that parameter does exactly and how come it works in a different setting (e.g. master).

I assume, I got affected by looking at the wrong version of the documentation. The example was from the newer version of lvgl compared to the one I have. That’s my guess. So I was supplying a completely wrong constant.

I assumed you were using 9.0 because of you using the LV_COLOR_FORMAT_NATIVE enumeration. That is by fault and I should have asked.

Glad you got to the bottom of the problem.