[gnome-remote-desktop] rdp-gfx-surface: Add handling to lower frame latency
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-remote-desktop] rdp-gfx-surface: Add handling to lower frame latency
- Date: Fri, 3 Sep 2021 09:34:43 +0000 (UTC)
commit 7d510f134d3cd428464c4bbc31f72bcd9f59806b
Author: Pascal Nowack <Pascal Nowack gmx de>
Date: Mon Jun 21 17:31:31 2021 +0200
rdp-gfx-surface: Add handling to lower frame latency
While the throttling mechanism can currently take care of higher and
increasing RTT values, it can currently not take care of lowering the
latency.
For example: If an RTT value of 300ms is detected and the RDP client is
slow with the decoding and displaying process, then
gnome-remote-desktop adapts to the situation.
However, if the RTT value suddenly drops to, for example, 150ms, then
the frame content might still be delayed by 300ms, since the client
might be too slow with the frame updates.
To solve this situation, recalculate the activate threshold for the
throttling mechanism, when a new frame is encoded or a frame is being
acked.
When the new activate threshold is lower than the current one, suspend
the encoding until the client acks enough logical frames.
After this, reevaluate the throttling situation.
This ensures that gnome-remote-desktop uses the lowest possible
activate threshold for the throttling mechanism to ensure an experience
with the lowest possible latency, while still being able to handle high
latency connections.
src/grd-rdp-gfx-surface.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 59 insertions(+), 1 deletion(-)
---
diff --git a/src/grd-rdp-gfx-surface.c b/src/grd-rdp-gfx-surface.c
index e05f44c..74f08e1 100644
--- a/src/grd-rdp-gfx-surface.c
+++ b/src/grd-rdp-gfx-surface.c
@@ -33,6 +33,7 @@ typedef enum _ThrottlingState
{
THROTTLING_STATE_INACTIVE,
THROTTLING_STATE_ACTIVE,
+ THROTTLING_STATE_ACTIVE_LOWERING_LATENCY,
} ThrottlingState;
struct _GrdRdpGfxSurface
@@ -111,6 +112,7 @@ grd_rdp_gfx_surface_unack_frame (GrdRdpGfxSurface *gfx_surface,
{
GrdRdpSurface *rdp_surface = gfx_surface->rdp_surface;
GrdRdpGfxFrameLog *frame_log = gfx_surface->frame_log;
+ uint32_t current_activate_throttling_th;
uint32_t n_unacked_frames;
uint32_t enc_rate = 0;
uint32_t ack_rate = 0;
@@ -133,7 +135,22 @@ grd_rdp_gfx_surface_unack_frame (GrdRdpGfxSurface *gfx_surface,
}
break;
case THROTTLING_STATE_ACTIVE:
- rdp_surface->encoding_suspended = enc_rate > ack_rate + 1;
+ current_activate_throttling_th = get_activate_throttling_th_from_rtt (
+ gfx_surface, gfx_surface->nw_auto_last_rtt_us);
+
+ if (current_activate_throttling_th < gfx_surface->activate_throttling_th)
+ {
+ gfx_surface->throttling_state = THROTTLING_STATE_ACTIVE_LOWERING_LATENCY;
+ rdp_surface->encoding_suspended = TRUE;
+ }
+ else
+ {
+ gfx_surface->activate_throttling_th = current_activate_throttling_th;
+ rdp_surface->encoding_suspended = enc_rate > ack_rate + 1;
+ }
+ break;
+ case THROTTLING_STATE_ACTIVE_LOWERING_LATENCY:
+ g_assert (rdp_surface->encoding_suspended);
break;
}
}
@@ -146,6 +163,7 @@ grd_rdp_gfx_surface_ack_frame (GrdRdpGfxSurface *gfx_surface,
GrdRdpSurface *rdp_surface = gfx_surface->rdp_surface;
GrdRdpGfxFrameLog *frame_log = gfx_surface->frame_log;
gboolean encoding_was_suspended;
+ uint32_t current_activate_throttling_th;
uint32_t n_unacked_frames;
uint32_t enc_rate = 0;
uint32_t ack_rate = 0;
@@ -165,11 +183,44 @@ grd_rdp_gfx_surface_ack_frame (GrdRdpGfxSurface *gfx_surface,
{
gfx_surface->throttling_state = THROTTLING_STATE_INACTIVE;
rdp_surface->encoding_suspended = FALSE;
+ break;
+ }
+
+ current_activate_throttling_th = get_activate_throttling_th_from_rtt (
+ gfx_surface, gfx_surface->nw_auto_last_rtt_us);
+ if (current_activate_throttling_th < gfx_surface->activate_throttling_th)
+ {
+ gfx_surface->throttling_state = THROTTLING_STATE_ACTIVE_LOWERING_LATENCY;
+ rdp_surface->encoding_suspended = TRUE;
}
else
{
+ gfx_surface->activate_throttling_th = current_activate_throttling_th;
+ rdp_surface->encoding_suspended = enc_rate > ack_rate;
+ }
+ break;
+ case THROTTLING_STATE_ACTIVE_LOWERING_LATENCY:
+ current_activate_throttling_th = get_activate_throttling_th_from_rtt (
+ gfx_surface, gfx_surface->nw_auto_last_rtt_us);
+
+ if (n_unacked_frames < current_activate_throttling_th)
+ {
+ gfx_surface->throttling_state = THROTTLING_STATE_INACTIVE;
+ rdp_surface->encoding_suspended = FALSE;
+ }
+ else if (n_unacked_frames == current_activate_throttling_th)
+ {
+ gfx_surface->throttling_state = THROTTLING_STATE_ACTIVE;
rdp_surface->encoding_suspended = enc_rate > ack_rate;
}
+ else if (n_unacked_frames > current_activate_throttling_th)
+ {
+ g_assert (rdp_surface->encoding_suspended);
+ }
+ else
+ {
+ g_assert_not_reached ();
+ }
break;
}
@@ -207,6 +258,13 @@ reevaluate_encoding_suspension_state (GrdRdpGfxSurface *gfx_surface)
g_assert (n_unacked_frames > gfx_surface->deactivate_throttling_th);
g_assert (rdp_surface->encoding_suspended);
break;
+ case THROTTLING_STATE_ACTIVE_LOWERING_LATENCY:
+ /*
+ * While the graphics pipeline rewrites the frame history, the RTT
+ * detection mechanism cannot submit a new round trip time.
+ */
+ g_assert_not_reached ();
+ break;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]