[PATCH 5/5] xwayland: Pixmap flips of child windows on sub-surfaces

Roman Gilg subdiff at gmail.com
Tue Aug 29 15:55:27 UTC 2017


There is a mistake in the patch description since the mentioned small
change to the Present extension code wasn't necessary in the end. So I
reverted the change, but forgot about the description.

On Tue, Aug 29, 2017 at 5:24 PM, Roman Gilg <subdiff at gmail.com> wrote:

> This patch enables Pixmap flips for child windows via Wayland
> sub-surfaces.
>
> If the Wayland compositor doesn't support sub-surfaces we fall back
> to flips without sub-surfaces when possible as before.
>
> A small change to Present is necessary, to restore the window pixmap
> correctly after an unflip operation.
>
> Signed-off-by: Roman Gilg <subdiff at gmail.com>
> ---
>  hw/xwayland/xwayland-present.c | 44 ++++++++++++++++++++++++++++++
> ++++++------
>  hw/xwayland/xwayland.c         |  6 +++++-
>  hw/xwayland/xwayland.h         |  2 ++
>  present/present_winmode.c      |  4 +---
>  4 files changed, 46 insertions(+), 10 deletions(-)
>
> diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-
> present.c
> index c10128c..8fa6831 100644
> --- a/hw/xwayland/xwayland-present.c
> +++ b/hw/xwayland/xwayland-present.c
> @@ -53,17 +53,25 @@ xwl_present_cleanup(WindowPtr window)
>       * And therefore need to cleanup.
>       */
>
> +    /* Clear frame callback */
>      if (xwl_window->present_frame_callback) {
>          wl_callback_destroy(xwl_window->present_frame_callback);
>          xwl_window->present_frame_callback = NULL;
>      }
>
> +    /* Clear surfaces */
> +    if (xwl_window->present_subsurface) {
> +        wl_subsurface_destroy(xwl_window->present_subsurface);
> +        wl_surface_destroy(xwl_window->present_surface);
> +        xwl_window->present_subsurface = NULL;
> +    }
> +    xwl_window->present_surface = NULL;
> +
>      /* Reset base data */
>      xorg_list_del(&xwl_window->present_link);
> -    xwl_window->present_surface = NULL;
>      xwl_window->present_window = NULL;
>
> -    /* Clear remaining events */
> +    /* Clear remaining queued events */
>      xorg_list_for_each_entry_safe(event, tmp, &xwl_window->present_event_list,
> list) {
>          xorg_list_del(&event->list);
>          free(event);
> @@ -231,7 +239,9 @@ xwl_present_check_flip(RRCrtcPtr crtc,
>       */
>      if (xwl_window->present_crtc_fake != crtc)
>          return FALSE;
> -    if (!RegionEqual(&xwl_window->window->winSize,
> &present_window->winSize))
> +
> +    if (!RegionEqual(&xwl_window->window->winSize,
> &present_window->winSize) &&
> +            !xwl_window->xwl_screen->subcompositor)
>          return FALSE;
>
>      return TRUE;
> @@ -246,11 +256,15 @@ xwl_present_flip(WindowPtr present_window,
>                   Bool sync_flip)
>  {
>      struct xwl_window           *xwl_window = xwl_window_from_window(
> present_window);
> -    BoxPtr                      present_box;
> +    WindowPtr                   window = xwl_window->window;
> +    struct xwl_screen           *xwl_screen = xwl_window->xwl_screen;
> +    BoxPtr                      win_box, present_box;
>      Bool                        buffer_created;
>      struct wl_buffer            *buffer;
>      struct xwl_present_event    *event;
> +    struct wl_region            *input_region;
>
> +    win_box = RegionExtents(&window->winSize);
>      present_box = RegionExtents(&present_window->winSize);
>
>      /* We always switch to another child window, if it wants to present.
> */
> @@ -260,8 +274,21 @@ xwl_present_flip(WindowPtr present_window,
>          xwl_window->present_window = present_window;
>          xorg_list_add(&xwl_window->present_link, &xwl_present_windows);
>
> -        /* We can flip directly to the main surface (full screen window
> without clips) */
> -        xwl_window->present_surface = xwl_window->surface;
> +        if (RegionEqual(&window->winSize, &present_window->winSize)) {
> +            /* We can flip directly to the main surface (full screen
> window without clips) */
> +            xwl_window->present_surface = xwl_window->surface;
> +        } else {
> +            xwl_window->present_surface =  wl_compositor_create_surface(
> xwl_window->xwl_screen->compositor);
> +            wl_surface_set_user_data(xwl_window->present_surface,
> xwl_window);
> +
> +            xwl_window->present_subsurface =
> +                    wl_subcompositor_get_subsurface(xwl_screen->subcompositor,
> xwl_window->present_surface, xwl_window->surface);
> +            wl_subsurface_set_desync(xwl_window->present_subsurface);
> +
> +            input_region = wl_compositor_create_region(
> xwl_screen->compositor);
> +            wl_surface_set_input_region(xwl_window->present_surface,
> input_region);
> +            wl_region_destroy(input_region);
> +        }
>      }
>
>      event = malloc(sizeof *event);
> @@ -270,6 +297,11 @@ xwl_present_flip(WindowPtr present_window,
>          return FALSE;
>      }
>
> +    if (xwl_window->present_subsurface)
> +        wl_subsurface_set_position(xwl_window->present_subsurface,
> +                                   present_box->x1 - win_box->x1,
> +                                   present_box->y1 - win_box->y1);
> +
>      buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap,
>                                               present_box->x2 -
> present_box->x1,
>                                               present_box->y2 -
> present_box->y1,
> diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
> index 2182c71..18e5b8b 100644
> --- a/hw/xwayland/xwayland.c
> +++ b/hw/xwayland/xwayland.c
> @@ -659,7 +659,7 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen)
>      xorg_list_for_each_entry_safe(xwl_window, next_xwl_window,
>                                    &xwl_screen->damage_window_list,
> link_damage) {
>          /* Present on the main surface. So don't commit here as well. */
> -        if (xwl_window->present_surface)
> +        if (xwl_window->present_surface && !xwl_window->present_
> subsurface)
>              continue;
>          /* If we're waiting on a frame callback from the server,
>           * don't attach a new buffer. */
> @@ -683,6 +683,10 @@ registry_global(void *data, struct wl_registry
> *registry, uint32_t id,
>          xwl_screen->compositor =
>              wl_registry_bind(registry, id, &wl_compositor_interface, 1);
>      }
> +    else if (strcmp(interface, "wl_subcompositor") == 0) {
> +        xwl_screen->subcompositor =
> +            wl_registry_bind(registry, id, &wl_subcompositor_interface,
> 1);
> +    }
>      else if (strcmp(interface, "wl_shm") == 0) {
>          xwl_screen->shm = wl_registry_bind(registry, id,
> &wl_shm_interface, 1);
>      }
> diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
> index 0969043..166ba9b 100644
> --- a/hw/xwayland/xwayland.h
> +++ b/hw/xwayland/xwayland.h
> @@ -77,6 +77,7 @@ struct xwl_screen {
>      struct wl_registry *registry;
>      struct wl_registry *input_registry;
>      struct wl_compositor *compositor;
> +    struct wl_subcompositor *subcompositor;
>      struct zwp_tablet_manager_v2 *tablet_manager;
>      struct wl_shm *shm;
>      struct wl_shell *shell;
> @@ -120,6 +121,7 @@ struct xwl_window {
>      struct xorg_list present_link;
>      WindowPtr present_window;
>      struct wl_surface *present_surface;
> +    struct wl_subsurface *present_subsurface;
>      uint64_t present_msc;
>      struct wl_callback *present_frame_callback;
>      struct xorg_list present_event_list;
> diff --git a/present/present_winmode.c b/present/present_winmode.c
> index 3027db7..8e98634 100644
> --- a/present/present_winmode.c
> +++ b/present/present_winmode.c
> @@ -123,7 +123,6 @@ present_winmode_restore_window_pixmap(WindowPtr
> window)
>
>      flip_pixmap = window_priv->flip_pending ? window_priv->flip_pending->pixmap
> :
>                                                window_priv->flip_active->
> pixmap;
> -
>      assert (flip_pixmap);
>
>      restore_pixmap = screen->GetWindowPixmap(window->parent);
> @@ -419,12 +418,11 @@ present_winmode_execute(present_vblank_ptr vblank,
> uint64_t ust, uint64_t crtc_m
>                      RegionIntersect(damage, damage, &window->clipList);
>                  } else
>                      damage = &window->clipList;
> -
>                  DamageDamageRegion(&vblank->window->drawable, damage);
> +
>                  if (*screen_priv->winmode_info->flip_executed)
>                      (*screen_priv->winmode_info->flip_executed)
> (vblank->window, vblank->crtc, vblank->event_id, damage);
>
> -
>                  return;
>              }
>
> --
> 2.7.4
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.x.org/archives/xorg-devel/attachments/20170829/9838df09/attachment.html>


More information about the xorg-devel mailing list