diff --git a/Documentation/components/drivers/special/framebuffer.rst b/Documentation/components/drivers/special/framebuffer.rst index 0f68399da0..9805ef95ce 100644 --- a/Documentation/components/drivers/special/framebuffer.rst +++ b/Documentation/components/drivers/special/framebuffer.rst @@ -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 ======== diff --git a/drivers/video/fb.c b/drivers/video/fb.c index 2a88e4f329..508ef84257 100644 --- a/drivers/video/fb.c +++ b/drivers/video/fb.c @@ -39,6 +39,8 @@ #include #include #include +#include +#include /**************************************************************************** * 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); + } } /**************************************************************************** diff --git a/include/nuttx/video/fb.h b/include/nuttx/video/fb.h index 0db5d8b00b..3c39fdbe09 100644 --- a/include/nuttx/video/fb.h +++ b/include/nuttx/video/fb.h @@ -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 */