[PATCH weston] westoy: Add an option to explicitly disable cairo on a widget
Pekka Paalanen
ppaalanen at gmail.com
Thu Dec 19 08:46:05 PST 2013
On Thu, 19 Dec 2013 16:17:12 +0000
Neil Roberts <neil at linux.intel.com> 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
More information about the wayland-devel
mailing list