From 97b747cdda1ec32df3317a1df44d3c4a217f06d9 Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Thu, 19 Dec 2013 16:17:12 +0000 Subject: [PATCH] westoy: Add an option to explicitly disable cairo on a widget MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 | 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 0f11009e..45cc44b4 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 be89b641..cc4fe4ee 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 { @@ -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; } diff --git a/clients/window.h b/clients/window.h index 57ff87bf..8bf9adc1 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);