From patchwork Mon Jan 17 10:26:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Horn, Michal" X-Patchwork-Id: 2545 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 7C85CC433EF for ; Mon, 17 Jan 2022 10:26:09 +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:26:08 -0800 Message-ID: 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:26:09 -0000 X-Groupsio-URL: https://lists.yoctoproject.org/g/yocto/message/55889 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*. # Technical details: ## Why every second frame gets thrown? Panning the display by FBIOPAN_DISPLAY ioctl is always checking carefully that the resolution, virtual buffer resolution and offsets in it are in bounds at (fb_pan_display)[https://elixir.bootlin.com/linux/v4.9.275/source/drivers/video/fbdev/core/fbmem.c#L891]. Switching between the front and back buffers is done by switching the yoffset between 0 and yres values. For double buffering, the complete buffer has yres_virtual size and it must be 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. ## Why doubling the yres_virtual fails? yres_virtual is supposed to be doubled by FBIOPUT_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 yres, effectively canceling the doubling. But no error is returned in this case, so it gets silently ignored. # Solution These two problems can be solved by double checking 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(-) -- 2.25.1 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 { -          DBG("Virtual resolution set to double"); -          fb->double_buffering = 1; +          if (ioctl(fb->fd, FBIOPAN_DISPLAY, &fb_var) == -1) { +            fprintf(stderr, "warning: FBIOPAN_DISPLAY failed, " +                    "double buffering disabled\n"); +          } else { +            if (fb_var.yres_virtual == fb_var.yres * 2) { +              DBG("Virtual resolution set to double"); +              fb->double_buffering = 1; +            } else { +              fprintf(stderr, "warning: Doubling virtual " +                      "resolution failed, double buffering disabled\n"); +            } +          } } } }