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 <subd...@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 <subd...@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 > >
_______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel