Commit afc5006e authored by Jeremy White's avatar Jeremy White Committed by Frediano Ziglio

Add a full-screen-fps option.

This option will bypass XDamage and periodic scanning and simply
transmit the whole screen to the spice server at the specified rate.

This will allow the streaming logic to kick in and hopefully for
video codecs to optimize the transmission.  This is particularly
useful for applications that often change the whole screen.
Acked-by: Frediano Ziglio's avatarFrediano Ziglio <fziglio@redhat.com>
parent 96e86d52
......@@ -408,23 +408,29 @@ int display_open(display_t *d, session_t *session)
return X11SPICE_ERR_NODAMAGE;
}
dcookie = xcb_damage_query_version(d->c, XCB_DAMAGE_MAJOR_VERSION, XCB_DAMAGE_MINOR_VERSION);
damage_version = xcb_damage_query_version_reply(d->c, dcookie, &error);
if (error) {
fprintf(stderr, "Error: Could not query damage; type %d; code %d; major %d; minor %d\n",
error->response_type, error->error_code, error->major_code, error->minor_code);
return X11SPICE_ERR_NODAMAGE;
}
free(damage_version);
d->damage = xcb_generate_id(d->c);
cookie =
xcb_damage_create_checked(d->c, d->damage, d->root, XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES);
error = xcb_request_check(d->c, cookie);
if (error) {
fprintf(stderr, "Error: Could not create damage; type %d; code %d; major %d; minor %d\n",
error->response_type, error->error_code, error->major_code, error->minor_code);
return X11SPICE_ERR_NODAMAGE;
if (session->options.full_screen_fps == 0) {
dcookie =
xcb_damage_query_version(d->c, XCB_DAMAGE_MAJOR_VERSION, XCB_DAMAGE_MINOR_VERSION);
damage_version = xcb_damage_query_version_reply(d->c, dcookie, &error);
if (error) {
fprintf(stderr,
"Error: Could not query damage; type %d; code %d; major %d; minor %d\n",
error->response_type, error->error_code, error->major_code, error->minor_code);
return X11SPICE_ERR_NODAMAGE;
}
free(damage_version);
d->damage = xcb_generate_id(d->c);
cookie =
xcb_damage_create_checked(d->c, d->damage, d->root,
XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES);
error = xcb_request_check(d->c, cookie);
if (error) {
fprintf(stderr,
"Error: Could not create damage; type %d; code %d; major %d; minor %d\n",
error->response_type, error->error_code, error->major_code, error->minor_code);
return X11SPICE_ERR_NODAMAGE;
}
}
d->shm_ext = xcb_get_extension_data(d->c, &xcb_shm_id);
......@@ -741,7 +747,9 @@ void display_close(display_t *d)
{
shm_cache_destroy(d);
g_mutex_clear(&d->shm_cache_mutex);
xcb_damage_destroy(d->c, d->damage);
if (d->session->options.full_screen_fps == 0) {
xcb_damage_destroy(d->c, d->damage);
}
display_destroy_screen_images(d);
xcb_disconnect(d->c);
}
......
......@@ -395,6 +395,8 @@ static void options_from_config(options_t *options)
options->trust_damage = NEVER_TRUST;
g_free(trust_damage);
options->full_screen_fps = int_option(userkey, systemkey, "spice", "full-screen-fps");
#if defined(HAVE_LIBAUDIT_H)
/* Pick an arbitrary default in the user range. CodeWeavers was founed in 1996, so 1196 it is... */
if (options->audit_message_type == 0)
......
......@@ -65,6 +65,7 @@ typedef struct {
int audit;
int audit_message_type;
damage_trust_t trust_damage;
int full_screen_fps;
/* file names of config files */
char *user_config_file;
......
......@@ -113,6 +113,9 @@ static QXLDrawable *shm_image_to_drawable(spice_t *s, shm_image_t *shmi, int x,
static guint64 get_timeout(scanner_t *scanner)
{
if (scanner->session->options.full_screen_fps > 0) {
return G_USEC_PER_SEC / scanner->session->options.full_screen_fps;
}
return G_USEC_PER_SEC / scanner->target_fps / NUM_SCANLINES;
}
......@@ -384,6 +387,18 @@ static gpointer g_async_queue_timeout_pop(GAsyncQueue *queue, guint64 t)
}
#endif
static void scanner_push_screen(scanner_t *scanner)
{
scan_report_t whole_screen = {
.type = SCANLINE_SCAN_REPORT,
.x = 0,.y = 0,
.w = scanner->session->display.width,
.h = scanner->session->display.height
};
handle_scan_report(scanner->session, &whole_screen);
}
static void *scanner_run(void *opaque)
{
scanner_t *scanner = (scanner_t *) opaque;
......@@ -391,8 +406,12 @@ static void *scanner_run(void *opaque)
scan_report_t *r;
r = (scan_report_t *) g_async_queue_timeout_pop(scanner->queue, get_timeout(scanner));
if (!r) {
scan_update_fps(scanner, -1);
scanner_periodic(scanner);
if (scanner->session->options.full_screen_fps > 0) {
scanner_push_screen(scanner);
} else {
scan_update_fps(scanner, -1);
scanner_periodic(scanner);
}
continue;
}
......
......@@ -100,6 +100,17 @@
#-----------------------------------------------------------------------------
#trust-damage=auto
#-----------------------------------------------------------------------------
# full-screen-fps
# There are use cases where the most effective thing we can
# do is simply transmit the whole screen periodically, and
# trust the spice server and the video codecs to optimize.
# 0 disables; otherwise the number indicates how often to
# transmit the full screen
# Default 0.
#-----------------------------------------------------------------------------
#full-screen-fps=0
#-----------------------------------------------------------------------------
# minimize Starts the x11spice gui minimized. Default false.
#-----------------------------------------------------------------------------
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment