From 90884fcd28cac6a20070162a5e8e1e189204b27e Mon Sep 17 00:00:00 2001 From: Michael Scherle Date: Wed, 30 Apr 2025 09:36:20 +0200 Subject: [PATCH] push a new frame on display channel connect (experimental) --- server/dcc-send.cpp | 2 +- server/dcc.cpp | 21 +++++++++++++++++++++ server/display-channel.cpp | 10 ++++++++-- server/display-channel.h | 3 ++- server/gstreamer-encoder.c | 2 +- 5 files changed, 33 insertions(+), 5 deletions(-) diff --git a/server/dcc-send.cpp b/server/dcc-send.cpp index 05a3c1e3..5930af7b 100644 --- a/server/dcc-send.cpp +++ b/server/dcc-send.cpp @@ -1789,7 +1789,7 @@ static void red_marshall_gl_draw_stream(DisplayChannelClient *dcc, return; } - dmabuf_data->drm_dma_buf_fd = scanout->drm_dma_buf_fd; + dmabuf_data->drm_dma_buf_fd = dup(scanout->drm_dma_buf_fd); dmabuf_data->drm_fourcc_format = scanout->drm_fourcc_format; dmabuf_data->width = stream->width; dmabuf_data->height = stream->height; diff --git a/server/dcc.cpp b/server/dcc.cpp index 8fdc8299..cde3d96f 100644 --- a/server/dcc.cpp +++ b/server/dcc.cpp @@ -24,6 +24,7 @@ #include "red-client.h" #include "main-channel-client.h" #include +#include "red-qxl.h" #define DISPLAY_CLIENT_SHORT_TIMEOUT 15000000000ULL //nano #define DISPLAY_FREE_LIST_DEFAULT_SIZE 128 @@ -422,6 +423,26 @@ void dcc_start(DisplayChannelClient *dcc) dcc->pipe_add(dcc_gl_scanout_item_new(dcc, nullptr, 0)); dcc_push_monitors_config(dcc); } + + //TODO : only if dmabuf encode + { + QXLInstance* qxl = display->priv->qxl; + SpiceMsgDisplayGlScanoutUnix *scanout = red_qxl_get_gl_scanout(qxl); + if (scanout) { + display_channel_push_monitors_config(display); + SpiceMsgDisplayGlDraw draw = { + .x = 0, + .y = 0, + .w = scanout->width, + .h = scanout->height + }; + red_qxl_put_gl_scanout(qxl, scanout); + display_channel_gl_draw(display, &draw, true); + } else { + red_qxl_put_gl_scanout(qxl, scanout); + } + display_channel_push_monitors_config(display); + } } static void dcc_destroy_stream_agents(DisplayChannelClient *dcc) diff --git a/server/display-channel.cpp b/server/display-channel.cpp index a36e9cc3..9a46889c 100644 --- a/server/display-channel.cpp +++ b/server/display-channel.cpp @@ -2327,6 +2327,9 @@ void display_channel_gl_scanout(DisplayChannel *display) static void set_gl_draw_async_count(DisplayChannel *display, int num) { + if(num < 0) { + return; + } display->priv->gl_draw_async_count = num; if (num == 0) { @@ -2334,13 +2337,16 @@ static void set_gl_draw_async_count(DisplayChannel *display, int num) } } -void display_channel_gl_draw(DisplayChannel *display, SpiceMsgDisplayGlDraw *draw) +void display_channel_gl_draw(DisplayChannel *display, SpiceMsgDisplayGlDraw *draw, bool initial) { int num; spice_return_if_fail(display->priv->gl_draw_async_count == 0); num = display->pipes_new_add(dcc_gl_draw_item_new, draw); + if(initial) { + return; + } set_gl_draw_async_count(display, num); } @@ -2486,7 +2492,7 @@ void DisplayChannel::on_connect(RedClient *client, RedChannelCapabilities *caps) { DisplayChannelClient *dcc; - + spice_debug("connect new client"); SpiceServer *reds = get_server(); diff --git a/server/display-channel.h b/server/display-channel.h index c54df25c..bc8a5f95 100644 --- a/server/display-channel.h +++ b/server/display-channel.h @@ -125,7 +125,8 @@ void display_channel_destroy_surface_wait (DisplayCha void display_channel_destroy_surfaces (DisplayChannel *display); void display_channel_gl_scanout (DisplayChannel *display); void display_channel_gl_draw (DisplayChannel *display, - SpiceMsgDisplayGlDraw *draw); + SpiceMsgDisplayGlDraw *draw, + bool initial = false); void display_channel_gl_draw_done (DisplayChannel *display); void display_channel_process_draw(DisplayChannel *display, diff --git a/server/gstreamer-encoder.c b/server/gstreamer-encoder.c index c97243b7..dd21ede5 100644 --- a/server/gstreamer-encoder.c +++ b/server/gstreamer-encoder.c @@ -1860,7 +1860,7 @@ spice_gst_encoder_encode_dmabuf(VideoEncoder *video_encoder, mem = gst_dmabuf_allocator_alloc_with_flags(encoder->allocator, dmabuf_data->drm_dma_buf_fd, size, - GST_FD_MEMORY_FLAG_DONT_CLOSE); + GST_FD_MEMORY_FLAG_NONE); if (!mem) { return rc; }