【发布时间】:2018-09-14 08:59:06
【问题描述】:
我想知道如何正确地对帧缓冲区进行双重缓冲以避免撕裂。我已经对这个主题进行了大量研究,但似乎找不到任何东西。
我已经尝试过 FBIO_WAITFORVSYNC。但是根据这个帖子:How to query Vsync phase in Linux 这似乎行不通。
我也尝试过使用 FBIOGET_VSCREENINFO 和 FBIOPAN_DISPLAY 每个线程:Linux framebuffer graphics and VSync。但由于此线程中讨论的错误而失败:invalid argument error when setting yres_virtual in fb_var_screeninfo
该线程建议使用不同的驱动程序 (vesafb) 来解决错误。我设法在我的机器上安装了 uvesafb,但“无效参数”错误并没有消失。
我也尝试按照此人的建议映射更大的缓冲区:http://betteros.org/tut/graphics1.php#doublebuffer 但 mmap 一直返回 -1。
我还尝试实施此处讨论的解决方案:https://pyra-handheld.com/boards/threads/my-frustrating-experiences-with-dev-fb.21062/。然而,线程在没有发布实际解决方案的情况下就死了,我怀疑交换硬件地址的效率(或者甚至可以做到)。
非常感谢您对此主题的任何帮助!
由于一个请求,这里是我希望开始工作的代码:
fb0 = open("/dev/fb0", O_RDWR);
if(fb0 == 0)
error("Could not open framebuffer located in /dev/fb0!");
if (ioctl(fb0, FBIOGET_FSCREENINFO, &screeninfo_fixed) == -1)
error("Could not retrive fixed screen info!");
if (ioctl(fb0, FBIOGET_VSCREENINFO, &screeninfo_var) == -1)
error("Could not retrive variable screen info!");
screeninfo_var.xres_virtual = screeninfo_var.xres;
screeninfo_var.yres_virtual = screeninfo_var.yres * 2;
screeninfo_var.width = screeninfo_var.xres;
screeninfo_var.height = screeninfo_var.yres;
screeninfo_var.xoffset = 0;
screeninfo_var.yoffset = 0;
if (ioctl(fb0, FBIOPUT_VSCREENINFO, &screeninfo_var) == -1)
error("Could not set variable screen info!");
这将始终打印“无法设置可变屏幕信息!”由于一些扩展虚拟帧缓冲区大小的问题。
【问题讨论】:
-
请发minimal reproducible example,以便我们帮助您确定问题的根本原因
-
我也添加了一些示例代码。
-
关于:
fb0 = open("/dev/fb0", O_RDWR); if(fb0 == 0) error("Could not open framebuffer located in /dev/fb0!");函数:open()在失败时总是返回 perror() 所以系统认为函数失败的文本原因被写入到stderr0 是一个有效的返回值(尽管,如果stdin已关闭,代码应该只看到该值 -
当调用
open()失败时,显示错误信息后,代码应该调用exit(),因为没有file descriptor可用于启用对文件的访问。 -
我很欣赏这些回复......但他们根本没有解决这个问题。我的问题是关于使用帧缓冲区进行双缓冲......而不是 open() 函数
标签: c linux framebuffer double-buffering