On Thu, 19 Dec 2013 16:17:12 +0000 Neil Roberts <[email protected]> wrote:
> 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. Oh yeah, I had forgotten all about how the lazy creation worked when doing that commit. Or that it even existed. > 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. Yeah, the lazy creation would need changes in all demos and is implicit behaviour. I like explicit better, and it avoids the need to fix all demos. > --- > 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); Looks good to me! Thanks, pq _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
