Skip to content

LV_COLOR_FORMAT_L8 / LV_COLOR_DEPTH=8 flushing problems #7999

Open
@tangentaudio

Description

@tangentaudio

LVGL version

v9.3.0-dev (master) also tried 9.2 release with no change

Platform

Raspberry Pi Pico2, Pico SDK, small SPI OLED display SH1122 controller chip, 256x64 4bpp grayscale.

What happened?

Description

Trouble using LV_COLOR_FORMAT_L8 - it seems previously drawn items (e.g. label text) are not erased when they are updated or scroll and re-render. I have a custom flush callback that I have successfully working under LV_COLOR_FORMAT_I1 and LV_COLOR_DEPTH=1. My display supports grayscale so I am working to use L8 mode, but I have consistent rendering/flush problems that I have not been able to solve.

Note that I am only testing with LV_RENDER_MODE_FULL at the moment to keep it simple; once that is working I will finish implementing LV_RENDER_MODE_PARTIAL in the flush cb.

What have you tried so far?

I have confirmed via debug printf() that the data in the px_map buffer contains prior display items that have not been properly erased. I "drew" the contents of the buffer to the serial debug port and could see the same overwriting/smearing effect on changed or scrolling labels for example. Thus, I believe it is not a problem with putting pixels onto the display but something internal to LVGL or some configuration/setup that I'm possibly missing or have done incorrectly.

In searching/reading I found this thread which seems somewhat relevant, but it's over a year old and it seems like things have been resolved since then: #5657

I did also start a thread on the forum but it hasn't generated any responses. https://forum.lvgl.io/t/lv-color-format-l8-lv-color-depth-8-flushing-problems/20619/1

Trace Log

Here's a Trace-level debug log.
l8-trace.txt

The most suspicious thing to me are these lines:

lv_draw_buf_reshape: Draw buf too small for new shape lv_draw_buf.c:387

I added some extra trace info above those errors which show the required and available sizes. I have done a modest amount of tracing through the code peppering it with more debug info since taking this log, but nothing conclusive yet.

Screenshot and/or video

YouTube link in LV_COLOR_FORMAT_I1 and 1bpp mode (working as expected):
working with LV_COLOR_FORMAT_I1

YouTube link in LV_COLOR_FORMAT_L8 and 8bpp mode (note "smeared" scrolling text):
not working with LV_COLOR_FORMAT_L8

In L8 mode, static text that I only display once and do not update or scroll does render as expected with grayscale, note smooth appearance of the font vs 1bpp mode:

Image

How to reproduce?

Code to reproduce

My init code:

lv_init();
  
  #if LV_COLOR_DEPTH == 1
    #define LV_BUFSIZE ((SH1122_HOR_RES * SH1122_VER_RES / 8) + 8)
    #define LV_COLOR_FORMAT LV_COLOR_FORMAT_I1
  #elif LV_COLOR_DEPTH == 8
    #define LV_BUFSIZE (SH1122_HOR_RES * SH1122_VER_RES)
    #define LV_COLOR_FORMAT LV_COLOR_FORMAT_L8
  #else
    #pragma message "Unsupported color depth"
  #endif

  static uint8_t disp_buf1[LV_BUFSIZE];
  lv_display_t* display = lv_display_create(SH1122_HOR_RES, SH1122_VER_RES);
  lv_display_set_user_data(display, &oled);

  lv_display_set_buffers(display, disp_buf1, NULL, sizeof(disp_buf1), LV_DISPLAY_RENDER_MODE_FULL);
  lv_display_set_flush_cb(display, [](lv_display_t * display, const lv_area_t *area, uint8_t* px_map) {
      OLED* oled = static_cast<OLED*>(lv_display_get_user_data(display));
      oled->lv_sh1122_flush_cb(display, area, px_map);
  });

  lv_display_set_color_format (display, LV_COLOR_FORMAT);

And my flush callback:

void OLED::lv_sh1122_flush_cb(lv_display_t * display, const lv_area_t * area, uint8_t * px_map)
{
	unsigned int xx,yy;	  
    uint8_t* buf = px_map;

    #if LV_COLOR_DEPTH == 1
        // note this only supports LV_DISPLAY_RENDER_MODE_FULL at the moment
        buf += 8;
        for(yy=0; yy<64; yy++)
        {
            Set_Row_Address(yy);
            Set_Column_Address(0x10,0x00);
            for(xx=0;xx<32;xx++)
            {
                uint8_t bv = *(buf++);
                Data_processing(bv);
            }
        }
    #elif LV_COLOR_DEPTH == 8
        for(yy=area->y1; yy<area->y2+1; yy++)
        {
            Set_Row_Address(yy);
            Set_Column_Address(0x10, area->x1 & 0xFF);
            for(xx=area->x1; xx<area->x2+1; xx+=2)
            {
                uint8_t bv1 = *(buf++) >> 4;
                uint8_t bv2 = *(buf++) >> 4;
                uint8_t bv = (bv1 << 4) | bv2;
                Write_Data(bv);
            }
        }    

    #else
        #pragma message "Unsupported color depth"
    #endif


    // Inform LVGL that flushing is complete so buffer can be modified again.
    lv_display_flush_ready(display);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions