[PATCH v1 2/5] dcc: Create a stream associated with gl_draw for non-gl clients

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



For non-gl/remote clients, if a stream does not exist or if any
of the key parameters associated with gl_draw such as x/y or
width/height are changed, then we create a new stream. Otherwise,
we just update the current stream's timestamp.

Cc: Gerd Hoffmann <kraxel@xxxxxxxxxx>
Cc: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx>
Cc: Dongwon Kim <dongwon.kim@xxxxxxxxx>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@xxxxxxxxx>
---
 server/dcc-private.h    |  2 ++
 server/dcc.cpp          | 14 +++++++++++++
 server/video-stream.cpp | 44 +++++++++++++++++++++++++++++++++++++++++
 server/video-stream.h   |  2 ++
 4 files changed, 62 insertions(+)

diff --git a/server/dcc-private.h b/server/dcc-private.h
index bf485aec..cd5b76a3 100644
--- a/server/dcc-private.h
+++ b/server/dcc-private.h
@@ -69,6 +69,8 @@ struct DisplayChannelClientPrivate
     uint32_t streams_max_latency;
     uint64_t streams_max_bit_rate;
     bool gl_draw_ongoing;
+
+    VideoStream *gl_draw_stream;
 };
 
 #include "pop-visibility.h"
diff --git a/server/dcc.cpp b/server/dcc.cpp
index f0b355ca..9d91ca53 100644
--- a/server/dcc.cpp
+++ b/server/dcc.cpp
@@ -525,6 +525,20 @@ RedPipeItemPtr dcc_gl_draw_item_new(RedChannelClient *rcc, void *data, int num)
     auto item = red::make_shared<RedGlDrawItem>();
     item->draw = *draw;
 
+    if (!dcc_is_gl_client(dcc)) {
+        VideoStream *stream = dcc->priv->gl_draw_stream;
+
+        if (!stream ||
+            stream->dest_area.left != draw->x ||
+            stream->dest_area.top != draw->y ||
+            stream->width != draw->w || stream->height != draw->h) {
+            stream = display_channel_create_gl_draw_stream(dcc, draw);
+        } else {
+            stream->last_time = spice_get_monotonic_time_ns();
+        }
+        dcc->priv->gl_draw_stream = stream;
+    }
+
     return item;
 }
 
diff --git a/server/video-stream.cpp b/server/video-stream.cpp
index 056d0c31..03a7d68d 100644
--- a/server/video-stream.cpp
+++ b/server/video-stream.cpp
@@ -415,6 +415,47 @@ static void display_channel_create_stream(DisplayChannel *display, Drawable *dra
                 stream->input_fps);
 }
 
+VideoStream *
+display_channel_create_gl_draw_stream(DisplayChannelClient *dcc,
+                                      const SpiceMsgDisplayGlDraw *draw)
+{
+    DisplayChannel *display = DCC_TO_DC(dcc);
+    VideoStream *stream;
+    SpiceRect dest_area = {
+        .left = draw->x,
+        .top = draw->y,
+        .right = draw->w,
+        .bottom = draw->h
+    };
+
+    if (!(stream = display_channel_stream_try_new(display))) {
+        return nullptr;
+    }
+
+    ring_add(&display->priv->streams, &stream->link);
+    stream->current = nullptr;
+    stream->last_time = spice_get_monotonic_time_ns();
+    stream->width = draw->w;
+    stream->height = draw->h;
+    stream->dest_area = dest_area;
+    stream->refs = 1;
+    stream->top_down = 1;
+    stream->input_fps = MAX_FPS;
+    stream->num_input_frames = 0;
+    stream->input_fps_start_time = spice_get_monotonic_time_ns();
+    display->priv->streams_size_total += stream->width * stream->height;
+    display->priv->stream_count++;
+
+    dcc_create_stream(dcc, stream);
+    spice_debug("stream %d %dx%d (%d, %d) (%d, %d) %u fps",
+                display_channel_get_video_stream_id(display, stream), stream->width,
+                stream->height, stream->dest_area.left, stream->dest_area.top,
+                stream->dest_area.right, stream->dest_area.bottom,
+                stream->input_fps);
+
+    return stream;
+}
+
 // returns whether a stream was created
 static bool video_stream_add_frame(DisplayChannel *display,
                              Drawable *frame_drawable,
@@ -744,6 +785,9 @@ void dcc_create_stream(DisplayChannelClient *dcc, VideoStream *stream)
     if (stream->current) {
         region_clone(&agent->vis_region, &stream->current->tree_item.base.rgn);
         region_clone(&agent->clip, &agent->vis_region);
+    } else {
+        region_add(&agent->vis_region, &stream->dest_area);
+        region_clone(&agent->clip, &agent->vis_region);
     }
     agent->dcc = dcc;
 
diff --git a/server/video-stream.h b/server/video-stream.h
index 23b44ff5..a8b2c61c 100644
--- a/server/video-stream.h
+++ b/server/video-stream.h
@@ -124,6 +124,8 @@ struct VideoStream {
 };
 
 void display_channel_init_video_streams(DisplayChannel *display);
+VideoStream *display_channel_create_gl_draw_stream(DisplayChannelClient *dcc,
+                                                   const SpiceMsgDisplayGlDraw *draw);
 void video_stream_stop(DisplayChannel *display, VideoStream *stream);
 void video_stream_trace_update(DisplayChannel *display, Drawable *drawable);
 void video_stream_maintenance(DisplayChannel *display, Drawable *candidate,
-- 
2.37.2




[Index of Archives]     [Linux Virtualization]     [Linux Virtualization]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]