diff --git a/graphics/vnc/server/vnc_fbdev.c b/graphics/vnc/server/vnc_fbdev.c index bdee741b810..90715620525 100644 --- a/graphics/vnc/server/vnc_fbdev.c +++ b/graphics/vnc/server/vnc_fbdev.c @@ -447,6 +447,31 @@ static int up_updateearea(FAR struct fb_vtable_s *vtable, return ret; } +#ifdef CONFIG_FB_SYNC + +/**************************************************************************** + * Name: up_waitforsync + ****************************************************************************/ + +static int up_waitforsync(FAR struct fb_vtable_s *vtable) +{ + FAR struct vnc_fbinfo_s *fbinfo = (FAR struct vnc_fbinfo_s *)vtable; + FAR struct vnc_session_s *session; + + DEBUGASSERT(fbinfo); + DEBUGASSERT(fbinfo->display >= 0 && fbinfo->display < RFB_MAX_DISPLAYS); + + session = g_vnc_sessions[fbinfo->display]; + + if (session && session->state == VNCSERVER_RUNNING) + { + return nxsem_wait(&session->vsyncsem); + } + + return ERROR; +} +#endif + /**************************************************************************** * Name: vnc_start_server * @@ -817,6 +842,9 @@ FAR struct fb_vtable_s *up_fbgetvplane(int display, int vplane) #ifdef CONFIG_FB_HWCURSOR fbinfo->vtable.getcursor = up_getcursor, fbinfo->vtable.setcursor = up_setcursor, +#endif +#ifdef CONFIG_FB_SYNC + fbinfo->vtable.waitforvsync = up_waitforsync; #endif fbinfo->vtable.updatearea = up_updateearea, fbinfo->display = display; diff --git a/graphics/vnc/server/vnc_server.c b/graphics/vnc/server/vnc_server.c index 9af8f90ab45..78c6a9c2c95 100644 --- a/graphics/vnc/server/vnc_server.c +++ b/graphics/vnc/server/vnc_server.c @@ -279,6 +279,11 @@ int vnc_server(int argc, FAR char *argv[]) nxsem_init(&session->freesem, 0, CONFIG_VNCSERVER_NUPDATES); nxsem_init(&session->queuesem, 0, 0); +#ifdef CONFIG_FB_SYNC + nxsem_init(&session->vsyncsem, 0, 0); + nxsem_set_protocol(&session->vsyncsem, SEM_PRIO_NONE); +#endif + /* Inform any waiter that we have started */ vnc_reset_session(session, fb, display); diff --git a/graphics/vnc/server/vnc_server.h b/graphics/vnc/server/vnc_server.h index 489c365096a..7ce0ffd6def 100644 --- a/graphics/vnc/server/vnc_server.h +++ b/graphics/vnc/server/vnc_server.h @@ -235,6 +235,9 @@ struct vnc_session_s sq_queue_t updqueue; sem_t freesem; sem_t queuesem; +#ifdef CONFIG_FB_SYNC + sem_t vsyncsem; +#endif /* I/O buffers for misc network send/receive */ diff --git a/graphics/vnc/server/vnc_updater.c b/graphics/vnc/server/vnc_updater.c index 5a79851e70f..9d3fe273b82 100644 --- a/graphics/vnc/server/vnc_updater.c +++ b/graphics/vnc/server/vnc_updater.c @@ -356,6 +356,9 @@ static FAR void *vnc_updater(FAR void *arg) FAR struct vnc_session_s *session = (FAR struct vnc_session_s *)arg; FAR struct vnc_fbupdate_s *srcrect; int ret; +#ifdef CONFIG_FB_SYNC + int val; +#endif DEBUGASSERT(session != NULL); ginfo("Updater running for Display %d\n", session->display); @@ -393,6 +396,21 @@ static FAR void *vnc_updater(FAR void *arg) vnc_free_update(session, srcrect); +#ifdef CONFIG_FB_SYNC + ret = nxsem_get_value(&session->vsyncsem, &val); + + if (ret < 0) + { + gerr("ERROR: Get vsync sem failed: %d\n", ret); + break; + } + + if (sq_count(&session->updqueue) == 0 && val <= 0) + { + nxsem_post(&session->vsyncsem); + } +#endif + /* Break out and terminate the server if the encoding failed */ if (ret < 0)