summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-08-22 19:20:01 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2013-08-22 19:21:13 +0100
commit92a2f8010b5b786c52d676e87209e8332fd370a0 (patch)
tree07c181cd78131d0b42f1e01026ab61b2c148342f
parentb6ee8ccffe58a9d604ac0d593b4c6147d62f2898 (diff)
overlay: Double buffer the x11 window
For pleasant remote transport. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--overlay/overlay.c2
-rw-r--r--overlay/x11/x11-window.c38
2 files changed, 35 insertions, 5 deletions
diff --git a/overlay/overlay.c b/overlay/overlay.c
index ce3b6453..c6234bf4 100644
--- a/overlay/overlay.c
+++ b/overlay/overlay.c
@@ -55,8 +55,6 @@ static void overlay_show(cairo_surface_t *surface)
{
struct overlay *overlay;
- cairo_surface_flush(surface);
-
overlay = cairo_surface_get_user_data(surface, &overlay_key);
if (overlay == NULL)
return;
diff --git a/overlay/x11/x11-window.c b/overlay/x11/x11-window.c
index 7f7d6d72..89d5c738 100644
--- a/overlay/x11/x11-window.c
+++ b/overlay/x11/x11-window.c
@@ -36,6 +36,7 @@
struct x11_window {
struct overlay base;
+ cairo_surface_t *front;
Display *dpy;
Window win;
int width, height;
@@ -55,6 +56,15 @@ static int noop(Display *dpy, XErrorEvent *event)
static void x11_window_show(struct overlay *overlay)
{
struct x11_window *priv = to_x11_window(overlay);
+ cairo_t *cr;
+
+ cr = cairo_create(priv->front);
+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface(cr, priv->base.surface, 0, 0);
+ cairo_paint(cr);
+ cairo_destroy(cr);
+
+ cairo_surface_flush(priv->front);
if (!priv->visible) {
XMapWindow(priv->dpy, priv->win);
@@ -104,11 +114,24 @@ static void x11_window_hide(struct overlay *overlay)
static void x11_window_destroy(void *data)
{
struct x11_window *priv = data;
+ cairo_surface_destroy(priv->front);
XDestroyWindow(priv->dpy, priv->win);
XCloseDisplay(priv->dpy);
free(priv);
}
+static int prefer_image(struct config *config)
+{
+ const char *v = config_get_value(config, "x11", "prefer-image");
+
+ if (v == NULL)
+ return 0;
+ if (*v == '\0')
+ return 1;
+
+ return atoi(v);
+}
+
cairo_surface_t *
x11_window_create(struct config *config, int *width, int *height)
{
@@ -148,24 +171,33 @@ x11_window_create(struct config *config, int *width, int *height)
if (priv == NULL)
goto err_surface;
- priv->base.surface = surface;
+ if (prefer_image(config))
+ priv->base.surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, w, h);
+ else
+ priv->base.surface = cairo_surface_create_similar(surface, CAIRO_CONTENT_COLOR, w, h);
+ if (cairo_surface_status(priv->base.surface))
+ goto err_priv;
+
priv->base.show = x11_window_show;
priv->base.position = x11_window_position;
priv->base.hide = x11_window_hide;
priv->dpy = dpy;
priv->win = win;
+ priv->front = surface;
priv->visible = false;
priv->width = w;
priv->height = h;
- cairo_surface_set_user_data(surface, &overlay_key, priv, x11_window_destroy);
+ cairo_surface_set_user_data(priv->base.surface, &overlay_key, priv, x11_window_destroy);
*width = w;
*height = h;
- return surface;
+ return priv->base.surface;
+err_priv:
+ free(priv);
err_surface:
cairo_surface_destroy(surface);
err_win: