我想知道如何正确地双重缓冲帧缓冲以避免撕裂。我已经对这个主题进行了大量研究,似乎找不到任何东西。
我尝试过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,但“无效参数”错误没有消失。
我也试过根据这个人的建议mmaping一个更大的缓冲区: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!");
这将始终打印“无法设置变量屏幕信息!”由于某些问题扩展了虚拟帧缓冲区大小。
答案 0 :(得分:0)
我解决了Linux上帧缓冲的双重缓冲问题的方法是使用单独的后备缓冲,使用mmap将其分配给相同的屏幕尺寸:
bbp = mmap(0, screensize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
(其中screensize = vinfo.yres_virtual * finfo.line_length;
)
然后将所有更改都写入此后台缓冲区,并在所有写入结束后,使用一个update()函数将整个后台缓冲区复制到主帧缓冲区指针位置:
memcpy(fbp, bbp, screensize);
您还可以具有只复制给定区域的updateRect()函数。在我的x64 PC gnu / linux平台上,此逻辑工作正常。