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

LVGL with Wayland on Embedded Linux #225

Closed symfund closed 1 year ago

symfund commented 2 years ago

All controls can receive the touch events, but do not redraw the display.

https://github.com/symfund/lvgl-port-ma35d1/blob/master/IMG_2781.PNG

kisvegabor commented 2 years ago

I moved the issue to the driver's repository.

@simplejack-src. do you have any ideas?

ghost commented 2 years ago

Quick look at main.c in your repository, it seems as though you forgot to setup the struct pollfd pfd; structure. Adding something like below (before your while (1) loop) will wait until new incoming data is received on the Wayland file descriptor/pipe:

pfd.fd = lv_wayland_get_fd();
pfd.events = POLLIN;

In addition if you want to wait and loop again if the Wayland TX pipe gets full, you can add (before the actual poll(...)):

if (lv_wayland_window_is_flush_pending(NULL)) {
   pfd.events |= POLLOUT;
} else {
   pfd.events &= (~POLLOUT);
}
symfund commented 2 years ago

Thank @simplejack-src for your help. Thank @kisvegabor for your excellent LVGL!

LVGL natively supports Wayland is awesome.

@simplejack-src I added the setup code for pfd. The problem still existed.

For debugging, after creating the calendar LV object, add event callback:

lv_obj_t *calendar = lv_calendar_create(lv_scr_act()); lv_obj_add_event_cb(calendar, event_handler, LV_EVENT_ALL, NULL);

The event handler 'event_handler' actually recieved all the touch events. But in calendar's header dropdown button event handler, no touch event incomed at all!

That says, if not add the debug 'event_handler', the default calendar's class event handler actually recieved all the events.

BTW, I use the deprecated WL-SHELL.

https://github.com/symfund/lvgl-port-ma35d1/blob/master/gadgets.png

symfund commented 2 years ago

I found the problem! UI does not render because the backing buffer is always busy.

symfund commented 2 years ago

In _lv_wayland_flush(), It seems no harm to comment out the following lines:

if 0

else if (buffer->busy) { lv_disp_flush_ready(disp_drv); return; }

endif

When touch the calendar's YEAR dropdown, the popup dropdown list appears.

ghost commented 2 years ago

That check is needed to enforce the Wayland protocol. Effectively, it ensures that the buffer that was "sent" (committed) to the compositor isn't touched by the client until the corresponding release event is received (indicating that the client can reuse that buffer). Since this driver is single-buffered, we need to wait until the compositor releases that buffer before we can begin drawing on it again.

If that section is being hit (should generate an LVGL warning), it would imply that the compositor hasn't released the buffer back to the client by the time it was looking to draw the new frame (LVGL's flush call).

I'll have to think about a proper fix for this. I think the easiest would probably be to go double-buffered, and only commit a single surface/buffer at a time...

ghost commented 2 years ago

Further thinking on it, a proper fix (which I somewhat lament, as I've been just adding bandage fixes until I can do a full refactor) would be to replace the simple linear buffer allocator with a fixed-size free list and dynamically allocate backing buffers for LVGL to flush into. This keeps LVGL happy (not blocking it's flush routine), would only drop frames on memory starvation, and stays responsive (if flushes occur too often, frame-limiting could also be added).

Unfortunately, as this will be a decently substantial change it'll be a few weeks until I get to it (anyone else wanting to tackle it sooner though is always welcome :)).

stale[bot] commented 1 year ago

This issue or pull request 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.