block draws until first forced draw isdone

This commit is contained in:
Michael Scherle 2025-05-09 17:11:16 +02:00
parent 90884fcd28
commit 38d853f97f
8 changed files with 43 additions and 25 deletions

View File

@ -1755,10 +1755,9 @@ static bool red_marshall_stream_data(DisplayChannelClient *dcc,
static void red_free_cb(VideoEncoderDmabufData *dmabuf_data)
{
auto dcc = static_cast<DisplayChannelClient *>(dmabuf_data->dcc);
DisplayChannel *display = DCC_TO_DC(dcc);
dcc->priv->gl_draw_ongoing = false;
display_channel_gl_draw_done(display);
dcc_gl_draw_done(dcc);
delete dmabuf_data;
}
@ -1816,7 +1815,7 @@ static void red_marshall_gl_draw_stream(DisplayChannelClient *dcc,
}
dcc->priv->gl_draw_ongoing = false;
display_channel_gl_draw_done(display);
dcc_gl_draw_done(dcc);
delete dmabuf_data;
return;
}
@ -2384,9 +2383,8 @@ static void marshall_gl_draw(DisplayChannelClient *dcc,
} else if (DCC_TO_DC(dcc)->priv->gl_draw_stream) {
red_marshall_gl_draw_stream(dcc, m);
} else if (dcc->priv->gl_draw_ongoing){
DisplayChannel *display = DCC_TO_DC(dcc);
dcc->priv->gl_draw_ongoing = false;
display_channel_gl_draw_done(display);
dcc_gl_draw_done(dcc);
} else {
spice_warning("nothing to send to the client");
}

View File

@ -430,18 +430,18 @@ void dcc_start(DisplayChannelClient *dcc)
SpiceMsgDisplayGlScanoutUnix *scanout = red_qxl_get_gl_scanout(qxl);
if (scanout) {
display_channel_push_monitors_config(display);
dcc->set_pipes_enabled(false);
SpiceMsgDisplayGlDraw draw = {
.x = 0,
.y = 0,
.w = scanout->width,
.h = scanout->height
.h = scanout->height,
};
red_qxl_put_gl_scanout(qxl, scanout);
display_channel_gl_draw(display, &draw, true);
dcc->pipe_add(dcc_gl_draw_item_new(dcc, &draw, 0));
} else {
red_qxl_put_gl_scanout(qxl, scanout);
}
display_channel_push_monitors_config(display);
}
}
@ -457,10 +457,20 @@ static void dcc_destroy_stream_agents(DisplayChannelClient *dcc)
}
}
static void dcc_stop(DisplayChannelClient *dcc)
void dcc_gl_draw_done(DisplayChannelClient *dcc)
{
DisplayChannel *dc = DCC_TO_DC(dcc);
if (!dcc->is_pipes_enabled()) {
dcc->set_pipes_enabled(true);
return;
}
display_channel_gl_draw_done(dc);
}
static void dcc_stop(DisplayChannelClient *dcc)
{
pixmap_cache_unref(dcc->priv->pixmap_cache);
dcc->priv->pixmap_cache = nullptr;
dcc_palette_cache_reset(dcc);
@ -469,7 +479,7 @@ static void dcc_stop(DisplayChannelClient *dcc)
image_encoders_free(&dcc->priv->encoders);
if (dcc->priv->gl_draw_ongoing) {
display_channel_gl_draw_done(dc);
dcc_gl_draw_done(dcc);
}
}
@ -535,7 +545,7 @@ RedPipeItemPtr dcc_gl_draw_item_new(RedChannelClient *rcc, void *data, int num)
{
auto dcc = static_cast<DisplayChannelClient *>(rcc);
auto draw = static_cast<const SpiceMsgDisplayGlDraw *>(data);
if (!dcc->is_gl_client() &&
!rcc->test_remote_cap(SPICE_DISPLAY_CAP_MULTI_CODEC)) {
red_channel_warning(rcc->get_channel(),
@ -1005,9 +1015,8 @@ GArray *dcc_get_preferred_video_codecs_for_encoding(DisplayChannelClient *dcc)
return display_channel_get_video_codecs(DCC_TO_DC(dcc));
}
static bool dcc_handle_gl_draw_done(DisplayChannelClient *dcc)
bool dcc_handle_gl_draw_done(DisplayChannelClient *dcc)
{
DisplayChannel *display = DCC_TO_DC(dcc);
if (G_UNLIKELY(!dcc->priv->gl_draw_ongoing)) {
g_warning("unexpected DRAW_DONE received\n");
@ -1016,7 +1025,7 @@ static bool dcc_handle_gl_draw_done(DisplayChannelClient *dcc)
}
dcc->priv->gl_draw_ongoing = FALSE;
display_channel_gl_draw_done(display);
dcc_gl_draw_done(dcc);
return TRUE;
}

View File

@ -143,6 +143,7 @@ int dcc_compress_image (DisplayCha
SpiceImage *dest, SpiceBitmap *src, Drawable *drawable,
int can_lossy,
compress_send_data_t* o_comp_data);
void dcc_gl_draw_done (DisplayChannelClient *dcc);
void dcc_create_surface(DisplayChannelClient *dcc, struct RedSurface *surface);
void dcc_push_surface_image(DisplayChannelClient *dcc, struct RedSurface *surface);

View File

@ -2327,9 +2327,6 @@ 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) {
@ -2337,16 +2334,13 @@ static void set_gl_draw_async_count(DisplayChannel *display, int num)
}
}
void display_channel_gl_draw(DisplayChannel *display, SpiceMsgDisplayGlDraw *draw, bool initial)
void display_channel_gl_draw(DisplayChannel *display, SpiceMsgDisplayGlDraw *draw)
{
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);
}

View File

@ -125,8 +125,7 @@ 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,
bool initial = false);
SpiceMsgDisplayGlDraw *draw);
void display_channel_gl_draw_done (DisplayChannel *display);
void display_channel_process_draw(DisplayChannel *display,

View File

@ -165,6 +165,8 @@ struct RedChannelClientPrivate
bool wait_migrate_data;
bool wait_migrate_flush_mark;
bool pipes_enabled = true;
RedChannelClientLatencyMonitor latency_monitor;
RedChannelClientConnectivityMonitor connectivity_monitor;
@ -1550,6 +1552,16 @@ bool RedChannelClient::is_blocked() const
return priv->send_data.blocked;
}
bool RedChannelClient::is_pipes_enabled() const
{
return priv->pipes_enabled;
};
void RedChannelClient::set_pipes_enabled(bool enabled)
{
priv->pipes_enabled = enabled;
}
int RedChannelClient::send_message_pending()
{
return priv->send_data.header.get_msg_type(&priv->send_data.header) != 0;

View File

@ -45,7 +45,7 @@ public:
RedChannelCapabilities *caps,
bool monitor_latency=false);
virtual bool init();
bool is_connected() const;
bool is_waiting_for_migrate_data() const;
bool test_remote_cap(uint32_t cap) const;
@ -107,7 +107,9 @@ public:
void push_set_ack();
bool is_blocked() const;
bool is_pipes_enabled() const;
void set_pipes_enabled(bool enabled);
/* helper for channels that have complex logic that can possibly ready a send */
int send_message_pending();

View File

@ -437,6 +437,9 @@ int RedChannel::pipes_new_add(new_pipe_item_t creator, void *data)
spice_assert(creator != nullptr);
FOREACH_CLIENT(this, rcc) {
if(!rcc->is_pipes_enabled()){
continue;
}
auto item = (*creator)(rcc, data, num++);
if (item) {
rcc->pipe_add(std::move(item));