westoy: Add an option to explicitly disable cairo on a widget
authorNeil Roberts <neil@linux.intel.com>
Thu, 19 Dec 2013 16:17:12 +0000 (16:17 +0000)
committerKristian Høgsberg <krh@bitplanet.net>
Thu, 9 Jan 2014 23:03:15 +0000 (15:03 -0800)
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.

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

clients/subsurfaces.c
clients/window.c
clients/window.h

index 0f11009..45cc44b 100644 (file)
@@ -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);
 
index be89b64..cc4fe4e 100644 (file)
@@ -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 {
@@ -1609,6 +1614,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;
 }
@@ -1707,6 +1713,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);
@@ -1939,6 +1947,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)
 {
@@ -3971,7 +3986,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;
        }
index 57ff87b..8bf9adc 100644 (file)
@@ -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);