Issues rendering non-trivial shapes on TI MCU

Description

Firstly - thanks for developing and sharing such a powerful and usable piece of software.

The issue I’m having is trouble rendering widgets more complex than simple squares. For example, the screenshot should be rendering a rounded corner box, size 20 text saying hello world, and a line meter in the top left. When I paint the screen one color or draw a plain object (shaped as a rectangle), both the color and shape render perfectly.

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

TI TMS320F28379D (on a LAUNCHXL-F28379D Delfino dev board) using a TI C2000 compiler.

What do you experience?

Strange artifacts, omissions, and incorrect shapes.

What do you expect?

Please see the screenshot below.

Code to reproduce

static void hello_world(void) {

    /*Create a Label on the currently active screen*/
    lv_obj_t *label1 =  lv_label_create(lv_scr_act(), NULL);

    /*Modify the Label's text*/
    lv_label_set_text(label1, "Hello world!");

    static lv_style_t text_style;
    lv_style_init(&text_style);
    lv_style_set_text_color(&text_style, LV_STATE_DEFAULT, lv_color_hex(0xff3a43));
    lv_obj_add_style(label1, LV_LABEL_PART_MAIN, &text_style);

    /* Align the Label to the center
     * NULL means align on parent (which is the screen now)
     * 0, 0 at the end means an x, y offset after alignment*/
    lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, 0);
}

void test_box(void)
{
    static lv_style_t style;
    lv_style_init(&style);

    /*Make a gradient*/
    lv_style_set_bg_opa(&style, LV_STATE_DEFAULT, LV_OPA_COVER);
    lv_style_set_bg_color(&style, LV_STATE_DEFAULT, LV_COLOR_TEAL);
    lv_style_set_border_width(&style, LV_STATE_DEFAULT, 0);

    lv_style_set_radius(&style, LV_STATE_DEFAULT, 50);

    /*Create an object with the new style*/
    lv_obj_t * obj = lv_obj_create(lv_scr_act(), NULL);
    lv_obj_add_style(obj, LV_OBJ_PART_MAIN, &style);
    lv_obj_align(obj, NULL, LV_ALIGN_CENTER, 0, 0);

    lv_obj_set_size(obj, 80, 180);

    lv_obj_align(obj, NULL, LV_ALIGN_CENTER, 0, 0);
}

void make_line_meter(lv_obj_t * container, const char* label_text, const int value, const char* value_label) {

    /*
     * Create a top-level object
     *
     */
    lv_obj_t * top_object = lv_obj_create(container, NULL);

    const lv_coord_t width = 65;
    const lv_coord_t height = 70;

    //lv_obj_set_size(top_object, width, height);
    lv_obj_set_width(top_object, width);
    lv_obj_set_height(top_object, height);

    static lv_style_t top_object_style;
    lv_style_init(&top_object_style);
    lv_style_set_border_width(&top_object_style, LV_STATE_DEFAULT, 0);
    lv_style_set_shadow_width(&top_object_style, LV_STATE_DEFAULT, 0);
    lv_obj_add_style(top_object, LV_OBJ_PART_MAIN, &top_object_style);
    //lv_obj_align(top_object, container, LV_ALIGN_CENTER);

    /*
     * Create and style the label object
     *
     */
    lv_obj_t * label_object = lv_label_create(top_object, NULL);
    lv_label_set_text(label_object, label_text);

    static lv_style_t label_style;
    lv_style_init(&label_style);
    lv_style_set_text_font(&label_style, LV_STATE_DEFAULT, &lv_font_montserrat_12);
    lv_obj_add_style(label_object, LV_LABEL_PART_MAIN, &label_style);

    const lv_coord_t label_x_offset = 0;
    const lv_coord_t label_y_offset = -25;
    lv_obj_align(label_object, top_object, LV_ALIGN_CENTER, label_x_offset, label_y_offset);

    /*
     * Create and style the line meter object
     *
     */
    const int meter_size = 60;

    lv_obj_t * meter_object = lv_linemeter_create(top_object, NULL);
    lv_obj_set_width(meter_object, meter_size);
    lv_obj_set_height(meter_object, meter_size);
    lv_linemeter_set_value(meter_object, value);
    const lv_coord_t meter_x_offset = 0;
    const lv_coord_t meter_y_offset = 20;
    lv_obj_align(meter_object, top_object, LV_ALIGN_CENTER, meter_x_offset, meter_y_offset);


    static lv_style_t meter_style;
    lv_style_init(&meter_style);
    lv_style_set_border_width(&meter_style, LV_STATE_DEFAULT, 0);
    lv_style_set_line_width(&meter_style, LV_STATE_DEFAULT, 3);
    lv_style_set_scale_end_line_width(&meter_style, LV_STATE_DEFAULT, 2);
    lv_style_set_scale_width(&meter_style, LV_STATE_DEFAULT, 10);
    const int pad = 1;
    lv_style_set_pad_top(&meter_style, LV_STATE_DEFAULT, pad);
    lv_style_set_pad_left(&meter_style, LV_STATE_DEFAULT, pad);
    lv_style_set_pad_right(&meter_style, LV_STATE_DEFAULT, pad);
    lv_obj_add_style(meter_object, LV_LINEMETER_PART_MAIN, &meter_style);

    /*
     * Create and style the value label object
     *
     */
    lv_obj_t * value_label_object = lv_label_create(top_object, NULL);
    lv_label_set_text(value_label_object, value_label);

    static lv_style_t value_label_style;
    lv_style_init(&value_label_style);
    lv_style_set_text_font(&value_label_style, LV_STATE_DEFAULT, &lv_font_montserrat_12);
    lv_obj_add_style(value_label_object, LV_LABEL_PART_MAIN, &value_label_style);

    const lv_coord_t value_label_x_offset = LV_DPX(0);
    const lv_coord_t value_label_y_offset = LV_DPX(35);
    lv_obj_align(value_label_object, top_object, LV_ALIGN_CENTER, value_label_x_offset, value_label_y_offset);
}

void ui_init() {

	test_box();

	hello_world();

	make_line_meter(lv_scr_act(), "Tb", 50, "34C");

}

Screenshot and/or video

image

There’s likely something wrong with your display driver.

Thank you for the quick response. I’ve done some more troubleshooting and implemented the test documented here. It looks correct:

I also noticed some compiler warnings saying “shift count too large” so I added type casts to the code referenced in those warnings and now I see the screen rendering like this:

If I only draw the box with rounded corners I see this:

The issue seems like it may be limited to widgets relying on masking to draw correctly but this is, at best, a guess.

How likely is it there’s a compatibility issue between the C2000 compiler and some of the library’s C-code semantics? It’s unlikely the TI compiler is as mature as something using GCC or LLVM. Just a thought.

Given that the gradient test worked, very likely, especially because I don’t recall anyone else using this compiler before. :slightly_smiling_face:

Have you used any prior versions of LVGL with this compiler? Did they work properly?

I’ve not tried other versions and I am using features only in this version so my only option is to see if it can be fixed.

My plan is to step through with a debugger and see if I’m able to find the offending function(s). If I manage to make progress I’ll document it with a PR.

I just compiled and ran v6 from the TI SimpleLink SDK lvgl plugin and there doesn’t appear to be any rendering artifacts. I don’t yet have the style converted to match using the old syntax but everything appears to be drawing correctly.

Which place(s) in the v7 code should I focus on for determining the discrepancy between “rendering paths” / behavior compared to v6? Specifically, it looks like the TI compiler is very strict about implicit promotion for variable / constant types. I’d very much like to contribute to the project if I know where to start looking. See here for a more thorough description.

The fact that uint8_t addressing doesn’t work the same way it does elsewhere is a bit concerning, but it’s strange that v6 runs without problems. There haven’t been any changes to color unions between the two versions that I’m aware of.

I’d guess that the problem lies somewhere in here but unfortunately I’m not familiar enough with that segment of the code to give you a more specific hint. Maybe @kisvegabor has an idea.

It’s nearly without problems. For example, the hello world test I was using above works in v6:

The moment I move to something every slightly more useful (for my UI design) - I see the re-emergence of artifacts:

The uint8_t bit was a little shocking to me as well. I’m actually surprised how well-behaved enough of the library is when this assumption isn’t upheld by this architecture.

If the problem also appears in v6 it would probably be easier to debug that one first, as the drawing logic is simpler.