[PATCH 3/4 v2] xwayland: Draw decoration on window manager side
Louis-Francis Ratté-Boulianne
louis-francis.ratte-boulianne at collabora.co.uk
Mon Aug 5 09:14:36 PDT 2013
Draw everything in a cairo image surface before copying it to the XCB
surface. That removes the flickering visible on rpi whenever the
decoration were redrawn.
---
src/xwayland/window-manager.c | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
index 15cb2ed..594c64f 100644
--- a/src/xwayland/window-manager.c
+++ b/src/xwayland/window-manager.c
@@ -97,6 +97,7 @@ struct weston_wm_window {
xcb_window_t id;
xcb_window_t frame_id;
cairo_surface_t *cairo_surface;
+ cairo_surface_t *cairo_xcb_surface;
struct weston_surface *surface;
struct shell_surface *shsurf;
struct wl_listener surface_destroy_listener;
@@ -900,12 +901,16 @@ weston_wm_handle_map_request(struct weston_wm *wm, xcb_generic_event_t *event)
xcb_map_window(wm->conn, map_request->window);
xcb_map_window(wm->conn, window->frame_id);
- window->cairo_surface =
+ window->cairo_xcb_surface =
cairo_xcb_surface_create_with_xrender_format(wm->conn,
wm->screen,
window->frame_id,
&wm->format_rgba,
width, height);
+ window->cairo_surface =
+ cairo_surface_create_similar_image(window->cairo_xcb_surface,
+ CAIRO_FORMAT_ARGB32,
+ width, height);
hash_table_insert(wm->window_hash, window->frame_id, window);
@@ -967,6 +972,8 @@ weston_wm_handle_unmap_notify(struct weston_wm *wm, xcb_generic_event_t *event)
wl_event_source_remove(window->repaint_source);
if (window->cairo_surface)
cairo_surface_destroy(window->cairo_surface);
+ if (window->cairo_xcb_surface)
+ cairo_surface_destroy(window->cairo_xcb_surface);
if (window->frame_id) {
xcb_reparent_window(wm->conn, window->id, wm->wm_window, 0, 0);
@@ -1009,7 +1016,16 @@ weston_wm_window_draw_decoration(void *data)
weston_wm_window_get_frame_size(window, &width, &height);
weston_wm_window_get_child_position(window, &x, &y);
- cairo_xcb_surface_set_size(window->cairo_surface, width, height);
+ if (cairo_image_surface_get_width(window->cairo_surface) != width ||
+ cairo_image_surface_get_height(window->cairo_surface) != height) {
+ cairo_surface_destroy(window->cairo_surface);
+ window->cairo_surface =
+ cairo_surface_create_similar_image(window->cairo_xcb_surface,
+ CAIRO_FORMAT_ARGB32,
+ width, height);
+ cairo_xcb_surface_set_size(window->cairo_xcb_surface, width, height);
+ }
+
cr = cairo_create(window->cairo_surface);
if (window->fullscreen) {
@@ -1036,6 +1052,12 @@ weston_wm_window_draw_decoration(void *data)
cairo_destroy(cr);
+ cr = cairo_create(window->cairo_xcb_surface);
+ cairo_set_source_surface(cr, window->cairo_surface, 0, 0);
+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint(cr);
+ cairo_destroy(cr);
+
if (window->surface) {
pixman_region32_fini(&window->surface->pending.opaque);
if(window->has_alpha) {
--
1.8.1.4
More information about the wayland-devel
mailing list