@@ -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");
+ }
+ }
}
}
}
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 <michalhorn@eaton.com> --- psplash-fb.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) -- 2.25.1