mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 12:08:36 +08:00
VNC: Ignore client framebuffer updates if nothing has changed (we can does this because client requests incremental updates
This commit is contained in:
parent
f3499b173a
commit
47a33cbb64
5 changed files with 51 additions and 15 deletions
|
@ -877,7 +877,7 @@ void nx_notify_rectangle(FAR NX_PLANEINFOTYPE *pinfo,
|
|||
{
|
||||
/* Queue the rectangular update */
|
||||
|
||||
ret = vnc_update_rectangle(session, rect);
|
||||
ret = vnc_update_rectangle(session, rect, true);
|
||||
if (ret < 0)
|
||||
{
|
||||
gdbg("ERROR: vnc_update_rectangle failed: %d\n", ret);
|
||||
|
|
|
@ -521,5 +521,6 @@ int vnc_client_pixelformat(FAR struct vnc_session_s *session,
|
|||
return -ENOSYS;
|
||||
}
|
||||
|
||||
session->change = true;
|
||||
return OK;
|
||||
}
|
||||
|
|
|
@ -176,6 +176,10 @@ int vnc_receiver(FAR struct vnc_session_s *session)
|
|||
return -errcode;
|
||||
}
|
||||
|
||||
/* REVISIT: This assertion sometimes fires when there is a client
|
||||
* disconnection.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(nrecvd == 1);
|
||||
|
||||
/* 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 */
|
||||
{
|
||||
FAR struct rfb_setencodings_s *encodings;
|
||||
uint32_t nencodings;
|
||||
unsigned int nencodings;
|
||||
|
||||
gvdbg("Received SetEncodings\n");
|
||||
|
||||
|
@ -239,7 +243,7 @@ int vnc_receiver(FAR struct vnc_session_s *session)
|
|||
/* Read the following encodings */
|
||||
|
||||
encodings = (FAR struct rfb_setencodings_s *)session->inbuf;
|
||||
nencodings = rfb_getbe32(encodings->nencodings);
|
||||
nencodings = rfb_getbe16(encodings->nencodings);
|
||||
|
||||
ret = vnc_read_remainder(session,
|
||||
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.y = rect.pt1.y + rfb_getbe16(update->height);
|
||||
|
||||
ret = vnc_update_rectangle(session, &rect);
|
||||
ret = vnc_update_rectangle(session, &rect, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
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 */
|
||||
|
||||
nencodings = rfb_getbe32(encodings->nencodings);
|
||||
nencodings = rfb_getbe16(encodings->nencodings);
|
||||
for (i = 0; i < nencodings; i++)
|
||||
{
|
||||
/* Get the next encoding */
|
||||
|
@ -475,10 +479,10 @@ int vnc_client_encodings(FAR struct vnc_session_s *session,
|
|||
if (encoding == RFB_ENCODING_RRE)
|
||||
{
|
||||
session->rre = true;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
session->change = true;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -246,14 +246,15 @@ struct vnc_session_s
|
|||
struct socket connect; /* Connected socket */
|
||||
volatile uint8_t state; /* See enum vnc_server_e */
|
||||
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 */
|
||||
|
||||
uint8_t display; /* Display number (for debug) */
|
||||
volatile uint8_t colorfmt; /* Remote color format (See include/nuttx/fb.h) */
|
||||
volatile uint8_t bpp; /* Remote bits per pixel */
|
||||
volatile bool bigendian; /* Remote expect data in big-endian format */
|
||||
volatile bool rre; /* Remote supports RRE encoding */
|
||||
volatile bool bigendian; /* True: Remote expect data in big-endian format */
|
||||
volatile bool rre; /* True: Remote supports RRE encoding */
|
||||
FAR uint8_t *fb; /* Allocated local frame buffer */
|
||||
|
||||
/* VNC client input support */
|
||||
|
@ -450,6 +451,7 @@ int vnc_stop_updater(FAR struct vnc_session_s *session);
|
|||
* Input Parameters:
|
||||
* session - An instance of the session structure.
|
||||
* rect - The rectanglular region to be updated.
|
||||
* change - True: Frame buffer data has changed
|
||||
*
|
||||
* Returned Value:
|
||||
* 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,
|
||||
FAR const struct nxgl_rect_s *rect);
|
||||
FAR const struct nxgl_rect_s *rect,
|
||||
bool change);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_receiver
|
||||
|
|
|
@ -490,6 +490,7 @@ int vnc_stop_updater(FAR struct vnc_session_s *session)
|
|||
* Input Parameters:
|
||||
* session - An instance of the session structure.
|
||||
* rect - The rectanglular region to be updated.
|
||||
* change - True: Frame buffer data has changed
|
||||
*
|
||||
* Returned Value:
|
||||
* 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,
|
||||
FAR const struct nxgl_rect_s *rect)
|
||||
FAR const struct nxgl_rect_s *rect, bool change)
|
||||
{
|
||||
FAR struct vnc_fbupdate_s *update;
|
||||
struct nxgl_rect_s intersection;
|
||||
|
@ -506,7 +507,7 @@ int vnc_update_rectangle(FAR struct vnc_session_s *session,
|
|||
|
||||
/* Clip rectangle to the screen dimensions */
|
||||
|
||||
nxgl_rectintersect(&intersection, rect, &g_wholescreen);
|
||||
nxgl_rectintersect(&intersection, rect, &g_wholescreen);
|
||||
|
||||
/* Make sure that the clipped rectangle has a area */
|
||||
|
||||
|
@ -519,20 +520,34 @@ int vnc_update_rectangle(FAR struct vnc_session_s *session,
|
|||
whupd = (memcmp(&intersection, &g_wholescreen,
|
||||
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();
|
||||
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)
|
||||
{
|
||||
/* Is this a new whole screen update */
|
||||
/* No whole screen updates in the queue. Is this a new whole
|
||||
* screen update?
|
||||
*/
|
||||
|
||||
if (whupd)
|
||||
{
|
||||
/* Yes.. Discard all of the previously queued updates */
|
||||
|
||||
FAR struct vnc_fbupdate_s *curr;
|
||||
FAR struct vnc_fbupdate_s *next;
|
||||
|
||||
/* Yes.. discard all of the previously queued updates */
|
||||
|
||||
updvdbg("New whole screen update...\n");
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* One whole screen update will be queued. There have been
|
||||
* no frame buffer data changes since this update was queued.
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
|
Loading…
Reference in a new issue