lvgl / lv_drivers

TFT and touch pad drivers for LVGL embedded GUI library
https://docs.lvgl.io/master/porting/index.html
MIT License
291 stars 310 forks source link

fbdev driver doesn't work when the device only supports 24 bits per pixel #230

Closed Johennes closed 1 year ago

Johennes commented 1 year ago

In https://gitlab.com/cherrypicker/unl0kr/-/issues/35 we found out that the fbdev driver doesn't work well when the framebuffer has only 24 bits per pixel. The same memcpy code is used for both 32 and 24 bits per pixel

    /*32 or 24 bit per pixel*/
    if(vinfo.bits_per_pixel == 32 || vinfo.bits_per_pixel == 24) {
        uint32_t * fbp32 = (uint32_t *)fbp;
        int32_t y;
        for(y = act_y1; y <= act_y2; y++) {
            location = (act_x1 + vinfo.xoffset) + (y + vinfo.yoffset) * finfo.line_length / 4;
            memcpy(&fbp32[location], (uint32_t *)color_p, (act_x2 - act_x1 + 1) * 4);
            color_p += w;
        }
    }

but when the framebuffer memory layout only uses 24 bits per pixel the 32-bit-wide color_p values will flow over into the next pixel.

I was able to fix the rendering by manually extracting the lower 24 bits from every color_p value.

    /*24 bit per pixel*/
    else if(vinfo.bits_per_pixel == 24) {
        uint8_t * fbp8 = (uint8_t *)fbp;
        int32_t y;
        for(y = act_y1; y <= act_y2; y++) {
            location = (act_x1 + vinfo.xoffset) + (y + vinfo.yoffset) * finfo.line_length / 3;
            long int length = (act_x2 - act_x1 + 1);
            for (long int i = 0; i < length; i += 1) {
                uint32_t c = ((uint32_t *)color_p)[i];
                uint8_t *c8 = (uint8_t *)&c;
                fbp8[3*location + 3*i] = c8[0];
                fbp8[3*location + 3*i+1] = c8[1];
                fbp8[3*location + 3*i+2] = c8[2];
            }
            color_p += w;
        }
    }

However, this is probably a lot less performant than the memcpy. Is there any other way we could truncate the 32-bit color_p values into the lower 24-bits without doing it pixel by pixel?

kisvegabor commented 1 year ago

Hi,

Thanks for reporting it.

In v9 we will add support for rendering in 24 bit color depth directly. Until that it needs to be converted pixel by pixel. :slightly_frowning_face: