Screen tearing when using a Makerfabs Matouch 4.0" 480x480 parallel LCD screen
MCUdude opened this issue · 7 comments
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 ( 実行環境 )
- MCU or Board name: Makerfabs Matouch 4.0" 480x480 RGB565 (ESP32S3)
- Panel Driver IC: ST7701
- Bus type: Parallel16 (RGB565 + SPI)
- LovyanGFX version: latest, v1.1.16
- FrameWork version: ArduinoESP32 v3.0.0 (to better support double buffering)
- Build Environment: PlatformIO
- Operating System: Windows
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
And here is the video:
IMG_6181.mp4
Steps to reproduce ( 再現のための前提条件 )
- Compile and upload PlatformIO project to the Matouch board
- 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
#include <Arduino.h>
#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);
}
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
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.
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.
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.
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?