问题描述
我正在尝试为Linux创建一个直接写入帧缓冲区/dev/fb0的应用程序.为了使它具有双重缓冲,我尝试使虚拟屏幕大小是屏幕大小的两倍.这是我写的程序:
I'm trying to make an application for linux that writes directly to the framebuffer /dev/fb0. In order to make it double buffered I try to make the virtual screen be double the size of the screen. This is the program I wrote:
struct fb_var_screeninfo screeninfo_var;
struct fb_fix_screeninfo screeninfo_fixed;
unsigned int* screenbuffer;
void gfx_init()
{
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!");
info("Detected monitor of %ix%i pixels using %i bit colors.",screeninfo_var.xres, screeninfo_var.yres, screeninfo_var.bits_per_pixel);
screenbuffersize = screeninfo_var.xres_virtual * screeninfo_var.yres_virtual * screeninfo_var.bits_per_pixel/8;
screenbuffer = (unsigned int *)mmap(0, screenbuffersize, PROT_READ | PROT_WRITE, MAP_SHARED, fb0, 0);
if( (long)screenbuffer == 0 || (long)screenbuffer == -1 )
error("Failed to map framebuffer to device memory!");
}
程序在ioctl(fb0, FBIOPUT_VSCREENINFO, &screeninfo_var)
上失败,报告错误无效参数.删除行screeninfo_var.yres_virtual = screeninfo_var.yres * 2;
时,它运行良好(但没有双重缓冲).
The program failes on ioctl(fb0, FBIOPUT_VSCREENINFO, &screeninfo_var)
reporting the error invalid argument. When removing the line screeninfo_var.yres_virtual = screeninfo_var.yres * 2;
it runs fine (but without double buffering).
有人在这里看到我做错了吗?
Does someone see what I do wrong here?
推荐答案
为了避免将来给任何人带来麻烦,有一种方法可以在Linux上使用低级图形(例如/dev/fb0)来适当地使缓冲区加倍.但是,根据该线程: https://forum.odroid.com/viewtopic .php?f = 55& t = 8741 不可能通过创建两倍于原始大小的虚拟帧缓冲区来真正地对帧缓冲区加倍缓冲(我已经阅读过树莓派PI可能是一个例外遵守此规则,因为它由其他驱动程序支持.
To save anyone a headache in the future, there is a way to properly double buffer using low level graphics on linux (such as /dev/fb0). However per this thread: https://forum.odroid.com/viewtopic.php?f=55&t=8741 it is not possible to truly double buffer the framebuffer by creating a virtual framebuffer of double the size of the original one (I've read that the raspberry PI might be an exception to this rule because it is backed by a different driver).
在Linux上使用低级图形加倍缓冲区的正确方法是通过libdrm(或/dev/dri/card0).我在这里跟随着一个很好的例子: https://github.com/dvdhrm/docs/blob/master/drm-howto/modeset-vsync.c .将我的/dev/fb0代码转换为/dev/dri/card0代码并不难.
The right way to double buffer using low level graphics on linux is to go through libdrm (or /dev/dri/card0). There is a really nice example that I followed myself here: https://github.com/dvdhrm/docs/blob/master/drm-howto/modeset-vsync.c. It wasn't very hard to convert my /dev/fb0 code to /dev/dri/card0 code.
无论如何,我希望我已经帮助了将来可能遇到这种情况的人.
Anyways I hope I've helped someone out here who might come across this in the future.
这篇关于在fb_var_screeninfo中设置yres_virtual时无效的参数错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!