From 92a2f8010b5b786c52d676e87209e8332fd370a0 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 22 Aug 2013 19:20:01 +0100 Subject: overlay: Double buffer the x11 window For pleasant remote transport. Signed-off-by: Chris Wilson --- overlay/overlay.c | 2 -- overlay/x11/x11-window.c | 38 +++++++++++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 5 deletions(-) (limited to 'overlay') 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: -- cgit v1.2.3