mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 23:03:27 +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:
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
Reference in New Issue
Block a user