video/fb: add vsync offset support

Android Documentation: https://source.android.com/docs/core/graphics/implement-vsync#vsync_offset

Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
pengyiqiang 2023-03-27 14:09:59 +08:00 committed by Xiang Xiao
parent abbc661282
commit 0ed82e8380
3 changed files with 53 additions and 7 deletions

View File

@ -48,6 +48,20 @@ This example will walk through the path from userspace to hardware-specific deta
#. ``include/nuttx/lcd/lcd.h`` provides structures and APIs needed to work with LCD screens, whereas using the framebuffer adapter or the :doc:`lcd`;
VSYNC
======
Vertical synchronization (VSync) synchronizes the frame rate of an application's graphics with the refresh rate of the display, helping to establish stability.
If not synchronized, it may cause screen tearing, which is the effect of the image appearing to have horizontal jagged edges or ghosting across the entire screen.
VSYNC Offset
------------
During the VSYNC event, the screen starts displaying frame N while the renderer begins compositing window for frame N+1.
The application processes waiting input and generates frame N+2.
When the renderer has a short rendering time, it can cause a delay of almost two frames from the end of rendering to the completion of screen display.
To solve this problem, ``FBIOSET_VSYNCOFFSET`` can be used to set the VSYNC offset time (in microseconds) and reduce the delay from input device to screen using the VSYNC offset.
Examples
========

View File

@ -39,6 +39,8 @@
#include <nuttx/fs/fs.h>
#include <nuttx/fs/ioctl.h>
#include <nuttx/video/fb.h>
#include <nuttx/clock.h>
#include <nuttx/wdog.h>
/****************************************************************************
* Private Types
@ -59,6 +61,8 @@ struct fb_chardev_s
uint8_t plane; /* Video plan number */
uint8_t bpp; /* Bits per pixel */
volatile bool pollready; /* Poll ready flag */
clock_t vsyncoffset; /* VSync offset ticks */
struct wdog_s wdog; /* VSync offset timer */
};
/****************************************************************************
@ -540,6 +544,13 @@ static int fb_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
break;
case FBIOSET_VSYNCOFFSET:
{
fb->vsyncoffset = USEC2TICK(arg);
ret = OK;
}
break;
case FBIOGET_VSCREENINFO:
{
struct fb_videoinfo_s vinfo;
@ -751,6 +762,21 @@ static int fb_poll(FAR struct file *filep, struct pollfd *fds, bool setup)
return OK;
}
/****************************************************************************
* Name: fb_do_pollnotify
****************************************************************************/
static void fb_do_pollnotify(wdparm_t arg)
{
FAR struct fb_chardev_s *fb = (FAR struct fb_chardev_s *)arg;
fb->pollready = true;
/* Notify framebuffer is writable. */
poll_notify(&fb->fds, 1, POLLOUT);
}
/****************************************************************************
* Name: fb_pollnotify
*
@ -770,11 +796,14 @@ void fb_pollnotify(FAR struct fb_vtable_s *vtable)
fb = vtable->priv;
fb->pollready = true;
/* Notify framebuffer is writable. */
poll_notify(&fb->fds, 1, POLLOUT);
if (fb->vsyncoffset > 0)
{
wd_start(&fb->wdog, fb->vsyncoffset, fb_do_pollnotify, (wdparm_t)fb);
}
else
{
fb_do_pollnotify((wdparm_t)fb);
}
}
/****************************************************************************

View File

@ -288,12 +288,15 @@
#define FBIO_CLEARNOTIFY _FBIOC(0x0017) /* Clear notify signal */
#define FBIOSET_VSYNCOFFSET _FBIOC(0x0018) /* Set VSync offset in usec
* Argument: int */
/* Linux Support ************************************************************/
#define FBIOGET_VSCREENINFO _FBIOC(0x0018) /* Get video variable info */
#define FBIOGET_VSCREENINFO _FBIOC(0x0019) /* Get video variable info */
/* Argument: writable struct
* fb_var_screeninfo */
#define FBIOGET_FSCREENINFO _FBIOC(0x0019) /* Get video fix info */
#define FBIOGET_FSCREENINFO _FBIOC(0x001a) /* Get video fix info */
/* Argument: writable struct
* fb_fix_screeninfo */