VNC: Ignore client framebuffer updates if nothing has changed (we can does this because client requests incremental updates

This commit is contained in:
Gregory Nutt
2016-04-23 10:22:54 -06:00
parent f3499b173a
commit 47a33cbb64
5 changed files with 51 additions and 15 deletions
+1 -1
View File
@@ -877,7 +877,7 @@ void nx_notify_rectangle(FAR NX_PLANEINFOTYPE *pinfo,
{ {
/* Queue the rectangular update */ /* Queue the rectangular update */
ret = vnc_update_rectangle(session, rect); ret = vnc_update_rectangle(session, rect, true);
if (ret < 0) if (ret < 0)
{ {
gdbg("ERROR: vnc_update_rectangle failed: %d\n", ret); gdbg("ERROR: vnc_update_rectangle failed: %d\n", ret);
+1
View File
@@ -521,5 +521,6 @@ int vnc_client_pixelformat(FAR struct vnc_session_s *session,
return -ENOSYS; return -ENOSYS;
} }
session->change = true;
return OK; return OK;
} }
+9 -5
View File
@@ -176,6 +176,10 @@ int vnc_receiver(FAR struct vnc_session_s *session)
return -errcode; return -errcode;
} }
/* REVISIT: This assertion sometimes fires when there is a client
* disconnection.
*/
DEBUGASSERT(nrecvd == 1); DEBUGASSERT(nrecvd == 1);
/* The single byte received should be the message type. Handle the /* The single byte received should be the message type. Handle the
@@ -218,7 +222,7 @@ int vnc_receiver(FAR struct vnc_session_s *session)
case RFB_SETENCODINGS_MSG: /* SetEncodings */ case RFB_SETENCODINGS_MSG: /* SetEncodings */
{ {
FAR struct rfb_setencodings_s *encodings; FAR struct rfb_setencodings_s *encodings;
uint32_t nencodings; unsigned int nencodings;
gvdbg("Received SetEncodings\n"); gvdbg("Received SetEncodings\n");
@@ -239,7 +243,7 @@ int vnc_receiver(FAR struct vnc_session_s *session)
/* Read the following encodings */ /* Read the following encodings */
encodings = (FAR struct rfb_setencodings_s *)session->inbuf; encodings = (FAR struct rfb_setencodings_s *)session->inbuf;
nencodings = rfb_getbe32(encodings->nencodings); nencodings = rfb_getbe16(encodings->nencodings);
ret = vnc_read_remainder(session, ret = vnc_read_remainder(session,
nencodings * sizeof(uint32_t), nencodings * sizeof(uint32_t),
@@ -291,7 +295,7 @@ int vnc_receiver(FAR struct vnc_session_s *session)
rect.pt2.x = rect.pt1.x + rfb_getbe16(update->width); rect.pt2.x = rect.pt1.x + rfb_getbe16(update->width);
rect.pt2.y = rect.pt1.y + rfb_getbe16(update->height); rect.pt2.y = rect.pt1.y + rfb_getbe16(update->height);
ret = vnc_update_rectangle(session, &rect); ret = vnc_update_rectangle(session, &rect, false);
if (ret < 0) if (ret < 0)
{ {
gdbg("ERROR: Failed to queue update: %d\n", ret); gdbg("ERROR: Failed to queue update: %d\n", ret);
@@ -463,7 +467,7 @@ int vnc_client_encodings(FAR struct vnc_session_s *session,
/* Loop for each client supported encoding */ /* Loop for each client supported encoding */
nencodings = rfb_getbe32(encodings->nencodings); nencodings = rfb_getbe16(encodings->nencodings);
for (i = 0; i < nencodings; i++) for (i = 0; i < nencodings; i++)
{ {
/* Get the next encoding */ /* Get the next encoding */
@@ -475,10 +479,10 @@ int vnc_client_encodings(FAR struct vnc_session_s *session,
if (encoding == RFB_ENCODING_RRE) if (encoding == RFB_ENCODING_RRE)
{ {
session->rre = true; session->rre = true;
return OK;
} }
} }
session->change = true;
return OK; return OK;
} }
+6 -3
View File
@@ -246,14 +246,15 @@ struct vnc_session_s
struct socket connect; /* Connected socket */ struct socket connect; /* Connected socket */
volatile uint8_t state; /* See enum vnc_server_e */ volatile uint8_t state; /* See enum vnc_server_e */
volatile uint8_t nwhupd; /* Number of whole screen updates queued */ volatile uint8_t nwhupd; /* Number of whole screen updates queued */
volatile bool change; /* True: Frambebuffer data change since last whole screen update */
/* Display geometry and color characteristics */ /* Display geometry and color characteristics */
uint8_t display; /* Display number (for debug) */ uint8_t display; /* Display number (for debug) */
volatile uint8_t colorfmt; /* Remote color format (See include/nuttx/fb.h) */ volatile uint8_t colorfmt; /* Remote color format (See include/nuttx/fb.h) */
volatile uint8_t bpp; /* Remote bits per pixel */ volatile uint8_t bpp; /* Remote bits per pixel */
volatile bool bigendian; /* Remote expect data in big-endian format */ volatile bool bigendian; /* True: Remote expect data in big-endian format */
volatile bool rre; /* Remote supports RRE encoding */ volatile bool rre; /* True: Remote supports RRE encoding */
FAR uint8_t *fb; /* Allocated local frame buffer */ FAR uint8_t *fb; /* Allocated local frame buffer */
/* VNC client input support */ /* VNC client input support */
@@ -450,6 +451,7 @@ int vnc_stop_updater(FAR struct vnc_session_s *session);
* Input Parameters: * Input Parameters:
* session - An instance of the session structure. * session - An instance of the session structure.
* rect - The rectanglular region to be updated. * rect - The rectanglular region to be updated.
* change - True: Frame buffer data has changed
* *
* Returned Value: * Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on * Zero (OK) is returned on success; a negated errno value is returned on
@@ -458,7 +460,8 @@ int vnc_stop_updater(FAR struct vnc_session_s *session);
****************************************************************************/ ****************************************************************************/
int vnc_update_rectangle(FAR struct vnc_session_s *session, int vnc_update_rectangle(FAR struct vnc_session_s *session,
FAR const struct nxgl_rect_s *rect); FAR const struct nxgl_rect_s *rect,
bool change);
/**************************************************************************** /****************************************************************************
* Name: vnc_receiver * Name: vnc_receiver
+33 -5
View File
@@ -490,6 +490,7 @@ int vnc_stop_updater(FAR struct vnc_session_s *session)
* Input Parameters: * Input Parameters:
* session - An instance of the session structure. * session - An instance of the session structure.
* rect - The rectanglular region to be updated. * rect - The rectanglular region to be updated.
* change - True: Frame buffer data has changed
* *
* Returned Value: * Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on * Zero (OK) is returned on success; a negated errno value is returned on
@@ -498,7 +499,7 @@ int vnc_stop_updater(FAR struct vnc_session_s *session)
****************************************************************************/ ****************************************************************************/
int vnc_update_rectangle(FAR struct vnc_session_s *session, int vnc_update_rectangle(FAR struct vnc_session_s *session,
FAR const struct nxgl_rect_s *rect) FAR const struct nxgl_rect_s *rect, bool change)
{ {
FAR struct vnc_fbupdate_s *update; FAR struct vnc_fbupdate_s *update;
struct nxgl_rect_s intersection; struct nxgl_rect_s intersection;
@@ -519,20 +520,34 @@ int vnc_update_rectangle(FAR struct vnc_session_s *session,
whupd = (memcmp(&intersection, &g_wholescreen, whupd = (memcmp(&intersection, &g_wholescreen,
sizeof(struct nxgl_rect_s)) == 0); sizeof(struct nxgl_rect_s)) == 0);
/* Ignore all updates if there is a queue whole screen update */ /* Ignore any client update requests if there have been no changes to
* the framebuffer since the last whole screen update.
*/
sched_lock(); sched_lock();
if (!change && !session->change)
{
/* No.. ignore the client update. We have nothing new to report. */
sched_unlock();
return OK;
}
/* Ignore all updates if there is a queued whole screen update */
if (session->nwhupd == 0) if (session->nwhupd == 0)
{ {
/* Is this a new whole screen update */ /* No whole screen updates in the queue. Is this a new whole
* screen update?
*/
if (whupd) if (whupd)
{ {
/* Yes.. Discard all of the previously queued updates */
FAR struct vnc_fbupdate_s *curr; FAR struct vnc_fbupdate_s *curr;
FAR struct vnc_fbupdate_s *next; FAR struct vnc_fbupdate_s *next;
/* Yes.. discard all of the previously queued updates */
updvdbg("New whole screen update...\n"); updvdbg("New whole screen update...\n");
curr = (FAR struct vnc_fbupdate_s *)session->updqueue.head; curr = (FAR struct vnc_fbupdate_s *)session->updqueue.head;
@@ -545,7 +560,20 @@ int vnc_update_rectangle(FAR struct vnc_session_s *session,
vnc_free_update(session, curr); vnc_free_update(session, curr);
} }
/* One whole screen update will be queued. There have been
* no frame buffer data changes since this update was queued.
*/
session->nwhupd = 1; session->nwhupd = 1;
session->change = false;
}
else
{
/* We are not updating the whole screen. Remember if this
* update (OR a preceding update) was due to a data change.
*/
session->change |= change;
} }
/* Allocate an update structure... waiting if necessary */ /* Allocate an update structure... waiting if necessary */