[gnome-remote-desktop] rdp: Run do_render() as GSourceFunc in custom GMainContext
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-remote-desktop] rdp: Run do_render() as GSourceFunc in custom GMainContext
- Date: Thu, 14 Oct 2021 14:42:42 +0000 (UTC)
commit acd990aff25a327e6f0fb2797d4998824b0fbdc0
Author: Pascal Nowack <Pascal Nowack gmx de>
Date: Mon Aug 23 19:18:10 2021 +0200
rdp: Run do_render() as GSourceFunc in custom GMainContext
In order to be able to run all graphics operations in a different
thread, add a new GSource, which runs do_render() as callback function.
This GSource will then be attached to a custom GMainContext.
In a future commit, this custom GMainContext will be the GMainContext
of the graphics thread.
src/grd-rdp-pipewire-stream.c | 122 +++++++++++++++++++++++++-----------------
src/grd-rdp-pipewire-stream.h | 1 +
src/grd-session-rdp.c | 1 +
3 files changed, 76 insertions(+), 48 deletions(-)
---
diff --git a/src/grd-rdp-pipewire-stream.c b/src/grd-rdp-pipewire-stream.c
index 1d4a5a2..ba8050a 100644
--- a/src/grd-rdp-pipewire-stream.c
+++ b/src/grd-rdp-pipewire-stream.c
@@ -67,6 +67,7 @@ struct _GrdRdpPipeWireStream
struct spa_hook pipewire_core_listener;
+ GSource *render_source;
GMutex frame_mutex;
GrdRdpFrame *pending_frame;
@@ -81,6 +82,69 @@ struct _GrdRdpPipeWireStream
G_DEFINE_TYPE (GrdRdpPipeWireStream, grd_rdp_pipewire_stream,
G_TYPE_OBJECT)
+static gboolean
+do_render (gpointer user_data)
+{
+ GrdRdpPipeWireStream *stream = GRD_RDP_PIPEWIRE_STREAM (user_data);
+ GrdRdpFrame *frame;
+
+ g_mutex_lock (&stream->frame_mutex);
+ frame = g_steal_pointer (&stream->pending_frame);
+ g_mutex_unlock (&stream->frame_mutex);
+
+ if (!frame)
+ return G_SOURCE_CONTINUE;
+
+ if (frame->data)
+ {
+ grd_session_rdp_take_buffer (stream->session_rdp, frame->data,
+ frame->width, frame->height);
+ }
+
+ if (frame->pointer_bitmap)
+ {
+ grd_session_rdp_update_pointer (stream->session_rdp,
+ frame->pointer_hotspot_x,
+ frame->pointer_hotspot_y,
+ frame->pointer_width,
+ frame->pointer_height,
+ frame->pointer_bitmap);
+ }
+ else if (frame->pointer_is_hidden)
+ {
+ grd_session_rdp_hide_pointer (stream->session_rdp);
+ }
+
+ g_free (frame);
+
+ return G_SOURCE_CONTINUE;
+}
+
+static gboolean
+render_source_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ g_source_set_ready_time (source, -1);
+
+ return callback (user_data);
+}
+
+static GSourceFuncs render_source_funcs =
+{
+ .dispatch = render_source_dispatch,
+};
+
+static void
+create_render_source (GrdRdpPipeWireStream *stream,
+ GMainContext *render_context)
+{
+ stream->render_source = g_source_new (&render_source_funcs, sizeof (GSource));
+ g_source_set_callback (stream->render_source, do_render, stream, NULL);
+ g_source_set_ready_time (stream->render_source, -1);
+ g_source_attach (stream->render_source, render_context);
+}
+
static gboolean
pipewire_loop_source_prepare (GSource *base,
int *timeout)
@@ -212,49 +276,6 @@ on_stream_param_changed (void *user_data,
params, G_N_ELEMENTS (params));
}
-static int
-do_render (struct spa_loop *loop,
- bool async,
- uint32_t seq,
- const void *data,
- size_t size,
- void *user_data)
-{
- GrdRdpPipeWireStream *stream = GRD_RDP_PIPEWIRE_STREAM (user_data);
- GrdRdpFrame *frame;
-
- g_mutex_lock (&stream->frame_mutex);
- frame = g_steal_pointer (&stream->pending_frame);
- g_mutex_unlock (&stream->frame_mutex);
-
- if (!frame)
- return 0;
-
- if (frame->data)
- {
- grd_session_rdp_take_buffer (stream->session_rdp, frame->data,
- frame->width, frame->height);
- }
-
- if (frame->pointer_bitmap)
- {
- grd_session_rdp_update_pointer (stream->session_rdp,
- frame->pointer_hotspot_x,
- frame->pointer_hotspot_y,
- frame->pointer_width,
- frame->pointer_height,
- frame->pointer_bitmap);
- }
- else if (frame->pointer_is_hidden)
- {
- grd_session_rdp_hide_pointer (stream->session_rdp);
- }
-
- g_free (frame);
-
- return 0;
-}
-
static GrdRdpFrame *
process_buffer (GrdRdpPipeWireStream *stream,
struct spa_buffer *buffer)
@@ -386,8 +407,6 @@ static void
on_stream_process (void *user_data)
{
GrdRdpPipeWireStream *stream = GRD_RDP_PIPEWIRE_STREAM (user_data);
- GrdPipeWireSource *pipewire_source =
- (GrdPipeWireSource *) stream->pipewire_source;
struct pw_buffer *next_buffer;
struct pw_buffer *buffer = NULL;
GrdRdpFrame *frame;
@@ -419,9 +438,7 @@ on_stream_process (void *user_data)
pw_stream_queue_buffer (stream->pipewire_stream, buffer);
- pw_loop_invoke (pipewire_source->pipewire_loop, do_render,
- SPA_ID_INVALID, NULL, 0,
- false, stream);
+ g_source_set_ready_time (stream->render_source, 0);
}
static const struct pw_stream_events stream_events = {
@@ -516,6 +533,7 @@ static const struct pw_core_events core_events = {
GrdRdpPipeWireStream *
grd_rdp_pipewire_stream_new (GrdSessionRdp *session_rdp,
+ GMainContext *render_context,
uint32_t src_node_id,
uint32_t refresh_rate,
GError **error)
@@ -529,6 +547,8 @@ grd_rdp_pipewire_stream_new (GrdSessionRdp *session_rdp,
stream->session_rdp = session_rdp;
stream->src_node_id = src_node_id;
+ create_render_source (stream, render_context);
+
pipewire_source = create_pipewire_source ();
if (!pipewire_source)
{
@@ -586,6 +606,12 @@ grd_rdp_pipewire_stream_finalize (GObject *object)
g_clear_pointer (&stream->pipewire_source, g_source_unref);
}
+ if (stream->render_source)
+ {
+ g_source_destroy (stream->render_source);
+ g_clear_pointer (&stream->render_source, g_source_unref);
+ }
+
G_OBJECT_CLASS (grd_rdp_pipewire_stream_parent_class)->finalize (object);
}
diff --git a/src/grd-rdp-pipewire-stream.h b/src/grd-rdp-pipewire-stream.h
index 69b7592..dcedf84 100644
--- a/src/grd-rdp-pipewire-stream.h
+++ b/src/grd-rdp-pipewire-stream.h
@@ -31,6 +31,7 @@ G_DECLARE_FINAL_TYPE (GrdRdpPipeWireStream, grd_rdp_pipewire_stream,
GObject)
GrdRdpPipeWireStream *grd_rdp_pipewire_stream_new (GrdSessionRdp *session_rdp,
+ GMainContext *render_context,
uint32_t src_node_id,
uint32_t refresh_rate,
GError **error);
diff --git a/src/grd-session-rdp.c b/src/grd-session-rdp.c
index 17a37f9..f85e3e7 100644
--- a/src/grd-session-rdp.c
+++ b/src/grd-session-rdp.c
@@ -2095,6 +2095,7 @@ grd_session_rdp_stream_ready (GrdSession *session,
pipewire_node_id = grd_stream_get_pipewire_node_id (stream);
refresh_rate = session_rdp->rdp_surface->refresh_rate;
session_rdp->pipewire_stream = grd_rdp_pipewire_stream_new (session_rdp,
+ NULL,
pipewire_node_id,
refresh_rate,
&error);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]