GUACAMOLE-377: Leverage RDPGFX to report remote frame statistics to the client.
This commit is contained in:
parent
52c8683bcf
commit
669e02b4dc
@ -372,12 +372,27 @@ BOOL guac_rdp_gdi_set_bounds(rdpContext* context, const rdpBounds* bounds) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL guac_rdp_gdi_begin_paint(rdpContext* context) {
|
||||||
|
|
||||||
|
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||||
|
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||||
|
|
||||||
|
/* A new frame is beginning */
|
||||||
|
rdp_client->in_frame = 1;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
BOOL guac_rdp_gdi_end_paint(rdpContext* context) {
|
BOOL guac_rdp_gdi_end_paint(rdpContext* context) {
|
||||||
|
|
||||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||||
rdpGdi* gdi = context->gdi;
|
rdpGdi* gdi = context->gdi;
|
||||||
|
|
||||||
|
/* The current frame has ended */
|
||||||
|
rdp_client->in_frame = 0;
|
||||||
|
|
||||||
/* Ignore paint if GDI output is suppressed */
|
/* Ignore paint if GDI output is suppressed */
|
||||||
if (gdi->suppressOutput)
|
if (gdi->suppressOutput)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -396,12 +411,30 @@ BOOL guac_rdp_gdi_end_paint(rdpContext* context) {
|
|||||||
gdi->primary_buffer + 4*x + y*gdi->stride,
|
gdi->primary_buffer + 4*x + y*gdi->stride,
|
||||||
CAIRO_FORMAT_RGB24, w, h, gdi->stride);
|
CAIRO_FORMAT_RGB24, w, h, gdi->stride);
|
||||||
|
|
||||||
|
guac_timestamp frame_end = guac_timestamp_current();
|
||||||
|
int time_elapsed = frame_end - rdp_client->frame_start;
|
||||||
|
|
||||||
/* Send surface to buffer */
|
/* Send surface to buffer */
|
||||||
guac_common_surface_draw(rdp_client->display->default_surface, x, y, surface);
|
guac_common_surface_draw(rdp_client->display->default_surface, x, y, surface);
|
||||||
|
|
||||||
/* Free surface */
|
/* Free surface */
|
||||||
cairo_surface_destroy(surface);
|
cairo_surface_destroy(surface);
|
||||||
|
|
||||||
|
/* A new frame has been received from the RDP server and processed */
|
||||||
|
rdp_client->frames_received++;
|
||||||
|
|
||||||
|
/* Flush a new frame if the client is ready for it */
|
||||||
|
if (time_elapsed >= guac_client_get_processing_lag(client)) {
|
||||||
|
|
||||||
|
guac_common_display_flush(rdp_client->display);
|
||||||
|
guac_client_end_multiple_frames(client, rdp_client->frames_received);
|
||||||
|
guac_socket_flush(client->socket);
|
||||||
|
|
||||||
|
rdp_client->frame_start = frame_end;
|
||||||
|
rdp_client->frames_received = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -156,8 +156,22 @@ BOOL guac_rdp_gdi_opaquerect(rdpContext* context,
|
|||||||
BOOL guac_rdp_gdi_set_bounds(rdpContext* context, const rdpBounds* bounds);
|
BOOL guac_rdp_gdi_set_bounds(rdpContext* context, const rdpBounds* bounds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler called when a paint operation is complete. We don't actually
|
* Handler called when a paint operation is beginning. This function is
|
||||||
* use this, but FreeRDP requires it. Calling this function has no effect.
|
* expected to be called by the FreeRDP GDI implementation of RemoteFX when a
|
||||||
|
* new frame is beginning.
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* The rdpContext associated with the current RDP session.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* TRUE if successful, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
BOOL guac_rdp_gdi_begin_paint(rdpContext* context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler called when a paint operation is complete. This function is
|
||||||
|
* expected to be called by the FreeRDP GDI implementation of RemoteFX when a
|
||||||
|
* new frame has been completed.
|
||||||
*
|
*
|
||||||
* @param context
|
* @param context
|
||||||
* The rdpContext associated with the current RDP session.
|
* The rdpContext associated with the current RDP session.
|
||||||
|
@ -179,6 +179,7 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) {
|
|||||||
|
|
||||||
/* Set up GDI */
|
/* Set up GDI */
|
||||||
instance->update->DesktopResize = guac_rdp_gdi_desktop_resize;
|
instance->update->DesktopResize = guac_rdp_gdi_desktop_resize;
|
||||||
|
instance->update->BeginPaint = guac_rdp_gdi_begin_paint;
|
||||||
instance->update->EndPaint = guac_rdp_gdi_end_paint;
|
instance->update->EndPaint = guac_rdp_gdi_end_paint;
|
||||||
instance->update->SetBounds = guac_rdp_gdi_set_bounds;
|
instance->update->SetBounds = guac_rdp_gdi_set_bounds;
|
||||||
|
|
||||||
@ -530,6 +531,7 @@ static int guac_rdp_handle_connection(guac_client* client) {
|
|||||||
rdp_client->rdp_inst = rdp_inst;
|
rdp_client->rdp_inst = rdp_inst;
|
||||||
|
|
||||||
guac_timestamp last_frame_end = guac_timestamp_current();
|
guac_timestamp last_frame_end = guac_timestamp_current();
|
||||||
|
rdp_client->frame_start = guac_timestamp_current();
|
||||||
|
|
||||||
/* Signal that reconnect has been completed */
|
/* Signal that reconnect has been completed */
|
||||||
guac_rdp_disp_reconnect_complete(rdp_client->disp);
|
guac_rdp_disp_reconnect_complete(rdp_client->disp);
|
||||||
@ -569,6 +571,13 @@ static int guac_rdp_handle_connection(guac_client* client) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Continue handling inbound data if we are in the middle of an RDP frame */
|
||||||
|
if (rdp_client->in_frame) {
|
||||||
|
wait_result = rdp_guac_client_wait_for_messages(client, GUAC_RDP_FRAME_START_TIMEOUT);
|
||||||
|
if (wait_result >= 0)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Calculate time remaining in frame */
|
/* Calculate time remaining in frame */
|
||||||
frame_end = guac_timestamp_current();
|
frame_end = guac_timestamp_current();
|
||||||
frame_remaining = frame_start + GUAC_RDP_FRAME_DURATION
|
frame_remaining = frame_start + GUAC_RDP_FRAME_DURATION
|
||||||
@ -612,11 +621,17 @@ static int guac_rdp_handle_connection(guac_client* client) {
|
|||||||
guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_UNAVAILABLE,
|
guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_UNAVAILABLE,
|
||||||
"Connection closed.");
|
"Connection closed.");
|
||||||
|
|
||||||
/* Flush frame only if successful */
|
/* Flush frame only if successful and an RDP frame is not known to be
|
||||||
else {
|
* in progress */
|
||||||
|
else if (rdp_client->frames_received) {
|
||||||
|
|
||||||
guac_common_display_flush(rdp_client->display);
|
guac_common_display_flush(rdp_client->display);
|
||||||
guac_client_end_frame(client);
|
guac_client_end_multiple_frames(client, rdp_client->frames_received);
|
||||||
guac_socket_flush(client->socket);
|
guac_socket_flush(client->socket);
|
||||||
|
|
||||||
|
rdp_client->frame_start = guac_timestamp_current();
|
||||||
|
rdp_client->frames_received = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,27 @@ typedef struct guac_rdp_client {
|
|||||||
*/
|
*/
|
||||||
guac_common_surface* current_surface;
|
guac_common_surface* current_surface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the RDP server has reported that a new frame is in progress, and
|
||||||
|
* we are now receiving updates relevant to that frame.
|
||||||
|
*/
|
||||||
|
int in_frame;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of distinct frames received from the RDP server since last
|
||||||
|
* flush, if the RDP server supports reporting frame boundaries. If the RDP
|
||||||
|
* server does not support tracking frames, this will be zero.
|
||||||
|
*/
|
||||||
|
int frames_received;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server timestamp of the end of the last frame received from the RDP
|
||||||
|
* server, as returned by guac_timestamp_current(), if the RDP server
|
||||||
|
* supports reporting frame boundaries. If the RDP server does not support
|
||||||
|
* tracking frames, this will be zero.
|
||||||
|
*/
|
||||||
|
guac_timestamp frame_start;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current state of the keyboard with respect to the RDP session.
|
* The current state of the keyboard with respect to the RDP session.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user