82 lines
3.4 KiB
Diff
82 lines
3.4 KiB
Diff
From: Gabriel Valcazar <gabriel.valcazar@digi.com>
|
|
Date: Thu, 17 Sep 2020 13:16:04 +0200
|
|
Subject: [PATCH] libweston: g2d-renderer: try re-adjusting fb if the
|
|
FBIOPAN_DISPLAY ioctl fails
|
|
|
|
By default, the g2d renderer works with 3 buffers, and uses the FBIOPAN_DISPLAY
|
|
ioctl to have the kernel switch between them everytime the output has to be
|
|
shown. Because of this, when the renderer is initialized, it will increase the
|
|
framebuffer's yres_virtual parameter so it is 3 times the size of yres
|
|
(vertical resolution).
|
|
|
|
However, when the system goes through a suspend/resume iteration, the
|
|
framebuffer's yres_virtual parameter will change back to its original value,
|
|
causing the FBIOPAN_DISPLAY ioctl to fail when using the 2nd and 3rd buffers,
|
|
which is 2 out of 3 times whenever something changes in the output. This has
|
|
three direct effects:
|
|
|
|
* Constant "FBIOPAN_DISPLAY failed" messages in the weston log
|
|
* Choppy framerate (due to the renderer only being able to show 1/3 of the
|
|
total output frames)
|
|
* A 2/3 chance that the desktop will not show after resuming from suspend until
|
|
there's movement on the screen
|
|
|
|
To avoid this, whenever a FBIOPAN_DISPLAY ioctl fails, check if the
|
|
yres_virtual attribute read from the kernel is different from the one saved in
|
|
the renderer and, if so, update it once again and retry the ioctl. This adds
|
|
some additional overhead in case of a FBIOPAN_DISPLAY failure, but these have
|
|
only been observed in the specific suspend/resume scenario, not in an average
|
|
use case.
|
|
|
|
The only drawback to this workaround is that there's a 1/3 chance that the
|
|
display will go blank for a very small period of time when resuming from
|
|
suspend. This is due to the framebuffer being reconfigured and, although
|
|
undesireable, is much less bothersome than the original issue.
|
|
|
|
https://jira.digi.com/browse/DEL-7236
|
|
|
|
Signed-off-by: Gabriel Valcazar <gabriel.valcazar@digi.com>
|
|
---
|
|
libweston/renderer-g2d/g2d-renderer.c | 24 +++++++++++++++++++++++-
|
|
1 file changed, 23 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/libweston/renderer-g2d/g2d-renderer.c b/libweston/renderer-g2d/g2d-renderer.c
|
|
index 456190a3..cfc2e8b6 100644
|
|
--- a/libweston/renderer-g2d/g2d-renderer.c
|
|
+++ b/libweston/renderer-g2d/g2d-renderer.c
|
|
@@ -528,12 +528,34 @@ static void
|
|
g2d_flip_surface(struct weston_output *output)
|
|
{
|
|
struct g2d_output_state *go = get_output_state(output);
|
|
+ struct fb_var_screeninfo aux_varinfo;
|
|
go->fb_info.varinfo.yoffset = go->activebuffer * go->fb_info.y_resolution;
|
|
|
|
if(ioctl(go->fb_info.fb_fd, FBIOPAN_DISPLAY, &(go->fb_info.varinfo)) < 0)
|
|
{
|
|
- weston_log("FBIOPAN_DISPLAY Failed\n");
|
|
+ /* Check if yres_virtual has changed (it happens on suspend/resume) */
|
|
+ if (ioctl(go->fb_info.fb_fd, FBIOGET_VSCREENINFO, &aux_varinfo) < 0) {
|
|
+ weston_log("FBIOGET_VSCREENINFO Failed\n");
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ /* If yres_virtual has changed, adjust it and try flipping the surface again */
|
|
+ if (aux_varinfo.yres_virtual != go->fb_info.varinfo.yres_virtual) {
|
|
+ aux_varinfo.yres_virtual = aux_varinfo.yres * go->nNumBuffers;
|
|
+ if (ioctl(go->fb_info.fb_fd, FBIOPUT_VSCREENINFO, &aux_varinfo) < 0) {
|
|
+ weston_log("FBIOPUT_VSCREENINFO Failed\n");
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if(ioctl(go->fb_info.fb_fd, FBIOPAN_DISPLAY, &(go->fb_info.varinfo)) < 0) {
|
|
+ weston_log("FBIOPAN_DISPLAY Failed\n");
|
|
+ }
|
|
+ } else {
|
|
+ weston_log("FBIOPAN_DISPLAY Failed\n");
|
|
+ }
|
|
}
|
|
+
|
|
+out:
|
|
go->activebuffer = (go->activebuffer + 1) % go->nNumBuffers;
|
|
}
|