[PATCH weston] westoy: Add an option to explicitly disable cairo on a widget

Neil Roberts neil at linux.intel.com
Thu Dec 19 08:17:12 PST 2013


This problem was found while looking at the following bug:

https://bugs.freedesktop.org/show_bug.cgi?id=72612

It turns out the patch doesn't help to fix the bug but I think it
would be a good thing to do anyway.

------- >8 --------------- (use git am --scissors to automatically chop here)

The subsurfaces example creates a subsurface widget and uses EGL to
render to it directly rather than using the cairo context from the
widget. In theory this shouldn't cause any problems because the westoy
window code lazily creates the cairo surface when an application
creates a cairo context. However commit fdca95c7 changed the behaviour
to force the lazy creation at the beginning of each surface redraw.
This ends up making the triangle surface get two attaches – one from
Cairo and one from the direct EGL.

It looks like it would be difficult to reinstate the lazy surface
creation behaviour whilst still maintaining the error handling for
surface creation because none of the redraw handlers in the example
clients are designed to cope with that. Instead, this patch adds an
explicit option on a widget to disable creating the Cairo surface and
the subsurface example now uses that.
---
 clients/subsurfaces.c |  1 +
 clients/window.c      | 18 +++++++++++++++++-
 clients/window.h      |  2 ++
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/clients/subsurfaces.c b/clients/subsurfaces.c
index 0f11009..45cc44b 100644
--- a/clients/subsurfaces.c
+++ b/clients/subsurfaces.c
@@ -498,6 +498,7 @@ triangle_create(struct window *window, struct egl_state *egl)
 	tri->egl = egl;
 	tri->widget = window_add_subsurface(window, tri,
 		int_to_mode(option_triangle_mode));
+	widget_set_use_cairo(tri->widget, 0);
 	widget_set_resize_handler(tri->widget, triangle_resize_handler);
 	widget_set_redraw_handler(tri->widget, triangle_redraw_handler);
 
diff --git a/clients/window.c b/clients/window.c
index 43761ca..5a8df43 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -285,6 +285,11 @@ struct widget {
 	int opaque;
 	int tooltip_count;
 	int default_cursor;
+	/* If this is set to false then no cairo surface will be
+	 * created before redrawing the surface. This is useful if the
+	 * redraw handler is going to do completely custom rendering
+	 * such as using EGL directly */
+	int use_cairo;
 };
 
 struct touch_point {
@@ -1608,6 +1613,7 @@ widget_create(struct window *window, struct surface *surface, void *data)
 	widget->tooltip = NULL;
 	widget->tooltip_count = 0;
 	widget->default_cursor = CURSOR_LEFT_PTR;
+	widget->use_cairo = 1;
 
 	return widget;
 }
@@ -1706,6 +1712,8 @@ widget_get_cairo_surface(struct widget *widget)
 	struct surface *surface = widget->surface;
 	struct window *window = widget->window;
 
+	assert(widget->use_cairo);
+
 	if (!surface->cairo_surface) {
 		if (surface == window->main_surface)
 			window_create_main_surface(window);
@@ -1938,6 +1946,13 @@ widget_schedule_redraw(struct widget *widget)
 	window_schedule_redraw_task(widget->window);
 }
 
+void
+widget_set_use_cairo(struct widget *widget,
+		     int use_cairo)
+{
+	widget->use_cairo = use_cairo;
+}
+
 cairo_surface_t *
 window_get_surface(struct window *window)
 {
@@ -3942,7 +3957,8 @@ surface_redraw(struct surface *surface)
 		wl_callback_destroy(surface->frame_cb);
 	}
 
-	if (!widget_get_cairo_surface(surface->widget)) {
+	if (surface->widget->use_cairo &&
+	    !widget_get_cairo_surface(surface->widget)) {
 		DBG_OBJ(surface->surface, "cancelled due buffer failure\n");
 		return -1;
 	}
diff --git a/clients/window.h b/clients/window.h
index cf8fc6c..1e12374 100644
--- a/clients/window.h
+++ b/clients/window.h
@@ -507,6 +507,8 @@ widget_set_axis_handler(struct widget *widget,
 			widget_axis_handler_t handler);
 void
 widget_schedule_redraw(struct widget *widget);
+void
+widget_set_use_cairo(struct widget *widget, int use_cairo);
 
 struct widget *
 window_frame_create(struct window *window, void *data);
-- 
1.8.3.1



More information about the wayland-devel mailing list