-
Notifications
You must be signed in to change notification settings - Fork 322
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The wayland driver has a bug. #244
Comments
It seems the Wayland driver get popular. @WallaceIT @simplejack-src could you check this out? |
I need some time to investigate, maybe @simplejack-src has some ideas? |
LVGL uses single thread to process UI related content to avoid data race, but now maybe the wayland flush take too much time. In fact, I also encountered this problem. I think that's one of the reasons. |
Except LVGL, I also run electron with wayland and it seems nothing unusual. |
@HR1025 我在使用”#define LV_INV_BUF_SIZE 1“的情况下,添加了你的代码,但没有解决这个问题。理论上讲使用了”#define LV_INV_BUF_SIZE 1“后,能减少wayland的刷新次数,而避免wayland刷新过多的问题,但在这种情况下wayland依旧经常忙碌。所以,我猜测wayland才可能是问题的源头,感觉有可能是wayland版本太低,导致lvgl的通信效率低。我的weston是8.0.0,wayland1.18.0,请问一下你的wayland版本是多少?我去试试。 |
@904221150 weston 10.0 Another possibility is the performance of your device. Render with gpu or cpu,which? Runing the demo and observe the system payload I think you can try. |
@904221150 Could you try the following code? static void _lv_wayland_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
struct window *window = disp_drv->user_data;
struct buffer_hdl *buffer = &window->body->buffer;
const lv_coord_t hres = (disp_drv->rotated == 0) ? (disp_drv->hor_res) : (disp_drv->ver_res);
const lv_coord_t vres = (disp_drv->rotated == 0) ? (disp_drv->ver_res) : (disp_drv->hor_res);
/* If private data is not set, it means window has not been initialized */
if (!window)
{
LV_LOG_ERROR("please intialize wayland display using lv_wayland_create_window()");
return;
}
/* If window has been / is being closed, or is not visible, skip rendering */
else if (window->closed || window->shall_close)
{
lv_disp_flush_ready(disp_drv);
return;
}
/* Return if the area is out the screen */
else if ((area->x2 < 0) || (area->y2 < 0) || (area->x1 > hres - 1) || (area->y1 > vres - 1))
{
lv_disp_flush_ready(disp_drv);
return;
}
else if (window->resize_pending)
{
LV_LOG_TRACE("skip flush since resize is pending");
lv_disp_flush_ready(disp_drv);
return;
}
#if (LV_COLOR_DEPTH == BYTES_PER_PIXEL * 8) /* memory align */ \
&& !(LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8) /* not RGB332 */
int32_t bytes_pre_pixel = BYTES_PER_PIXEL;
int32_t x1 = area->x1, x2 = area->x2 <= disp_drv->hor_res - 1 ? area->x2 : disp_drv->hor_res - 1;
int32_t y1 = area->y1, y2 = area->y2 <= disp_drv->ver_res - 1 ? area->y2 : disp_drv->ver_res - 1;
int32_t act_w = x2 - x1 + 1;
for (int y = y1; y <= y2; y++)
{
lv_memcpy((uint8_t *)buffer->base + ((y * disp_drv->hor_res + x1) * bytes_pre_pixel), color_p, act_w * bytes_pre_pixel);
color_p += act_w;
}
#else
#if !(LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8)
#error "Unsupport LV_COLOR_DEPTH, support LV_COLOR_DEPTH: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)"
#endif
int32_t x;
int32_t y;
for (y = area->y1; y <= area->y2 && y < disp_drv->ver_res; y++)
{
for (x = area->x1; x <= area->x2 && x < disp_drv->hor_res; x++)
{
int offset = (y * disp_drv->hor_res) + x;
uint8_t * const buf = (uint8_t *)buffer->base + offset;
*buf = ((0x07 * color_p->ch.red) << 5) |
((0x07 * color_p->ch.green) << 2) |
((0x03 * color_p->ch.blue) << 0);
color_p++;
}
}
#endif
wl_surface_damage(window->body->surface, area->x1, area->y1,
(area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1));
if (buffer->busy)
{
LV_LOG_WARN("skip flush since wayland backing buffer is busy");
lv_disp_flush_ready(disp_drv);
return;
}
if (lv_disp_flush_is_last(disp_drv))
{
if (window->body->surface_configured) {
wl_surface_attach(window->body->surface, buffer->wl_buffer, 0, 0);
wl_surface_commit(window->body->surface);
}
buffer->busy = true;
window->flush_pending = true;
}
lv_disp_flush_ready(disp_drv);
} Maybe this will solve your problem, Thanks. |
@HR1025 In addition, I also checked the cpu usage. The good news is that the cpu performance is confirmed: 1080P frames cost 50ms. The bad news is that _lv_wayland_flush cost 10ms in 1080P frames.It seems that in addition to the wayland problem, I have to look at the opengl acceleration lvgl, which adds another puzzle. |
Do you use the standard memory operation interface? Add below define to #define LV_STDLIB_INCLUDE <stdlib.h>
#define LV_MALLOC malloc
#define LV_REALLOC realloc
#define LV_FREE free
#define LV_MEMSET memset
#define LV_MEMCPY memcpy
I think |
Apologies for the late response, life has dealt me a low hand on a bad turn. The root cause of this issue (and similar ones), comes down to the fact that the wayland driver only allocates a single backing buffer (per window/decoration/etc.). When this is busy (i.e. submitted to the wayland compositor), the driver is unable to continue drawing until this buffer becomes free (i.e. the wayland compositor returns the buffer). This is less then ideal, and a more verbose solution is to have the driver allocate backing buffers on demand (thus allowing more the one buffer to be in flight between the client and compositor). I had started this transition (see #250) but unfortunately, it doesn't look like I'll be able to complete it (at least not in the near future). I've posted my WIP up so anyone can continue the crusade. All the best, |
Thank you, for looking into it. It seems the Wayland driver is getting popular and it'd be great to have good support for it. How broken it is in it's current state? Is it working with some settings? |
@HR1025 |
@kisvegabor |
@kisvegabor
wayland_flush time:%d //_lv_wayland_flush runs properly I don't think the current solution will make wayland work properly. My remedy is not recommended. It doesn't completely solve the problem. |
I don't know much about Wayland, but can't we simply poll a "busy flag" in case of "skip flush since wayland backing buffer is busy" while the backing buffer becomes available? |
Hi, I found some time to work on the Wayland driver. Can you please try the version available in draft PR #253 ? The code there adds a second buffer to the Wayland driver, so one buffer is updated while another one is being displayed. In my tests, this eliminates the "busy buffer" issue. Please note that the PR is still in draft state! |
I'd be happy to try it out, but I'm not sure if there is a way to test it on conventional Linux Mint? |
Hi @kisvegabor You should be able to test the Wayland driver using Weston, that is available in Ubuntu (and thus also in Linux Mint, I think). |
In raw Linux environment,
If your system is based on # device input
sudo apt install libxkbcommon-dev
# wayland dependencies
sudo apt install libwayland-dev
sudo apt install wayland-protocols libwayland-bin
# weston
sudo apt install weston
You can simply run Good Luck |
@WallaceIT |
@904221150 any error printed before the Segmentation fault? Can you share some more details on your configuation? |
@WallaceIT |
See my earlier reported bug #225 |
You can use wayland-scanner to generate the file xdg-shell-client-protocol.h |
I found another solution. I added SDL to weston and then wrote an opengles lvgl display driver. Although the environment is more, but this method can display normally. |
Yes, it'd be great to have an OpenGLES drawing engine. In v9 the rendering architecture will be improved and I think it will be easier to add and OpenGLES backend. |
My English is not good that some sentences may be expressed incorrectly. If the statement is not accurate, try translating Chinese into English.
我的英语不是很好,部分句子可能表述不对。如果表述不准确,可以试试翻译将中文翻译成英文。
When I was using wayland, I found a bug that made the animation play incomplete

当我使用wayland时,我发现一个bug,这个bug使动画播放不完整
The bug is caused by the following code
这个bug是由下面这部分代码产生
The wl_buffer is always busy because it is submitted many times in a frame
这是由于一帧中多次提交wl_buffer,导致wl_buffer总是处于忙碌状态
I tried to change it
我试过修改
This keeps lvgl constantly in full screen refresh, and even then wl_buffer is often busy. But the weston I'm using can play 1080p@30 videos, and it should play lvgl.
这使lvgl经常处于全屏刷新,但即使这样wl_buffer也经常busy。但是我用的weston可以播放1080p@30的视频,不应该播不了lvgl。
So I removed the code about buffer->busy, and then everything works, is this method feasible?
所以我删除了buffer->busy这部分代码,然后一切都正常了,这个方法可行吗?
The text was updated successfully, but these errors were encountered: