[RFC xserver] xwayland: persistent window struct on present

Roman Gilg subdiff at gmail.com
Fri May 4 01:07:31 UTC 2018


Instead of reusing xwl_window introduce a persistent window struct for every
window, that asks for Present flips.

This struct saves all relevant data and is only freed on window destroy.

Signed-off-by: Roman Gilg <subdiff at gmail.com>
---
 hw/xwayland/xwayland-present.c | 277 ++++++++++++++++++++++++-----------------
 hw/xwayland/xwayland.c         |  50 ++++----
 hw/xwayland/xwayland.h         |  37 +++---
 3 files changed, 212 insertions(+), 152 deletions(-)

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 66bfaae..ae9f47e 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -36,11 +36,49 @@
 #define TIMER_LEN_COPY      17  // ~60fps
 #define TIMER_LEN_FLIP    1000  // 1fps
 
+static DevPrivateKeyRec xwl_present_window_private_key;
+
+static struct xwl_present_window *
+xwl_present_window_priv(WindowPtr window)
+{
+    return dixGetPrivate(&window->devPrivates,
+                         &xwl_present_window_private_key);
+}
+
+static struct xwl_present_window *
+xwl_present_window_get_priv(WindowPtr window)
+{
+    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
+
+    if (xwl_present_window == NULL) {
+        ScreenPtr screen = window->drawable.pScreen;
+
+        xwl_present_window = calloc (1, sizeof (struct xwl_present_window));
+        if (!xwl_present_window)
+            return NULL;
+
+        xwl_present_window->crtc_fake = RRCrtcCreate(screen,
+                                                     xwl_present_window);
+        xwl_present_window->window = window;
+        xwl_present_window->msc = 1;
+        xwl_present_window->ust = GetTimeInMicros();
+
+        xorg_list_init(&xwl_present_window->event_list);
+        xorg_list_init(&xwl_present_window->release_queue);
+
+        dixSetPrivate(&window->devPrivates,
+                      &xwl_present_window_private_key,
+                      xwl_present_window);
+    }
+
+    return xwl_present_window;
+}
+
 static void
-xwl_present_free_timer(struct xwl_window *xwl_window)
+xwl_present_free_timer(struct xwl_present_window *xwl_present_window)
 {
-    TimerFree(xwl_window->present_timer);
-    xwl_window->present_timer = NULL;
+    TimerFree(xwl_present_window->frame_timer);
+    xwl_present_window->frame_timer = NULL;
 }
 
 static CARD32
@@ -49,57 +87,73 @@ xwl_present_timer_callback(OsTimerPtr timer,
                            void *arg);
 
 static inline Bool
-xwl_present_has_events(struct xwl_window *xwl_window)
+xwl_present_has_events(struct xwl_present_window *xwl_present_window)
 {
-    return !xorg_list_is_empty(&xwl_window->present_event_list) ||
-           !xorg_list_is_empty(&xwl_window->present_release_queue);
+    return !xorg_list_is_empty(&xwl_present_window->event_list) ||
+           !xorg_list_is_empty(&xwl_present_window->release_queue);
+}
+
+static inline Bool
+xwl_present_is_flipping(WindowPtr window, struct xwl_window *xwl_window)
+{
+    return xwl_window && xwl_window->present_window == window;
 }
 
 static void
-xwl_present_reset_timer(struct xwl_window *xwl_window)
+xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
 {
-    if (xwl_present_has_events(xwl_window)) {
-        uint32_t timer_len = xwl_window->present_window ? TIMER_LEN_FLIP :
-                                                          TIMER_LEN_COPY;
-
-        xwl_window->present_timer = TimerSet(xwl_window->present_timer,
-                                             0,
-                                             timer_len,
-                                             &xwl_present_timer_callback,
-                                             xwl_window);
+    if (xwl_present_has_events(xwl_present_window)) {
+        WindowPtr present_window = xwl_present_window->window;
+        Bool is_flipping = xwl_present_is_flipping(present_window,
+                                                   xwl_window_from_window(present_window));
+
+        xwl_present_window->frame_timer = TimerSet(xwl_present_window->frame_timer,
+                                                   0,
+                                                   is_flipping ? TIMER_LEN_FLIP :
+                                                                 TIMER_LEN_COPY,
+                                                   &xwl_present_timer_callback,
+                                                   xwl_present_window);
     } else {
-        xwl_present_free_timer(xwl_window);
+        xwl_present_free_timer(xwl_present_window);
     }
 }
 
 void
-xwl_present_cleanup(struct xwl_window *xwl_window, WindowPtr window)
+xwl_present_cleanup(WindowPtr window)
 {
+    struct xwl_window *xwl_window = xwl_window_from_window(window);
+    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
     struct xwl_present_event *event, *tmp;
 
-    if (xwl_window->present_window != window && xwl_window->window != window)
+    if (!xwl_present_window)
         return;
 
-    if (xwl_window->present_frame_callback) {
-        wl_callback_destroy(xwl_window->present_frame_callback);
-        xwl_window->present_frame_callback = NULL;
+    if (xwl_window && xwl_window->present_window == window)
+        xwl_window->present_window = NULL;
+
+    RRCrtcDestroy(xwl_present_window->crtc_fake);
+
+    if (xwl_present_window->frame_callback) {
+        wl_callback_destroy(xwl_present_window->frame_callback);
+        xwl_present_window->frame_callback = NULL;
     }
-    xwl_window->present_window = NULL;
 
     /* Clear remaining events */
-    xorg_list_for_each_entry_safe(event, tmp, &xwl_window->present_event_list, list) {
+    xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->event_list, list) {
         xorg_list_del(&event->list);
         free(event);
     }
 
     /* Clear remaining buffer releases and inform Present about free ressources */
-    xorg_list_for_each_entry_safe(event, tmp, &xwl_window->present_release_queue, list) {
+    xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->release_queue, list) {
         xorg_list_del(&event->list);
         event->abort = TRUE;
     }
 
     /* Clear timer */
-    xwl_present_free_timer(xwl_window);
+    xwl_present_free_timer(xwl_present_window);
+
+    free(xwl_present_window);
 }
 
 static void
@@ -113,11 +167,10 @@ static void
 xwl_present_buffer_release(void *data, struct wl_buffer *buffer)
 {
     struct xwl_present_event *event = data;
-
     if (!event)
         return;
-    wl_buffer_set_user_data(buffer, NULL);
 
+    wl_buffer_set_user_data(buffer, NULL);
     event->buffer_released = TRUE;
 
     if (event->abort) {
@@ -127,10 +180,10 @@ xwl_present_buffer_release(void *data, struct wl_buffer *buffer)
     }
 
     if (!event->pending) {
-        present_wnmd_event_notify(event->present_window,
+        present_wnmd_event_notify(event->xwl_present_window->window,
                                   event->event_id,
-                                  event->xwl_window->present_ust,
-                                  event->xwl_window->present_msc);
+                                  event->xwl_present_window->ust,
+                                  event->xwl_present_window->msc);
         xwl_present_free_event(event);
     }
 }
@@ -140,18 +193,18 @@ static const struct wl_buffer_listener xwl_present_release_listener = {
 };
 
 static void
-xwl_present_events_notify(struct xwl_window *xwl_window)
+xwl_present_events_notify(struct xwl_present_window *xwl_present_window)
 {
-    uint64_t                    msc = xwl_window->present_msc;
+    uint64_t                    msc = xwl_present_window->msc;
     struct xwl_present_event    *event, *tmp;
 
     xorg_list_for_each_entry_safe(event, tmp,
-                                  &xwl_window->present_event_list,
+                                  &xwl_present_window->event_list,
                                   list) {
         if (event->target_msc <= msc) {
-            present_wnmd_event_notify(event->present_window,
+            present_wnmd_event_notify(xwl_present_window->window,
                                       event->event_id,
-                                      xwl_window->present_ust,
+                                      xwl_present_window->ust,
                                       msc);
             xwl_present_free_event(event);
         }
@@ -163,21 +216,23 @@ xwl_present_timer_callback(OsTimerPtr timer,
                            CARD32 time,
                            void *arg)
 {
-    struct xwl_window *xwl_window = arg;
+    struct xwl_present_window *xwl_present_window = arg;
+    WindowPtr present_window = xwl_present_window->window;
+    struct xwl_window *xwl_window = xwl_window_from_window(present_window);
 
-    xwl_window->present_timer_firing = TRUE;
-    xwl_window->present_msc++;
-    xwl_window->present_ust = GetTimeInMicros();
+    xwl_present_window->frame_timer_firing = TRUE;
+    xwl_present_window->msc++;
+    xwl_present_window->ust = GetTimeInMicros();
 
-    xwl_present_events_notify(xwl_window);
+    xwl_present_events_notify(xwl_present_window);
 
-    if (xwl_present_has_events(xwl_window)) {
+    if (xwl_present_has_events(xwl_present_window)) {
         /* Still events, restart timer */
-        return xwl_window->present_window ? TIMER_LEN_FLIP :
-                                            TIMER_LEN_COPY;
+        return xwl_present_is_flipping(present_window, xwl_window) ? TIMER_LEN_FLIP :
+                                                                     TIMER_LEN_COPY;
     } else {
         /* No more events, do not restart timer and delete it instead */
-        xwl_present_free_timer(xwl_window);
+        xwl_present_free_timer(xwl_present_window);
         return 0;
     }
 }
@@ -187,25 +242,25 @@ xwl_present_frame_callback(void *data,
                struct wl_callback *callback,
                uint32_t time)
 {
-    struct xwl_window *xwl_window = data;
+    struct xwl_present_window *xwl_present_window = data;
 
-    wl_callback_destroy(xwl_window->present_frame_callback);
-    xwl_window->present_frame_callback = NULL;
+    wl_callback_destroy(xwl_present_window->frame_callback);
+    xwl_present_window->frame_callback = NULL;
 
-    if (xwl_window->present_timer_firing) {
+    if (xwl_present_window->frame_timer_firing) {
         /* If the timer is firing, this frame callback is too late */
         return;
     }
 
-    xwl_window->present_msc++;
-    xwl_window->present_ust = GetTimeInMicros();
+    xwl_present_window->msc++;
+    xwl_present_window->ust = GetTimeInMicros();
 
-    xwl_present_events_notify(xwl_window);
+    xwl_present_events_notify(xwl_present_window);
 
     /* we do not need the timer anymore for this frame,
      * reset it for potentially the next one
      */
-    xwl_present_reset_timer(xwl_window);
+    xwl_present_reset_timer(xwl_present_window);
 }
 
 static const struct wl_callback_listener xwl_present_frame_listener = {
@@ -218,7 +273,7 @@ xwl_present_sync_callback(void *data,
                uint32_t time)
 {
     struct xwl_present_event *event = data;
-    struct xwl_window *xwl_window = event->xwl_window;
+    struct xwl_present_window *xwl_present_window = event->xwl_present_window;
 
     event->pending = FALSE;
 
@@ -230,17 +285,17 @@ xwl_present_sync_callback(void *data,
         return;
     }
 
-    present_wnmd_event_notify(event->present_window,
+    present_wnmd_event_notify(xwl_present_window->window,
                               event->event_id,
-                              xwl_window->present_ust,
-                              xwl_window->present_msc);
+                              xwl_present_window->ust,
+                              xwl_present_window->msc);
 
     if (event->buffer_released)
         /* If the buffer was already released, send the event now again */
-        present_wnmd_event_notify(event->present_window,
+        present_wnmd_event_notify(xwl_present_window->window,
                                   event->event_id,
-                                  xwl_window->present_ust,
-                                  xwl_window->present_msc);
+                                  xwl_present_window->ust,
+                                  xwl_present_window->msc);
 }
 
 static const struct wl_callback_listener xwl_present_sync_listener = {
@@ -250,33 +305,24 @@ static const struct wl_callback_listener xwl_present_sync_listener = {
 static RRCrtcPtr
 xwl_present_get_crtc(WindowPtr present_window)
 {
-    struct xwl_window *xwl_window = xwl_window_from_window(present_window);
-    if (xwl_window == NULL)
+    struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
+    if (xwl_present_window == NULL)
         return NULL;
 
-    return xwl_window->present_crtc_fake;
+    return xwl_present_window->crtc_fake;
 }
 
 static int
 xwl_present_get_ust_msc(WindowPtr present_window, uint64_t *ust, uint64_t *msc)
 {
-    struct xwl_window *xwl_window = xwl_window_from_window(present_window);
-    if (!xwl_window)
+    struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
+    if (!xwl_present_window)
         return BadAlloc;
-    *ust = xwl_window->present_ust;
-    *msc = xwl_window->present_msc;
 
-    return Success;
-}
-
-static void
-xwl_present_set_present_window(struct xwl_window *xwl_window,
-                               WindowPtr present_window)
-{
-    if (xwl_window->present_window)
-        return;
+    *ust = xwl_present_window->ust;
+    *msc = xwl_present_window->msc;
 
-    xwl_window->present_window = present_window;
+    return Success;
 }
 
 /*
@@ -290,12 +336,13 @@ xwl_present_queue_vblank(WindowPtr present_window,
                          uint64_t msc)
 {
     struct xwl_window *xwl_window = xwl_window_from_window(present_window);
+    struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
     struct xwl_present_event *event;
 
     if (!xwl_window)
         return BadMatch;
 
-    if (xwl_window->present_crtc_fake != crtc)
+    if (xwl_present_window->crtc_fake != crtc)
         return BadRequest;
 
     if (xwl_window->present_window &&
@@ -307,14 +354,13 @@ xwl_present_queue_vblank(WindowPtr present_window,
         return BadAlloc;
 
     event->event_id = event_id;
-    event->present_window = present_window;
-    event->xwl_window = xwl_window;
+    event->xwl_present_window = xwl_present_window;
     event->target_msc = msc;
 
-    xorg_list_append(&event->list, &xwl_window->present_event_list);
+    xorg_list_append(&event->list, &xwl_present_window->event_list);
 
-    if (!xwl_window->present_timer)
-        xwl_present_reset_timer(xwl_window);
+    if (!xwl_present_window->frame_timer)
+        xwl_present_reset_timer(xwl_present_window);
 
     return Success;
 }
@@ -329,13 +375,13 @@ xwl_present_abort_vblank(WindowPtr present_window,
                          uint64_t event_id,
                          uint64_t msc)
 {
-    struct xwl_window *xwl_window = xwl_window_from_window(present_window);
+    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(present_window);
     struct xwl_present_event *event, *tmp;
 
-    if (!xwl_window)
+    if (!xwl_present_window)
         return;
 
-    xorg_list_for_each_entry_safe(event, tmp, &xwl_window->present_event_list, list) {
+    xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->event_list, list) {
         if (event->event_id == event_id) {
             xorg_list_del(&event->list);
             free(event);
@@ -343,7 +389,7 @@ xwl_present_abort_vblank(WindowPtr present_window,
         }
     }
 
-    xorg_list_for_each_entry(event, &xwl_window->present_release_queue, list) {
+    xorg_list_for_each_entry(event, &xwl_present_window->release_queue, list) {
         if (event->event_id == event_id) {
             event->abort = TRUE;
             return;
@@ -378,15 +424,6 @@ xwl_present_check_flip2(RRCrtcPtr crtc,
             xwl_window->present_window != present_window)
         return FALSE;
 
-    if (!xwl_window->present_crtc_fake)
-        return FALSE;
-    /*
-     * Make sure the client doesn't try to flip to another crtc
-     * than the one created for 'xwl_window'.
-     */
-    if (xwl_window->present_crtc_fake != crtc)
-        return FALSE;
-
     /*
      * We currently only allow flips of windows, that have the same
      * dimensions as their xwl_window parent window. For the case of
@@ -408,35 +445,45 @@ xwl_present_flip(WindowPtr present_window,
                  RegionPtr damage)
 {
     struct xwl_window           *xwl_window = xwl_window_from_window(present_window);
+    struct xwl_present_window   *xwl_present_window = xwl_present_window_priv(present_window);
     BoxPtr                      present_box, damage_box;
     Bool                        buffer_created;
     struct wl_buffer            *buffer;
     struct xwl_present_event    *event;
 
+    if (!xwl_window)
+        return FALSE;
+
+    /*
+     * Make sure the client doesn't try to flip to another crtc
+     * than the one created for 'xwl_window'.
+     */
+    if (xwl_present_window->crtc_fake != crtc)
+        return FALSE;
+
     present_box = RegionExtents(&present_window->winSize);
     damage_box = RegionExtents(damage);
 
-    xwl_present_set_present_window(xwl_window, present_window);
-
     event = malloc(sizeof *event);
     if (!event)
         return FALSE;
 
+    xwl_window->present_window = present_window;
+
     buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap,
                                              present_box->x2 - present_box->x1,
                                              present_box->y2 - present_box->y1,
                                              &buffer_created);
 
     event->event_id = event_id;
-    event->present_window = present_window;
-    event->xwl_window = xwl_window;
+    event->xwl_present_window = xwl_present_window;
     event->buffer = buffer;
-    event->target_msc = xwl_window->present_msc;
+    event->target_msc = xwl_present_window->msc;
     event->pending = TRUE;
     event->abort = FALSE;
     event->buffer_released = FALSE;
 
-    xorg_list_add(&event->list, &xwl_window->present_release_queue);
+    xorg_list_add(&event->list, &xwl_present_window->release_queue);
 
     if (buffer_created)
         wl_buffer_add_listener(buffer, &xwl_present_release_listener, NULL);
@@ -445,18 +492,18 @@ xwl_present_flip(WindowPtr present_window,
     /* We can flip directly to the main surface (full screen window without clips) */
     wl_surface_attach(xwl_window->surface, buffer, 0, 0);
 
-    if (!xwl_window->present_timer ||
-            xwl_window->present_timer_firing) {
+    if (!xwl_present_window->frame_timer ||
+            xwl_present_window->frame_timer_firing) {
         /* Realign timer */
-        xwl_window->present_timer_firing = FALSE;
-        xwl_present_reset_timer(xwl_window);
+        xwl_present_window->frame_timer_firing = FALSE;
+        xwl_present_reset_timer(xwl_present_window);
     }
 
-    if (!xwl_window->present_frame_callback) {
-        xwl_window->present_frame_callback = wl_surface_frame(xwl_window->surface);
-        wl_callback_add_listener(xwl_window->present_frame_callback,
+    if (!xwl_present_window->frame_callback) {
+        xwl_present_window->frame_callback = wl_surface_frame(xwl_window->surface);
+        wl_callback_add_listener(xwl_present_window->frame_callback,
                                  &xwl_present_frame_listener,
-                                 xwl_window);
+                                 xwl_present_window);
     }
 
     wl_surface_damage(xwl_window->surface, 0, 0,
@@ -465,8 +512,8 @@ xwl_present_flip(WindowPtr present_window,
 
     wl_surface_commit(xwl_window->surface);
 
-    xwl_window->present_sync_callback = wl_display_sync(xwl_window->xwl_screen->display);
-    wl_callback_add_listener(xwl_window->present_sync_callback,
+    xwl_present_window->sync_callback = wl_display_sync(xwl_window->xwl_screen->display);
+    wl_callback_add_listener(xwl_present_window->sync_callback,
                              &xwl_present_sync_listener,
                              event);
 
@@ -478,6 +525,7 @@ static void
 xwl_present_flips_stop(WindowPtr window)
 {
     struct xwl_window *xwl_window = xwl_window_from_window(window);
+    struct xwl_present_window   *xwl_present_window = xwl_present_window_priv(window);
 
     if (!xwl_window)
         return;
@@ -487,7 +535,7 @@ xwl_present_flips_stop(WindowPtr window)
     xwl_window->present_window = NULL;
 
     /* Change back to the fast refresh rate */
-    xwl_present_reset_timer(xwl_window);
+    xwl_present_reset_timer(xwl_present_window);
 }
 
 static present_wnmd_info_rec xwl_present_info = {
@@ -518,5 +566,8 @@ xwl_present_init(ScreenPtr screen)
     if (xwl_screen->egl_backend.post_damage != NULL)
         return FALSE;
 
+    if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0))
+        return FALSE;
+
     return present_wnmd_screen_init(screen, &xwl_present_info);
 }
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index f7e2ce9..f5b03b2 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -531,17 +531,6 @@ xwl_realize_window(WindowPtr window)
         wl_region_destroy(region);
     }
 
-#ifdef GLAMOR_HAS_GBM
-    if (xwl_screen->present) {
-        xwl_window->present_crtc_fake = RRCrtcCreate(xwl_screen->screen, xwl_window);
-        xwl_window->present_msc = 1;
-        xwl_window->present_ust = GetTimeInMicros();
-
-        xorg_list_init(&xwl_window->present_event_list);
-        xorg_list_init(&xwl_window->present_release_queue);
-    }
-#endif
-
     wl_display_flush(xwl_screen->display);
 
     send_surface_id_event(xwl_window);
@@ -607,12 +596,6 @@ xwl_unrealize_window(WindowPtr window)
 
     compUnredirectWindow(serverClient, window, CompositeRedirectManual);
 
-#ifdef GLAMOR_HAS_GBM
-    xwl_window = xwl_window_from_window(window);
-    if (xwl_window && xwl_screen->present)
-        xwl_present_cleanup(xwl_window, window);
-#endif
-
     screen->UnrealizeWindow = xwl_screen->UnrealizeWindow;
     ret = (*screen->UnrealizeWindow) (window);
     xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;
@@ -629,11 +612,6 @@ xwl_unrealize_window(WindowPtr window)
     if (xwl_window->frame_callback)
         wl_callback_destroy(xwl_window->frame_callback);
 
-#ifdef GLAMOR_HAS_GBM
-    if (xwl_window->present_crtc_fake)
-        RRCrtcDestroy(xwl_window->present_crtc_fake);
-#endif
-
     free(xwl_window);
     dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL);
 
@@ -661,6 +639,31 @@ static const struct wl_callback_listener frame_listener = {
     frame_callback
 };
 
+static Bool
+xwl_destroy_window(WindowPtr window)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+    Bool ret;
+
+#ifdef GLAMOR_HAS_GBM
+    if (xwl_screen->present)
+        xwl_present_cleanup(window);
+#endif
+
+    screen->DestroyWindow = xwl_screen->DestroyWindow;
+
+    if (screen->DestroyWindow)
+        ret = screen->DestroyWindow (window);
+    else
+        ret = TRUE;
+
+    xwl_screen->DestroyWindow = screen->DestroyWindow;
+    screen->DestroyWindow = xwl_destroy_window;
+
+    return ret;
+}
+
 static void
 xwl_window_post_damage(struct xwl_window *xwl_window)
 {
@@ -1114,6 +1117,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
     xwl_screen->UnrealizeWindow = pScreen->UnrealizeWindow;
     pScreen->UnrealizeWindow = xwl_unrealize_window;
 
+    xwl_screen->DestroyWindow = pScreen->DestroyWindow;
+    pScreen->DestroyWindow = xwl_destroy_window;
+
     xwl_screen->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = xwl_close_screen;
 
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 985ba9d..ce290d4 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -77,6 +77,7 @@ struct xwl_screen {
     CloseScreenProcPtr CloseScreen;
     RealizeWindowProcPtr RealizeWindow;
     UnrealizeWindowProcPtr UnrealizeWindow;
+    DestroyWindowProcPtr DestroyWindow;
     XYToWindowProcPtr XYToWindow;
 
     struct xorg_list output_list;
@@ -172,26 +173,29 @@ struct xwl_window {
     struct xorg_list link_damage;
     struct wl_callback *frame_callback;
     Bool allow_commits;
-#ifdef GLAMOR_HAS_GBM
-    /* present */
-    RRCrtcPtr present_crtc_fake;
-    struct xorg_list present_link;
     WindowPtr present_window;
-    uint64_t present_msc;
-    uint64_t present_ust;
+};
+
+#ifdef GLAMOR_HAS_GBM
+struct xwl_present_window {
+    struct xwl_screen *xwl_screen;
+    WindowPtr window;
+    struct xorg_list link;
 
-    OsTimerPtr present_timer;
-    Bool present_timer_firing;
+    RRCrtcPtr crtc_fake;
+    uint64_t msc;
+    uint64_t ust;
 
-    struct wl_callback *present_frame_callback;
-    struct wl_callback *present_sync_callback;
+    OsTimerPtr frame_timer;
+    Bool frame_timer_firing;
 
-    struct xorg_list present_event_list;
-    struct xorg_list present_release_queue;
-#endif
+    struct wl_callback *frame_callback;
+    struct wl_callback *sync_callback;
+
+    struct xorg_list event_list;
+    struct xorg_list release_queue;
 };
 
-#ifdef GLAMOR_HAS_GBM
 struct xwl_present_event {
     uint64_t event_id;
     uint64_t target_msc;
@@ -200,8 +204,7 @@ struct xwl_present_event {
     Bool pending;
     Bool buffer_released;
 
-    WindowPtr present_window;
-    struct xwl_window *xwl_window;
+    struct xwl_present_window *xwl_present_window;
     struct wl_buffer *buffer;
 
     struct xorg_list list;
@@ -433,7 +436,7 @@ Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window);
 
 #ifdef GLAMOR_HAS_GBM
 Bool xwl_present_init(ScreenPtr screen);
-void xwl_present_cleanup(struct xwl_window *xwl_window, WindowPtr window);
+void xwl_present_cleanup(WindowPtr window);
 #endif
 
 void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen);
-- 
2.7.4



More information about the xorg-devel mailing list