summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy White <jwhite@codeweavers.com>2019-08-22 13:24:47 -0500
committerFrediano Ziglio <freddy77@gmail.com>2020-05-06 13:35:00 +0100
commitafc5006ead4c475947bf8401efd079e1bff4640f (patch)
treea53eff76398a4672dd0be71e34295fb0711d4ab2
parent96e86d52bfabc80039b95ef574829a3df7315353 (diff)
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 <fziglio@redhat.com>
-rw-r--r--src/display.c44
-rw-r--r--src/options.c2
-rw-r--r--src/options.h1
-rw-r--r--src/scan.c23
-rw-r--r--src/xdg/x11spice/x11spice.conf11
5 files changed, 61 insertions, 20 deletions
diff --git a/src/display.c b/src/display.c
index f78c54b..931a314 100644
--- a/src/display.c
+++ b/src/display.c
@@ -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);
}
diff --git a/src/options.c b/src/options.c
index ef817bb..90442f8 100644
--- a/src/options.c
+++ b/src/options.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)
diff --git a/src/options.h b/src/options.h
index 19e22e4..343da2c 100644
--- a/src/options.h
+++ b/src/options.h
@@ -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;
diff --git a/src/scan.c b/src/scan.c
index 7b6d8f5..69a8b04 100644
--- a/src/scan.c
+++ b/src/scan.c
@@ -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;
}
diff --git a/src/xdg/x11spice/x11spice.conf b/src/xdg/x11spice/x11spice.conf
index 6b1ee8d..8bb2996 100644
--- a/src/xdg/x11spice/x11spice.conf
+++ b/src/xdg/x11spice/x11spice.conf
@@ -101,6 +101,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.
#-----------------------------------------------------------------------------
#minimize=false