I am wondering how to properly double buffer the framebuffer to avoid tearing. I've done lots of research on this topic and I can't seem to find anything.
I've tried FBIO_WAITFORVSYNC. But per this thread: How to query Vsync phase in Linux it seems that this won't work.
I've also tried using FBIOGET_VSCREENINFO and FBIOPAN_DISPLAY per this thread: Linux framebuffer graphics and VSync. But it failed due to an error discussed in this thread: invalid argument error when setting yres_virtual in fb_var_screeninfo
That thread suggested using a different driver (vesafb) to resolve the error. I managed to install uvesafb on my machine but the "Invalid Argument" error didn't go away.
I've also tried just mmaping a larger buffer per this person's suggestion: http://betteros.org/tut/graphics1.php#doublebuffer but mmap keeps returning -1.
I've also tried to implement the solution discussed here: https://pyra-handheld.com/boards/threads/my-frustrating-experiences-with-dev-fb.21062/. However the thread died without the actual solution being posted and I am doubtful of the efficiency of swapping hardware addresses (or if it can even be done).
Any help would be so greatly appreciated on this topic!
Due to a request here is the code I would ideally like to get to work:
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!");
This will always print "Could not set variable screen info!" due to some issue extending the virtual framebuffer size.
fb0 = open("/dev/fb0", O_RDWR); if(fb0 == 0) error("Could not open framebuffer located in /dev/fb0!");
The function:open()
always returns a <0 value when it fails (then the code should be callingperror()
so the text reason the system thinks the function failed is written tostderr
0 is a valid return value (although, the code should only see that value ifstdin
has been closed – Stereopticonopen()
fails, after displaying the error message, the code should be callingexit()
as there is nofile descriptor
available to enable access to the file. – Stereopticon