[PATCH] compositor: update the surface size when there is a size change without a buffer attach

Jason Ekstrand jason at jlekstrand.net
Wed Jun 18 12:38:50 PDT 2014


On Fri, Jun 13, 2014 at 9:14 AM, George Kiagiadakis <
george.kiagiadakis at collabora.com> wrote:

> This fixes at least the case where you want to do
> wl_viewport.set_destination
> to resize the surface but without attaching new content in it.
> ---
>  src/compositor.c | 60
> +++++++++++++++++++++++++++++++++++++++++++-------------
>  src/compositor.h |  2 ++
>  2 files changed, 48 insertions(+), 14 deletions(-)
>
> diff --git a/src/compositor.c b/src/compositor.c
> index 2fbfdbf..973c7e4 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -404,6 +404,7 @@ weston_surface_create(struct weston_compositor
> *compositor)
>         surface->buffer_viewport.buffer.scale = 1;
>         surface->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
>         surface->buffer_viewport.surface.width = -1;
> +       surface->pending.buffer_viewport.changed = 0;
>         surface->pending.buffer_viewport = surface->buffer_viewport;
>         surface->output = NULL;
>         surface->pending.newly_attached = 0;
> @@ -1211,13 +1212,12 @@ fixed_round_up_to_int(wl_fixed_t f)
>  }
>
>  static void
> -weston_surface_set_size_from_buffer(struct weston_surface *surface)
> +weston_surface_calculate_size_from_buffer(struct weston_surface *surface)
>  {
>         struct weston_buffer_viewport *vp = &surface->buffer_viewport;
>         int32_t width, height;
>
>         if (!surface->buffer_ref.buffer) {
> -               surface_set_size(surface, 0, 0);
>                 surface->width_from_buffer = 0;
>                 surface->height_from_buffer = 0;
>                 return;
> @@ -1239,14 +1239,24 @@ weston_surface_set_size_from_buffer(struct
> weston_surface *surface)
>
>         surface->width_from_buffer = width;
>         surface->height_from_buffer = height;
> +}
> +
> +static void
> +weston_surface_update_size(struct weston_surface *surface)
> +{
> +       struct weston_buffer_viewport *vp = &surface->buffer_viewport;
> +       int32_t width, height;
> +
> +       width = surface->width_from_buffer;
> +       height = surface->height_from_buffer;
>
> -       if (vp->surface.width != -1) {
> +       if (width != 0 && vp->surface.width != -1) {
>                 surface_set_size(surface,
>                                  vp->surface.width, vp->surface.height);
>                 return;
>         }
>
> -       if (vp->buffer.src_width != wl_fixed_from_int(-1)) {
> +       if (width != 0 && vp->buffer.src_width != wl_fixed_from_int(-1)) {
>                 int32_t w = fixed_round_up_to_int(vp->buffer.src_width);
>                 int32_t h = fixed_round_up_to_int(vp->buffer.src_height);
>
> @@ -1351,6 +1361,7 @@ weston_surface_reset_pending_buffer(struct
> weston_surface *surface)
>         surface->pending.sx = 0;
>         surface->pending.sy = 0;
>         surface->pending.newly_attached = 0;
> +       surface->pending.buffer_viewport.changed = 0;
>  }
>
>  struct weston_frame_callback {
> @@ -1520,7 +1531,7 @@ weston_surface_attach(struct weston_surface *surface,
>
>         surface->compositor->renderer->attach(surface, buffer);
>
> -       weston_surface_set_size_from_buffer(surface);
> +       weston_surface_calculate_size_from_buffer(surface);
>  }
>

I think we have an issue here.  If a client attaches a new buffer but does
not commit for a while, the width/height_from_buffer and width/height will
be out of sync.  That said, I think having surface_set_size_from_buffer
here was wrong in the first place.  The new surface size should only take
over after the commit.  Other than that, the patch looks fine to me.
--Jason Ekstrand


>
>  WL_EXPORT void
> @@ -2049,8 +2060,6 @@ weston_surface_commit(struct weston_surface *surface)
>         struct weston_view *view;
>         pixman_region32_t opaque;
>
> -       /* XXX: wl_viewport.set without an attach should call configure */
> -
>         /* wl_surface.set_buffer_transform */
>         /* wl_surface.set_buffer_scale */
>         /* wl_viewport.set */
> @@ -2060,9 +2069,13 @@ weston_surface_commit(struct weston_surface
> *surface)
>         if (surface->pending.newly_attached)
>                 weston_surface_attach(surface, surface->pending.buffer);
>
> -       if (surface->configure && surface->pending.newly_attached)
> -               surface->configure(surface,
> -                                  surface->pending.sx, surface->
> pending.sy);
> +       if (surface->pending.newly_attached ||
> +           surface->pending.buffer_viewport.changed) {
> +               weston_surface_update_size(surface);
> +               if (surface->configure)
> +                       surface->configure(surface, surface->pending.sx,
> +                                          surface->pending.sy);
> +       }
>
>         weston_surface_reset_pending_buffer(surface);
>
> @@ -2151,6 +2164,7 @@ surface_set_buffer_transform(struct wl_client
> *client,
>         }
>
>         surface->pending.buffer_viewport.buffer.transform = transform;
> +       surface->pending.buffer_viewport.changed = 1;
>  }
>
>  static void
> @@ -2169,6 +2183,7 @@ surface_set_buffer_scale(struct wl_client *client,
>         }
>
>         surface->pending.buffer_viewport.buffer.scale = scale;
> +       surface->pending.buffer_viewport.changed = 1;
>  }
>
>  static const struct wl_surface_interface surface_interface = {
> @@ -2300,11 +2315,17 @@ weston_subsurface_commit_from_cache(struct
> weston_subsurface *sub)
>                 weston_surface_attach(surface,
> sub->cached.buffer_ref.buffer);
>         weston_buffer_reference(&sub->cached.buffer_ref, NULL);
>
> -       if (surface->configure && sub->cached.newly_attached)
> -               surface->configure(surface, sub->cached.sx, sub->cached.sy
> );
> +       if (sub->cached.newly_attached ||
> sub->cached.buffer_viewport.changed) {
> +               weston_surface_update_size(surface);
> +               if (surface->configure)
> +                       surface->configure(surface, sub->cached.sx,
> +                                          sub->cached.sy);
> +       }
> +
>         sub->cached.sx = 0;
>         sub->cached.sy = 0;
>         sub->cached.newly_attached = 0;
> +       sub->cached.buffer_viewport.changed = 0;
>
>         /* wl_surface.damage */
>         pixman_region32_union(&surface->damage, &surface->damage,
> @@ -2375,9 +2396,14 @@ weston_subsurface_commit_to_cache(struct
> weston_subsurface *sub)
>         sub->cached.sx += surface->pending.sx;
>         sub->cached.sy += surface->pending.sy;
>
> -       weston_surface_reset_pending_buffer(surface);
> +       sub->cached.buffer_viewport.changed |=
> +               surface->pending.buffer_viewport.changed;
> +       sub->cached.buffer_viewport.buffer =
> +               surface->pending.buffer_viewport.buffer;
> +       sub->cached.buffer_viewport.surface =
> +               surface->pending.buffer_viewport.surface;
>
> -       sub->cached.buffer_viewport = surface->pending.buffer_viewport;
> +       weston_surface_reset_pending_buffer(surface);
>
>         pixman_region32_copy(&sub->cached.opaque,
> &surface->pending.opaque);
>
> @@ -3425,6 +3451,7 @@ destroy_viewport(struct wl_resource *resource)
>         surface->pending.buffer_viewport.buffer.src_width =
>                 wl_fixed_from_int(-1);
>         surface->pending.buffer_viewport.surface.width = -1;
> +       surface->pending.buffer_viewport.changed = 1;
>  }
>
>  static void
> @@ -3473,6 +3500,7 @@ viewport_set(struct wl_client *client,
>         surface->pending.buffer_viewport.buffer.src_height = src_height;
>         surface->pending.buffer_viewport.surface.width = dst_width;
>         surface->pending.buffer_viewport.surface.height = dst_height;
> +       surface->pending.buffer_viewport.changed = 1;
>  }
>
>  static void
> @@ -3493,6 +3521,7 @@ viewport_set_source(struct wl_client *client,
>                 /* unset source size */
>                 surface->pending.buffer_viewport.buffer.src_width =
>                         wl_fixed_from_int(-1);
> +               surface->pending.buffer_viewport.changed = 1;
>                 return;
>         }
>
> @@ -3509,6 +3538,7 @@ viewport_set_source(struct wl_client *client,
>         surface->pending.buffer_viewport.buffer.src_y = src_y;
>         surface->pending.buffer_viewport.buffer.src_width = src_width;
>         surface->pending.buffer_viewport.buffer.src_height = src_height;
> +       surface->pending.buffer_viewport.changed = 1;
>  }
>
>  static void
> @@ -3525,6 +3555,7 @@ viewport_set_destination(struct wl_client *client,
>         if (dst_width == -1 && dst_height == -1) {
>                 /* unset destination size */
>                 surface->pending.buffer_viewport.surface.width = -1;
> +               surface->pending.buffer_viewport.changed = 1;
>                 return;
>         }
>
> @@ -3538,6 +3569,7 @@ viewport_set_destination(struct wl_client *client,
>
>         surface->pending.buffer_viewport.surface.width = dst_width;
>         surface->pending.buffer_viewport.surface.height = dst_height;
> +       surface->pending.buffer_viewport.changed = 1;
>  }
>
>  static const struct wl_viewport_interface viewport_interface = {
> diff --git a/src/compositor.h b/src/compositor.h
> index 057f8be..eae1b20 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -686,6 +686,8 @@ struct weston_buffer_viewport {
>                  */
>                 int32_t width, height;
>         } surface;
> +
> +       int changed;
>  };
>
>  struct weston_region {
> --
> 2.0.0
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20140618/6d77f333/attachment.html>


More information about the wayland-devel mailing list