[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