Is the FBIO_WAITFORVSYNC ioctl implemented in Rpi's fb?


54 posts   Page 2 of 3   1, 2, 3
by dom » Sat Mar 22, 2014 12:10 pm
If you believe any of the FBIO ioctls are incorrect, then open a github issue, include a trivial test app that uses the FBIO ioctl, explain clearly what it currently does, what it should do.
Explain what the benefit is (e.g. will make this specific sdl app work correcty or more efficiently). Then I can look into it.

(Or even better, submit a PR to linux tree if you know what the fix is).
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 5084
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge
by cleverca22 » Sun Mar 23, 2014 1:24 am
from what ive seen in the framebuffer driver, the problem is likely in the blob, but i need to do some tests on another system to see what is 'normal' and also check to see if dispmanx is capable of the right thing easily
Posts: 202
Joined: Sat Aug 18, 2012 2:33 pm
by -rst- » Fri Mar 28, 2014 5:22 pm
Judging from my experience with the prototype using the mailbox interface 'Set virtual offset' (tag 0x00048009) this does not happen, so it is probably 'somewhere between'.

As far as I understand the Linux framebuffer driver, the page flipping should be done using the 'set virtual offset' not 'set variable info', so the RPI driver might not be wrong clearing the buffer when using 'set variable info' (which is analogous to the command/tool fbset, which clears the buffer when executed).

I will try to find time to look at compiling the kernel and adding the implementation of FBIOPAN_DISPLAY, but if someone else is nearly there... there is the trivial testcase code earlier in this thread (my reply on Mon Dec 10, 2012 3:30 pm).
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 1316
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by -rst- » Tue Sep 02, 2014 11:49 am
After a couple of failed attempts to compile the kernel :oops: I have submitted an issue 'bcm2708_fb_pan_display is not implemented' in github: https://github.com/raspberrypi/linux/issues/679
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 1316
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by dom » Wed Sep 03, 2014 10:31 pm
From github issue:

I've got pan and wait for vsync implemented.
I've also tweaked it so FBIOPUT_VSCREENINFO doesn't clear the framebuffer when the allocated size doesn't change.
Also attempted to make the blank command disable the HDMI output (so monitor is more likely to power-save).

The test app seems to work. If I don't find any problems tomorrow, I'll push it out.
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 5084
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge
by dom » Thu Sep 04, 2014 4:22 pm
Try running rpi-update (there is a gpu firmware change and well as the linux change) and report back on how it behaves.
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 5084
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge
by -rst- » Thu Sep 04, 2014 9:47 pm
Yep, I have just done a quick test on this - seems to work fine! Will test a bit more and close the ticket then. Breaking news published in the blog too http://raspberrycompote.blogspot.ie/201 ... -part.html

Thanks (especially popcornmix)!
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 1316
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by Boreal » Sun Jan 04, 2015 10:16 pm
Has anyone figured out how to wait for vsync?

I'd really love to see rst's fbtestXIII.c run properly under a recent version of Raspbian.
Posts: 5
Joined: Sat Jan 04, 2014 8:48 pm
Location: Denver, Colorado USA
by dom » Mon Jan 05, 2015 12:30 pm
As far as I'm aware, the wait for vsync is implemented in FB driver.
If it's not working correctly, then a simple example that shows the problem is needed and I can investigate.
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 5084
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge
by Boreal » Mon Jan 05, 2015 7:48 pm
Oops, my mistake. I jumped to the conclusion that vsync wasn't working
because of rst's last posts:

http://raspberrycompote.blogspot.com/20 ... chive.html
https://github.com/raspberrypi/linux/issues/679

I'm very pleased to have his fbtestXIII.c now running under Raspbian
3.12.28 Sep 8 2014 on my RPi B+ without any glitches. It runs in 10.027
seconds, which is another indication that vsync is working. All that was
required was inserting the ioctl line shown here:

vx = 0;
vy = cur_page * vinfo.yres;
set_fb_voffs(&vx, &vy);
ioctl(fbfd, FBIO_WAITFORVSYNC, 0);

After booting, "fbset -depth 8" (or a similar command) must be run,
otherwise fbtestXIII displays a blank screen.

This opens the door to smooth, glitch-free animation. Thanks for
everyone's help!

Links to fbtestXIII:
http://raspberrycompote.blogspot.com/20 ... rt_16.html
https://github.com/rst-/raspberry-compo ... testXIII.c
Posts: 5
Joined: Sat Jan 04, 2014 8:48 pm
Location: Denver, Colorado USA
by -rst- » Tue Jan 06, 2015 2:11 pm
Hmm, interesting - so the only combination I did not come to think of (ioctl vsync + mailbox pan)...

I am fairly sure I tried this https://github.com/rst-/raspberry-compo ... fbtestXI.c changing the 'switch page' section to:
Code: Select all
        // switch page
        vinfo.yoffset = cur_page * vinfo.yres;
        if (ioctl(fbfd, FBIO_WAITFORVSYNC, 0) == 0) {
            if (ioctl(fbfd, FBIOPAN_DISPLAY, &vinfo)) {
                printf("Error panning display.\n");
            }
        }
        else {
            printf("VSync failed.\n");
        }
       
        //usleep(1000000 / fps);


...and it did not work as expected but I may have made a mistake of course.

I will try to test this in the evening - if someone (Boreal?) manages to find time earlier, I don't mind ;)
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 1316
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by -rst- » Tue Jan 06, 2015 4:33 pm
Well, I managed to test this now myself too (lucky to have a colleague who brought his RPi to work and let me loan it :D ): both the ioctl pan and the mailbox pan with the FBIO_WAIT_FOR_VSYNC ioctl right _after_ seem to work fine! So (comment out/in to try options):
Code: Select all
        // switch page
        /**/
        // ioctl version
        vinfo.yoffset = cur_page * vinfo.yres;
        ioctl(fbfd, FBIOPAN_DISPLAY, &vinfo);
        ioctl(fbfd, FBIO_WAITFORVSYNC, 0);
        /**/
        /*
        // mailbox version
        vx = 0;
        vy = cur_page * vinfo.yres;
        set_fb_voffs(&vx, &vy);
        ioctl(fbfd, FBIO_WAITFORVSYNC, 0);
        */


Tested both on the upgraded 3.12.26 (Thu Sep 4) build and the very latest clean download 3.12.35 (Fri Dec 19).

Which puzzles me a bit: I would have thought you wait for the vsync (to start) and then during that (when the screen is not updated) you flip the display using the pan or alternatively using the FB_ACTIVATE_VBL flag (which in fact might be the best option in the end) with the pan force the flip to happen during the vsync.

But all in all I think this is good enough for closing the issue in github.

Another thing then is why the call to 'fbset -depth 8' is required for the display not to go blank - the code should switch to 8 bit mode...
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 1316
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by -rst- » Fri Jan 16, 2015 5:25 pm
Cleaned up 'pure fb' version of the double-buffering example and some info on the display blanking issue:
viewtopic.php?f=67&t=30720&p=672744#p672744
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 1316
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by -rst- » Tue Jan 27, 2015 2:21 pm
Boreal wrote:After booting, "fbset -depth 8" (or a similar command) must be run,
otherwise fbtestXIII displays a blank screen.


Finally managed to find the cause for the blanking after boot: the changes in the framebuffer driver seem to require the calls to KDSETMODE to be inside the FBIOPUT_VSCREENINFO calls... Fixed code now in https://github.com/rst-/raspberry-compo ... btestXIV.c
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 1316
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by kagerato » Sun Jan 17, 2016 2:31 am
The FBIO_WAITFORVSYNC ioctl syscalls in this thread have a subtle bug. For an I/O control call, the third argument is always a pointer (address), not the integer value itself. When zero is passed, the kernel is asked to read from your process' virtual address zero, which very likely has either nothing or arbitrary data mapped there.

There are five conceivable results of this:

{1} The illegal system call forces program termination. This is more likely on 64-bit arches, as sizeof(void *) is often larger than sizeof(int) there. However, this possibility may be eliminated by the C standard library (glibc/musl/others) wrapping the syscall, which could automatically force-cast the value. Violations of the syscall interface are more frequently encountered in assembly code.
{2} User program crashes due to an invalid read of unmapped memory.
{3} The kernel (Linux) detects and circumvents the invalid read, cancels the requested operation, and returns an error from the syscall.
{4} Linux detects the invalid read, determines that it doesn't make any difference, and continues the operation without error.
{5} The kernel framebuffer driver code is completely oblivious and there's no telling what happens next.

Note that there doesn't seem to be much error checking code in the examples shown here. It's a good idea to test and branch off the result of a function or syscall that has any non-trivial chance of failure. Otherwise, the user program can't notice or respond to problems.

This particular mistake is easy to make because the function prototype for ioctl is a varargs declaration. One must read the man page carefully to see that the third argument is in fact always a void pointer (traditionally in Unix it was a char pointer). Other examples of WAITFORVSYNC and ioctl calls on the web support this.

One reason I think this is important is that it's probable either the bugged vsync wait does nothing, or the kernel code invoked is lax on its error checks. In the first case, it may go unnoticed if the software rasterization uses so much CPU that it can't outpace the display's refresh rate. In the second case, kernel code really ought to be very strict about this stuff, since it makes a difference to correctness and security in many other cases.

Another reason this is significant is that it might be the reason for the "curious"/invalid call ordering. Vsync wait definitely should occur before the pan. Any type of clean buffer swap technique always works during the vertical blanking period, so naturally one must wait for it first before committing the change. See what happens if you fix the bug and then put the calls in their proper order.

Finally, I'd recommend any relevant involved parties comb through their other code for this same bug. It could be having various strange effects elsewhere.


Information References

http://www.pandorawiki.org/Kernel_interface
http://forum.fs-net.de/index.php/Thread ... supported/
http://www.linuxquestions.org/questions ... on-513838/
http://developer.toradex.com/knowledge- ... 28linux%29


User Relevant Links

http://raspberrycompote.blogspot.com/20 ... -part.html
https://plus.google.com/111471803806847234766
Posts: 5
Joined: Sat Jan 16, 2016 10:16 pm
by dom » Sun Jan 17, 2016 4:36 pm
kagerato wrote:The FBIO_WAITFORVSYNC ioctl syscalls in this thread have a subtle bug. For an I/O control call, the third argument is always a pointer (address), not the integer value itself. When zero is passed, the kernel is asked to read from your process' virtual address zero, which very likely has either nothing or arbitrary data mapped there.

Are you saying this a a real bug that has been observed to misbehave/crash?

The actual implementation of FBIO_WAITFORVSYNC won't use the final parameter:
https://github.com/raspberrypi/linux/bl ... _fb.c#L439

So it doesn't care if it is NULL or pointing to a valid memory location. Are you saying something else dereferences the last parameter?
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 5084
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge
by kagerato » Sun Jan 17, 2016 7:34 pm
It's debatable whether the bug here is more the userspace invocation of the syscall or the kernel implementation of it. In my opinion, the kernel should catch and validate every argument, always, regardless of whether it is used. Unless there's something different about Linux on RPi compared to typical desktop and server configurations, userspace should be unable to map the first VM page, thus making address zero (NULL) always an invalid address.

If I'm observing and interpreting all the facts here correctly, the programs they've run neither crash nor generate an error. Userspace "gets away" with the invalid call because the kernel framebuffer driver doesn't care to check/respond.

Another perspective is that the fundamental flaw is in the interface or the nearly nonexistent documentation, not the code. There's this nebulous gray area that surrounds most of the ioctl syscalls, and it seems pretty clear now that implementers aren't sure what they should do.

I don't have an RPi to test with, so I can't tell you what actually happens. Maybe -rst- just did something wrong (other than the pointer/value mixup, I don't see what else would be wrong though).

What I can tell you for sure is that strict checks are how it's done in several other framebuffer drivers. The Intel, ATI, Matrox, Samsung S3C, OMap, and PS3 framebuffer drivers all detect the invalid address page fault and return (-EFAULT). A few lesser known drivers ignore the argument, leaving it untouched.

Furthermore, wait for vsync before pan definitely should work. If it's not working for anyone, and the user code itself doesn't have any (more) bugs, then that would be a driver issue.


References

http://lxr.free-electrons.com/source/dr ... rv.c#L1442
http://lxr.free-electrons.com/source/dr ... se.c#L1829
http://lxr.free-electrons.com/source/dr ... ase.c#L873
http://lxr.free-electrons.com/source/dr ... fb.c#L1017
http://lxr.free-electrons.com/source/dr ... ctl.c#L583
http://lxr.free-electrons.com/source/dr ... 3fb.c#L774
Posts: 5
Joined: Sat Jan 16, 2016 10:16 pm
by -rst- » Tue Jan 19, 2016 4:19 pm
Thanks for the interest and info provided kagerato. I will try to find time to look at this on my part.
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 1316
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by kagerato » Tue Jan 19, 2016 8:09 pm
You're welcome -rst- :) . Hopefully, the resolution will be simple and effective.
Posts: 5
Joined: Sat Jan 16, 2016 10:16 pm
by -rst- » Tue Feb 09, 2016 4:21 pm
I have now tested the fixed call https://github.com/rst-/raspberry-compo ... XIV.c#L154 - the wrong order seems to work as before - the correct order still produces tearing https://github.com/rst-/raspberry-compo ... testXIVb.c :roll:
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 1316
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by kagerato » Mon Feb 15, 2016 4:17 am
Are the ioctl syscalls succeeding or failing, I wonder? I don't see any other issues in your new code.

If those calls succeed but the effect is tearing, I'd conclude there's a bug in the framebuffer driver. Honestly, it's weird to me that it ever worked in the reverse order to begin with. When reversed like that, logically the flip should happen at an arbitrary time (and be practically guaranteed to tear at high frame rates). I suspect the wait for vsync actually does nothing at all in either case.

Ideally, someone should verify your test results, but unfortunately lack of access to the relevant hardware means that won't be me. Another thing to check is whether your kernel (and thus the framebuffer driver) is at the most recent version available.

I've read that in the past six months a fully open source Direct Rendering Manager (DRM) driver for the Broadcom VC4 GPU has been committed upstream to the Linux kernel. Seems like there's still work to be done on the 3D and OpenGL components, but the 2D stuff should already be functional. The DRM API is much more complicated (and powerful) than the old-school fbdev API. However, it includes wait for vsync and page-flip functions as standard, rather than as something which certain drivers implement and others don't (the case here). Might be worth checking out for the future.


References

https://dri.freedesktop.org/wiki/VC4/
http://elinux.org/RPi_Upstreaming
https://www.phoronix.com/scan.php?page=search&q=VC4
https://dvdhrm.wordpress.com/2012/09/13 ... tting-api/
https://dvdhrm.wordpress.com/2012/12/21 ... tting-api/
Posts: 5
Joined: Sat Jan 16, 2016 10:16 pm
by -rst- » Sat Feb 20, 2016 3:34 pm
I checked the ioctl call return values and all are ok. With the calls in the correct order the tearing occurs at about the same line at the top of the display. I suspect the wait for vsync takes so long to return or the flip to be set up that when the flip actually happens the display is already refreshing. Maybe the other way around the flip gets queued and the vsync is called so quickly they end up happening about simultaneously hence no tearing... :roll:

I had actually started looking at the DRM stuff as some other distros on other hardware do not seem to have fbdev anymore (also just learned that Debian on VirtualBox does have DRM but does not support 'dumb buffers').

I have also looked at the dispmanx stuff as a substitute for pure fb but that would obviously be very RPi specific.

Thanks for the input.
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 1316
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by kagerato » Sat Feb 20, 2016 8:13 pm
That is another plausible explanation I hadn't considered. Normally the kernel code performance shouldn't be so unreliable as to cause this. Only time profiling could tell for sure.
Posts: 5
Joined: Sat Jan 16, 2016 10:16 pm
by gmli » Sat Mar 05, 2016 1:18 pm
Hi,

I've tested the code from -rst- with a PiTFT 3.5 from Adafruit (on the last Retropie), but the return for FBIO_WAITFORVSYNC gives me -1. Any idea of what is going wrong ?
Posts: 4
Joined: Fri Mar 04, 2016 8:10 am
by -rst- » Mon Mar 07, 2016 10:45 am
Are you sure you use the latest version https://github.com/rst-/raspberry-compo ... XIV.c#L154 passing the proper pointer?
Code: Select all
        __u32 dummy = 0;
        ioctl(fbfd, FBIO_WAITFORVSYNC, &dummy);


[Edit] Ah, saw your other post and seems you have done this.

If that is not the issue, it is quite possible that the specific framebuffer driver does not implement/support FBIO_WAITFORVSYNC .
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 1316
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland