From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id C0504C433F5 for ; Mon, 17 Jan 2022 10:39:55 +0000 (UTC) Subject: [psplash][PATCH] psplash: Fix double buffering initialization To: yocto@lists.yoctoproject.org From: "Horn, Michal" X-Originating-Location: Prague, Hlavni mesto Praha, CZ (185.63.97.23) X-Originating-Platform: Linux Chrome 95 User-Agent: GROUPS.IO Web Poster MIME-Version: 1.0 Date: Mon, 17 Jan 2022 02:39:54 -0800 Message-ID: Content-Type: multipart/alternative; boundary="rKMJqjWmawxi43geSiin" List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 17 Jan 2022 10:39:55 -0000 X-Groupsio-URL: https://lists.yoctoproject.org/g/yocto/message/55890 --rKMJqjWmawxi43geSiin Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Some fb drivers do not implement double buffering completely or correctly. For example mxsfb driver does not set yres_virtual to double on initialization, nor it allows its doubling by FBIOPUT_VSCREENINFO ioctl call. In such case, the double buffering gets enabled, but psplash fails to display every second frame with error 'psplash_fb_flip: FBIOPAN_DISPLAY = failed: Invalid argument'. Panning the display by FBIOPAN_DISPLAY ioctl is always checking carefully that the resolution, virtual buffer resolutin and offsets are in bounds at fb_pan_display - https://elixir.bootlin.com/linux/v4.9.275/source= /drivers/video/fbdev/core/fbmem.c#L891. Swapping the front and back buffers is done by switching the yoffset between 0 and yres values. For double buffering, the whole buffer must have yres_virtual buffer size double of yres. But in case of the mxsfb driver, the yres_virtual is always equal to yres, so drawing with the offset set to yres would overrun the buffer. So the panning is stopped and error 'Invalid argument' is returned. Psplash tries to double the=C2=A0yres_virtual on initialization by FBIOPUT_= VSCREENINFO ioctl call, that at some point calls the mxsfb_check_var - https://elixir.bootlin.com/l= inux/v4.9.275/source/drivers/video/fbdev/mxsfb.c#L269 function, which for some reason always sets the yres_virtual back to yres, effectively canceling the doubling. But no error is returned in this case, so it gets silently ignored. So in general, checking for the ioctl call success is not enough as some drivers may pass this test, but fail double buffering anyway. So now we double check the yres_virtual on fb_new and disable double buffering in case of doubling yres_virtual fails. Signed-off-by: Michal Horn --- psplash-fb.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/psplash-fb.c b/psplash-fb.c index 2babb5f..1b73807 100644 --- a/psplash-fb.c +++ b/psplash-fb.c @@ -213,8 +213,18 @@ psplash_fb_new (int angle, int fbdev_id) perror(" Error getting the fixed framebuffer info"); goto fail; } else { -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 DBG("Virtual resolution set to double")= ; -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fb->double_buffering =3D 1; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (ioctl(fb->fd, FBIOPAN_DISPLAY, &fb_= var) =3D=3D -1) { +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr, "warning: FBIOPA= N_DISPLAY failed, " +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "dou= ble buffering disabled\n"); +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } else { +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (fb_var.yres_virtual =3D=3D f= b_var.yres * 2) { +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 DBG("Virtual resolution s= et to double"); +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fb->double_buffering =3D = 1; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } else { +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr, "warning:= Doubling virtual " +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 "resolution failed, double buffering disabled\n"); +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } } } } -- 2.25.1 --rKMJqjWmawxi43geSiin Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable
Some fb drivers do not implement double buffering completely or correc= tly.
For example mxsfb driver does not set yres_virtual to double on
initialization, nor it allows its doubling by FBIOPUT_VSCREENINFO ioct= l
call. In such case, the double buffering gets enabled, but psplash fai= ls
to display every second frame with error 'psplash_fb_flip: FBIOPAN_DIS= PLAY failed: Invalid argument'.
 
Panning the display by FBIOPAN_DISPLAY ioctl is always checking carefu= lly
that the resolution, virtual buffer resolutin and offsets are in
bounds at fb_pan_display - https://elixir.bootlin.com/linux/v4.9.275/s= ource/drivers/video/fbdev/core/fbmem.c#L891.
 
Swapping the front and back buffers is done by switching the
yoffset between 0 and yres values. For double buffering, the whole buf= fer
must have yres_virtual buffer size double of yres.
 
But in case of the mxsfb driver, the yres_virtual is always equal to y= res,
so drawing with the offset set to yres would overrun the buffer. So th= e
panning is stopped and error 'Invalid argument' is returned.
 
Psplash tries to double the yres_virtual on initialization by FBI= OPUT_VSCREENINFO ioctl call,
that at some point calls the mxsfb_check_var - https://elixir.bootlin.= com/linux/v4.9.275/source/drivers/video/fbdev/mxsfb.c#L269
function, which for some reason always sets the yres_virtual back to y= res,
effectively canceling the doubling. But no error is returned in this c= ase,
so it gets silently ignored.

So in general, checking for th= e ioctl call success is not enough as some
drivers may pass this test,= but fail double buffering anyway.
So now we double check the yres_virtual on fb_new and disable doublebuffering in case of doubling yres_virtual fails.
 
Signed-off-by: Michal Horn <michalhorn@eaton.com>
---
 psplash-fb.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
 
diff --git a/psplash-fb.c b/psplash-fb.c
index 2babb5f..1b73807 100644
--- a/psplash-fb.c
+++ b/psplash-fb.c
@@ -213,8 +213,18 @@ psplash_fb_new (int angle, int fbdev_id)
           perror(" Error getting the fi= xed framebuffer info");
           goto fail;
         } else {
-          DBG("Virtual resolution set to dou= ble");
-          fb->double_buffering =3D 1;
+          if (ioctl(fb->fd, FBIOPAN_DISPL= AY, &fb_var) =3D=3D -1) {
+            fprintf(stderr, "warning: F= BIOPAN_DISPLAY failed, "
+                   = "double buffering disabled\n");
+          } else {
+            if (fb_var.yres_virtual =3D= =3D fb_var.yres * 2) {
+              DBG("Virtual resolut= ion set to double");
+              fb->double_buffer= ing =3D 1;
+            } else {
+              fprintf(stderr, "war= ning: Doubling virtual "
+                   =   "resolution failed, double buffering disabled\n");
+            }
+          }
         }
       }
     }
-- 
2.25.1
 
--rKMJqjWmawxi43geSiin--