If a remote connection is detected extract raw data from texture and pass to normal flow creating a dummy RedDrawable. Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx> --- server/display-channel.c | 52 +++++++++++++++++++++++++++++++++++++++++++++--- server/display-channel.h | 4 ++-- server/red-worker.c | 2 +- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/server/display-channel.c b/server/display-channel.c index 2154878..967070c 100644 --- a/server/display-channel.c +++ b/server/display-channel.c @@ -19,12 +19,14 @@ #endif #include "display-channel.h" +#include "egl.h" static void drawable_draw(DisplayChannel *display, Drawable *drawable); static Drawable *display_channel_drawable_try_new(DisplayChannel *display, int process_commands_generation); static RedDrawable *get_dummy_drawable(DisplayChannel *display, int w, int h, int y_0_top, uint8_t *data, uint32_t data_size); +static RedDrawable *get_dummy_gl_drawable(DisplayChannel *display); uint32_t display_channel_generate_uid(DisplayChannel *display) { @@ -2004,8 +2006,31 @@ void display_channel_update_compression(DisplayChannel *display, DisplayChannelC spice_info("zlib-over-glz %s", display->enable_zlib_glz_wrap ? "enabled" : "disabled"); } +static gboolean display_channel_gl_handle_remote(DisplayChannel *display, uint32_t process_commands_generation) +{ + RedChannelClient *rcc; + GList *link, *next; + + // check if all channel are remote + FOREACH_CLIENT(display, link, next, rcc) { + if (!reds_stream_is_plain_unix(rcc->stream) || + !red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_GL_SCANOUT)) { + RedDrawable *red_drawable = get_dummy_gl_drawable(display); + if (red_drawable) { + // FIXME no flow control, check pipe size! + display_channel_process_draw(display, red_drawable, process_commands_generation); + red_drawable_unref(red_drawable); + } + return TRUE; + } + } + return FALSE; +} + + void display_channel_gl_scanout(DisplayChannel *display) { + // don't call display_channel_gl_handle_remote, draw commands always follows red_channel_pipes_new_add_push(RED_CHANNEL(display), dcc_gl_scanout_item_new, NULL); } @@ -2020,13 +2045,15 @@ 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, uint32_t process_commands_generation) { - int num; + int num = 0; spice_return_if_fail(display->gl_draw_async_count == 0); - num = red_channel_pipes_new_add_push(RED_CHANNEL(display), dcc_gl_draw_item_new, draw); + if (!display_channel_gl_handle_remote(display, process_commands_generation)) { + num = red_channel_pipes_new_add_push(RED_CHANNEL(display), dcc_gl_draw_item_new, draw); + } set_gl_draw_async_count(display, num); } @@ -2074,3 +2101,22 @@ static RedDrawable *get_dummy_drawable(DisplayChannel *display, int w, int h, in return red; } + +static RedDrawable *get_dummy_gl_drawable(DisplayChannel *display) +{ + RedDrawable *red_drawable = NULL; + QXLInstance* qxl = display->common.qxl; + + RedGlTexture *texture = red_qxl_get_gl_texture(qxl); + if (texture != NULL) { + size_t size; + void *data = get_texture_raw_data(texture, &size); + spice_assert(data); + if (data) { + red_drawable = get_dummy_drawable(display, texture->width, texture->height, texture->flags, data, size); + spice_assert(red_drawable); + } + } + red_qxl_put_gl_texture(qxl, texture); + return red_drawable; +} diff --git a/server/display-channel.h b/server/display-channel.h index f090d99..7f42dcd 100644 --- a/server/display-channel.h +++ b/server/display-channel.h @@ -280,8 +280,8 @@ void display_channel_process_surface_cmd (DisplayCha void display_channel_update_compression (DisplayChannel *display, DisplayChannelClient *dcc); void display_channel_gl_scanout (DisplayChannel *display); -void display_channel_gl_draw (DisplayChannel *display, - SpiceMsgDisplayGlDraw *draw); +void display_channel_gl_draw(DisplayChannel *display, SpiceMsgDisplayGlDraw *draw, + uint32_t process_commands_generation); void display_channel_gl_draw_done (DisplayChannel *display); static inline int validate_surface(DisplayChannel *display, uint32_t surface_id) diff --git a/server/red-worker.c b/server/red-worker.c index 9eac0ad..c254b57 100644 --- a/server/red-worker.c +++ b/server/red-worker.c @@ -1133,7 +1133,7 @@ void handle_dev_gl_draw_async(void *opaque, void *payload) RedWorker *worker = opaque; SpiceMsgDisplayGlDraw *draw = payload; - display_channel_gl_draw(worker->display_channel, draw); + display_channel_gl_draw(worker->display_channel, draw, worker->process_display_generation); } static int loadvm_command(RedWorker *worker, QXLCommandExt *ext) -- 2.7.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel