westoy: Add an option to explicitly disable cairo on a widget

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
dev
Neil Roberts 11 years ago committed by Kristian Høgsberg
parent a30e29af2e
commit 97b747cdda
  1. 1
      clients/subsurfaces.c
  2. 18
      clients/window.c
  3. 2
      clients/window.h

@ -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);

@ -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;
}

@ -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);

Loading…
Cancel
Save