我想知道如何正确地对帧缓冲区进行双重缓冲以避免撕裂。我对这个主题做了很多研究,但似乎找不到任何东西。
我试过 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!");
这将始终打印“无法设置可变屏幕信息!”由于扩展虚拟帧缓冲区大小的一些问题。
最佳答案
我解决 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 平台上运行良好。
关于c - 使用 linux framebuffer 进行适当的双缓冲,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49657086/