lovyan03 / LovyanGFX

SPI LCD graphics library for ESP32 (ESP-IDF/ArduinoESP32) / ESP8266 (ArduinoESP8266) / SAMD51(Seeed ArduinoSAMD51)
Other
1.19k stars 209 forks source link

Screen tearing when using a Makerfabs Matouch 4.0" 480x480 parallel LCD screen #572

Closed MCUdude closed 4 months ago

MCUdude commented 5 months ago

Carefully written Issues are more likely to be given priority. 丁寧に記述された報告は優先して対応される可能性が高くなります。

Hi, and thank you for this excellent project! I have a Makerfabs Matouch 4.0" 480x480 screen that's supported by this library, and I've created a very simple LVGL project using Squareline Studio. I'm having some screen tearing issues, and I would like to know if or how this can be resolved.

I'm using the latest Arduino ESP32 version that uses ESP-IDF v5.

Environment ( 実行環境 )

Problem Description ( 問題の内容 )

When moving objects on the screen, I'm getting some screen tearing. It isn't all that bad in the LVGL example I've created, but it gets far worse with heavier objects such as images

Expected Behavior ( 期待される動作 )

Movements without any tearing. The FPS may drop, but it should only lag, not tear like shown in the video and in the picture

Actual Behavior ( 実際の動作 )

Here is a snapshot from the video showing the tearing

IMG_6182 1

And here is the video:

https://github.com/lovyan03/LovyanGFX/assets/3238730/cb5519c7-dd1d-412b-bf34-d5d2bc385ed7

Steps to reproduce ( 再現のための前提条件 )

  1. Compile and upload PlatformIO project to the Matouch board
  2. Test the example program on the Matouch board

Code to reproduce this issue ( 再現させるためのコード )

Here is the complete PlatformIO project, including the necessary LVGL files and setup: LovyanGFX_tearing_example.zip

Platformio main.cpp source code ```cpp #include #include "matouch.h" // Contains hardware setup provided my Makerfabs #include "ui/ui.h" // LVGL components /*Change to your screen resolution*/ static constexpr uint16_t SCREEN_WIDTH = 480; static constexpr uint16_t SCREEN_HEIGHT = 480; // assign heap in the PSRAM for both buffers static lv_color_t *disp_draw_buf_1 = (lv_color_t *)heap_caps_malloc(sizeof(lv_color_t) * SCREEN_WIDTH * 48 , MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); static lv_color_t *disp_draw_buf_2 = (lv_color_t *)heap_caps_malloc(sizeof(lv_color_t) * SCREEN_WIDTH * 48 , MALLOC_CAP_SPIRAM| MALLOC_CAP_8BIT); static lv_disp_draw_buf_t draw_buf; LGFX gfx; // Display flushing */ void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) { if (gfx.getStartCount() == 0) // Processing if not yet started gfx.startWrite(); gfx.pushImageDMA(area->x1, area->y1, area->x2 - area->x1 + 1, area->y2 - area->y1 + 1, (lgfx::rgb565_t*)&color_p->full); lv_disp_flush_ready(disp); } // Read the touchpad void my_touchpad_read( lv_indev_drv_t * indev_driver, lv_indev_data_t * data ) { uint16_t touchX, touchY; data->state = LV_INDEV_STATE_REL; if( gfx.getTouch( &touchX, &touchY ) ){ data->state = LV_INDEV_STATE_PR; // Set the coordinates data->point.x = touchX; data->point.y = touchY; } } void setup() { gfx.begin(); lv_init(); lv_disp_draw_buf_init(&draw_buf, disp_draw_buf_1, disp_draw_buf_2, SCREEN_WIDTH * 48); // Initialize display static lv_disp_drv_t disp_drv; lv_disp_drv_init( &disp_drv ); // Change the following line to your display resolution disp_drv.hor_res = SCREEN_WIDTH; disp_drv.ver_res = SCREEN_HEIGHT; disp_drv.flush_cb = my_disp_flush; disp_drv.draw_buf = &draw_buf; lv_disp_drv_register( &disp_drv ); //Initialize the input device driver static lv_indev_drv_t indev_drv; lv_indev_drv_init( &indev_drv ); indev_drv.type = LV_INDEV_TYPE_POINTER; indev_drv.read_cb = my_touchpad_read; lv_indev_drv_register( &indev_drv ); ui_init(); } void loop() { lv_timer_handler(); // let the GUI do its work delay(1); } ```
tobozo commented 5 months ago

hi,

maybe try lower freq?

cfg.freq_write = 14000000;

16 bit parallel can give really good performances even at 2MHz

in order to find the sweet spot you can start with a low value, then increase by 1MHz until the tearing occurs

MCUdude commented 5 months ago

Hi @tobozo!

maybe try lower freq?

I tried all the way down to 1 MHz, and worked my way all the way up to 14 MHz.

Below 5.6 MHz the picture wasn't displayed properly on the screen, and when I got to 5.6 MHz and above, the tearing effect was noticeable. So sadly, this didn't fix the issue for me.

lovyan03 commented 5 months ago

There is no easy way to prevent tearing because the timing of data transmission from the ESP32 is not synchronized with the operation of the LCD scan lines.

MCUdude commented 5 months ago

There is no easy way to prevent tearing because the timing of data transmission from the ESP32 is not synchronized with the operation of the LCD scan lines.

Interesting. Is something that could be solved with a hardware modification or similar? I'm planning to design a custom PCB with and ESP32S3 and this exact screen. Could a custom design solve this?

FYI I have another Matouch screen at my desk. This 7.0" 480x800 model. I have not used it with the LovyanGFX library, but I managed to get it working using this esp-idf (v5.0) project. It uses the same ESP32S3 module, and with this exact project I didn't have any screen tearing at all. It did occasionally lag, but then the entire screen lagged without any tearing. I thought this was because the double PSRAM frame buffering. But maybe it was just a coincidence?

I would much, much rather use this library and the Arduino framework instead of having to deal with the esp-idf directly.

MCUdude commented 5 months ago

After some more research, it seems like the esp-idf project I mentioned earlier (right here) is doing some RTOS magic in order to synchronize to the vsync signal. Is this library able to do the same?

github-actions[bot] commented 4 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

github-actions[bot] commented 4 months ago

This issue has been automatically closed because it has not had recent activity. Thank you for your contributions.