xwayland: persistent window struct on present

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@gmail.com>
Tested-by: Olivier Fourdan <ofourdan@redhat.com>
This commit is contained in:
Roman Gilg 2018-05-04 03:07:31 +02:00 committed by Adam Jackson
parent c9afd8cb5e
commit cf838f5ca8
3 changed files with 214 additions and 154 deletions

View File

@ -36,11 +36,49 @@
#define TIMER_LEN_COPY 17 // ~60fps #define TIMER_LEN_COPY 17 // ~60fps
#define TIMER_LEN_FLIP 1000 // 1fps #define TIMER_LEN_FLIP 1000 // 1fps
static void static DevPrivateKeyRec xwl_present_window_private_key;
xwl_present_free_timer(struct xwl_window *xwl_window)
static struct xwl_present_window *
xwl_present_window_priv(WindowPtr window)
{ {
TimerFree(xwl_window->present_timer); return dixGetPrivate(&window->devPrivates,
xwl_window->present_timer = NULL; &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_present_window *xwl_present_window)
{
TimerFree(xwl_present_window->frame_timer);
xwl_present_window->frame_timer = NULL;
} }
static CARD32 static CARD32
@ -49,57 +87,73 @@ xwl_present_timer_callback(OsTimerPtr timer,
void *arg); void *arg);
static inline Bool 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) || return !xorg_list_is_empty(&xwl_present_window->event_list) ||
!xorg_list_is_empty(&xwl_window->present_release_queue); !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 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)) { if (xwl_present_has_events(xwl_present_window)) {
uint32_t timer_len = xwl_window->present_window ? TIMER_LEN_FLIP : WindowPtr present_window = xwl_present_window->window;
TIMER_LEN_COPY; Bool is_flipping = xwl_present_is_flipping(present_window,
xwl_window_from_window(present_window));
xwl_window->present_timer = TimerSet(xwl_window->present_timer, xwl_present_window->frame_timer = TimerSet(xwl_present_window->frame_timer,
0, 0,
timer_len, is_flipping ? TIMER_LEN_FLIP :
&xwl_present_timer_callback, TIMER_LEN_COPY,
xwl_window); &xwl_present_timer_callback,
xwl_present_window);
} else { } else {
xwl_present_free_timer(xwl_window); xwl_present_free_timer(xwl_present_window);
} }
} }
void 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; struct xwl_present_event *event, *tmp;
if (xwl_window->present_window != window && xwl_window->window != window) if (!xwl_present_window)
return; return;
if (xwl_window->present_frame_callback) { if (xwl_window && xwl_window->present_window == window)
wl_callback_destroy(xwl_window->present_frame_callback); xwl_window->present_window = NULL;
xwl_window->present_frame_callback = 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 */ /* 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); xorg_list_del(&event->list);
free(event); free(event);
} }
/* Clear remaining buffer releases and inform Present about free ressources */ /* 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); xorg_list_del(&event->list);
event->abort = TRUE; event->abort = TRUE;
} }
/* Clear timer */ /* Clear timer */
xwl_present_free_timer(xwl_window); xwl_present_free_timer(xwl_present_window);
free(xwl_present_window);
} }
static void static void
@ -113,11 +167,10 @@ static void
xwl_present_buffer_release(void *data, struct wl_buffer *buffer) xwl_present_buffer_release(void *data, struct wl_buffer *buffer)
{ {
struct xwl_present_event *event = data; struct xwl_present_event *event = data;
if (!event) if (!event)
return; return;
wl_buffer_set_user_data(buffer, NULL);
wl_buffer_set_user_data(buffer, NULL);
event->buffer_released = TRUE; event->buffer_released = TRUE;
if (event->abort) { if (event->abort) {
@ -127,10 +180,10 @@ xwl_present_buffer_release(void *data, struct wl_buffer *buffer)
} }
if (!event->pending) { if (!event->pending) {
present_wnmd_event_notify(event->present_window, present_wnmd_event_notify(event->xwl_present_window->window,
event->event_id, event->event_id,
event->xwl_window->present_ust, event->xwl_present_window->ust,
event->xwl_window->present_msc); event->xwl_present_window->msc);
xwl_present_free_event(event); xwl_present_free_event(event);
} }
} }
@ -140,18 +193,18 @@ static const struct wl_buffer_listener xwl_present_release_listener = {
}; };
static void 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; struct xwl_present_event *event, *tmp;
xorg_list_for_each_entry_safe(event, tmp, xorg_list_for_each_entry_safe(event, tmp,
&xwl_window->present_event_list, &xwl_present_window->event_list,
list) { list) {
if (event->target_msc <= msc) { if (event->target_msc <= msc) {
present_wnmd_event_notify(event->present_window, present_wnmd_event_notify(xwl_present_window->window,
event->event_id, event->event_id,
xwl_window->present_ust, xwl_present_window->ust,
msc); msc);
xwl_present_free_event(event); xwl_present_free_event(event);
} }
@ -163,21 +216,23 @@ xwl_present_timer_callback(OsTimerPtr timer,
CARD32 time, CARD32 time,
void *arg) 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_present_window->frame_timer_firing = TRUE;
xwl_window->present_msc++; xwl_present_window->msc++;
xwl_window->present_ust = GetTimeInMicros(); 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 */ /* Still events, restart timer */
return xwl_window->present_window ? TIMER_LEN_FLIP : return xwl_present_is_flipping(present_window, xwl_window) ? TIMER_LEN_FLIP :
TIMER_LEN_COPY; TIMER_LEN_COPY;
} else { } else {
/* No more events, do not restart timer and delete it instead */ /* 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; return 0;
} }
} }
@ -187,25 +242,25 @@ xwl_present_frame_callback(void *data,
struct wl_callback *callback, struct wl_callback *callback,
uint32_t time) 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); wl_callback_destroy(xwl_present_window->frame_callback);
xwl_window->present_frame_callback = NULL; 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 */ /* If the timer is firing, this frame callback is too late */
return; return;
} }
xwl_window->present_msc++; xwl_present_window->msc++;
xwl_window->present_ust = GetTimeInMicros(); 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, /* we do not need the timer anymore for this frame,
* reset it for potentially the next one * 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 = { static const struct wl_callback_listener xwl_present_frame_listener = {
@ -218,7 +273,7 @@ xwl_present_sync_callback(void *data,
uint32_t time) uint32_t time)
{ {
struct xwl_present_event *event = data; 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; event->pending = FALSE;
@ -230,17 +285,17 @@ xwl_present_sync_callback(void *data,
return; return;
} }
present_wnmd_event_notify(event->present_window, present_wnmd_event_notify(xwl_present_window->window,
event->event_id, event->event_id,
xwl_window->present_ust, xwl_present_window->ust,
xwl_window->present_msc); xwl_present_window->msc);
if (event->buffer_released) if (event->buffer_released)
/* If the buffer was already released, send the event now again */ /* 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, event->event_id,
xwl_window->present_ust, xwl_present_window->ust,
xwl_window->present_msc); xwl_present_window->msc);
} }
static const struct wl_callback_listener xwl_present_sync_listener = { static const struct wl_callback_listener xwl_present_sync_listener = {
@ -250,35 +305,26 @@ static const struct wl_callback_listener xwl_present_sync_listener = {
static RRCrtcPtr static RRCrtcPtr
xwl_present_get_crtc(WindowPtr present_window) xwl_present_get_crtc(WindowPtr present_window)
{ {
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);
if (xwl_window == NULL) if (xwl_present_window == NULL)
return NULL; return NULL;
return xwl_window->present_crtc_fake; return xwl_present_window->crtc_fake;
} }
static int static int
xwl_present_get_ust_msc(WindowPtr present_window, uint64_t *ust, uint64_t *msc) 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); struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
if (!xwl_window) if (!xwl_present_window)
return BadAlloc; return BadAlloc;
*ust = xwl_window->present_ust;
*msc = xwl_window->present_msc; *ust = xwl_present_window->ust;
*msc = xwl_present_window->msc;
return Success; return Success;
} }
static void
xwl_present_set_present_window(struct xwl_window *xwl_window,
WindowPtr present_window)
{
if (xwl_window->present_window)
return;
xwl_window->present_window = present_window;
}
/* /*
* Queue an event to report back to the Present extension when the specified * Queue an event to report back to the Present extension when the specified
* MSC has past * MSC has past
@ -290,12 +336,13 @@ xwl_present_queue_vblank(WindowPtr present_window,
uint64_t msc) uint64_t msc)
{ {
struct xwl_window *xwl_window = xwl_window_from_window(present_window); 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; struct xwl_present_event *event;
if (!xwl_window) if (!xwl_window)
return BadMatch; return BadMatch;
if (xwl_window->present_crtc_fake != crtc) if (xwl_present_window->crtc_fake != crtc)
return BadRequest; return BadRequest;
if (xwl_window->present_window && if (xwl_window->present_window &&
@ -307,14 +354,13 @@ xwl_present_queue_vblank(WindowPtr present_window,
return BadAlloc; return BadAlloc;
event->event_id = event_id; event->event_id = event_id;
event->present_window = present_window; event->xwl_present_window = xwl_present_window;
event->xwl_window = xwl_window;
event->target_msc = msc; 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) if (!xwl_present_window->frame_timer)
xwl_present_reset_timer(xwl_window); xwl_present_reset_timer(xwl_present_window);
return Success; return Success;
} }
@ -329,13 +375,13 @@ xwl_present_abort_vblank(WindowPtr present_window,
uint64_t event_id, uint64_t event_id,
uint64_t msc) 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; struct xwl_present_event *event, *tmp;
if (!xwl_window) if (!xwl_present_window)
return; 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) { if (event->event_id == event_id) {
xorg_list_del(&event->list); xorg_list_del(&event->list);
free(event); 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) { if (event->event_id == event_id) {
event->abort = TRUE; event->abort = TRUE;
return; return;
@ -378,15 +424,6 @@ xwl_present_check_flip2(RRCrtcPtr crtc,
xwl_window->present_window != present_window) xwl_window->present_window != present_window)
return FALSE; 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 * We currently only allow flips of windows, that have the same
* dimensions as their xwl_window parent window. For the case of * dimensions as their xwl_window parent window. For the case of
@ -408,35 +445,45 @@ xwl_present_flip(WindowPtr present_window,
RegionPtr damage) RegionPtr damage)
{ {
struct xwl_window *xwl_window = xwl_window_from_window(present_window); 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; BoxPtr present_box, damage_box;
Bool buffer_created; Bool buffer_created;
struct wl_buffer *buffer; struct wl_buffer *buffer;
struct xwl_present_event *event; 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); present_box = RegionExtents(&present_window->winSize);
damage_box = RegionExtents(damage); damage_box = RegionExtents(damage);
xwl_present_set_present_window(xwl_window, present_window);
event = malloc(sizeof *event); event = malloc(sizeof *event);
if (!event) if (!event)
return FALSE; return FALSE;
xwl_window->present_window = present_window;
buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap, buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap,
present_box->x2 - present_box->x1, present_box->x2 - present_box->x1,
present_box->y2 - present_box->y1, present_box->y2 - present_box->y1,
&buffer_created); &buffer_created);
event->event_id = event_id; event->event_id = event_id;
event->present_window = present_window; event->xwl_present_window = xwl_present_window;
event->xwl_window = xwl_window;
event->buffer = buffer; event->buffer = buffer;
event->target_msc = xwl_window->present_msc; event->target_msc = xwl_present_window->msc;
event->pending = TRUE; event->pending = TRUE;
event->abort = FALSE; event->abort = FALSE;
event->buffer_released = 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) if (buffer_created)
wl_buffer_add_listener(buffer, &xwl_present_release_listener, NULL); 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) */ /* We can flip directly to the main surface (full screen window without clips) */
wl_surface_attach(xwl_window->surface, buffer, 0, 0); wl_surface_attach(xwl_window->surface, buffer, 0, 0);
if (!xwl_window->present_timer || if (!xwl_present_window->frame_timer ||
xwl_window->present_timer_firing) { xwl_present_window->frame_timer_firing) {
/* Realign timer */ /* Realign timer */
xwl_window->present_timer_firing = FALSE; xwl_present_window->frame_timer_firing = FALSE;
xwl_present_reset_timer(xwl_window); xwl_present_reset_timer(xwl_present_window);
} }
if (!xwl_window->present_frame_callback) { if (!xwl_present_window->frame_callback) {
xwl_window->present_frame_callback = wl_surface_frame(xwl_window->surface); xwl_present_window->frame_callback = wl_surface_frame(xwl_window->surface);
wl_callback_add_listener(xwl_window->present_frame_callback, wl_callback_add_listener(xwl_present_window->frame_callback,
&xwl_present_frame_listener, &xwl_present_frame_listener,
xwl_window); xwl_present_window);
} }
wl_surface_damage(xwl_window->surface, 0, 0, wl_surface_damage(xwl_window->surface, 0, 0,
@ -465,8 +512,8 @@ xwl_present_flip(WindowPtr present_window,
wl_surface_commit(xwl_window->surface); wl_surface_commit(xwl_window->surface);
xwl_window->present_sync_callback = wl_display_sync(xwl_window->xwl_screen->display); xwl_present_window->sync_callback = wl_display_sync(xwl_window->xwl_screen->display);
wl_callback_add_listener(xwl_window->present_sync_callback, wl_callback_add_listener(xwl_present_window->sync_callback,
&xwl_present_sync_listener, &xwl_present_sync_listener,
event); event);
@ -478,6 +525,7 @@ static void
xwl_present_flips_stop(WindowPtr window) xwl_present_flips_stop(WindowPtr window)
{ {
struct xwl_window *xwl_window = xwl_window_from_window(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) if (!xwl_window)
return; return;
@ -487,7 +535,7 @@ xwl_present_flips_stop(WindowPtr window)
xwl_window->present_window = NULL; xwl_window->present_window = NULL;
/* Change back to the fast refresh rate */ /* 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 = { 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) if (xwl_screen->egl_backend.post_damage != NULL)
return FALSE; return FALSE;
if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0))
return FALSE;
return present_wnmd_screen_init(screen, &xwl_present_info); return present_wnmd_screen_init(screen, &xwl_present_info);
} }

View File

@ -531,17 +531,6 @@ xwl_realize_window(WindowPtr window)
wl_region_destroy(region); 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); wl_display_flush(xwl_screen->display);
send_surface_id_event(xwl_window); send_surface_id_event(xwl_window);
@ -607,12 +596,6 @@ xwl_unrealize_window(WindowPtr window)
compUnredirectWindow(serverClient, window, CompositeRedirectManual); 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; screen->UnrealizeWindow = xwl_screen->UnrealizeWindow;
ret = (*screen->UnrealizeWindow) (window); ret = (*screen->UnrealizeWindow) (window);
xwl_screen->UnrealizeWindow = screen->UnrealizeWindow; xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;
@ -629,11 +612,6 @@ xwl_unrealize_window(WindowPtr window)
if (xwl_window->frame_callback) if (xwl_window->frame_callback)
wl_callback_destroy(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); free(xwl_window);
dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL); dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL);
@ -661,6 +639,31 @@ static const struct wl_callback_listener frame_listener = {
frame_callback 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 static void
xwl_window_post_damage(struct xwl_window *xwl_window) 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; xwl_screen->UnrealizeWindow = pScreen->UnrealizeWindow;
pScreen->UnrealizeWindow = xwl_unrealize_window; pScreen->UnrealizeWindow = xwl_unrealize_window;
xwl_screen->DestroyWindow = pScreen->DestroyWindow;
pScreen->DestroyWindow = xwl_destroy_window;
xwl_screen->CloseScreen = pScreen->CloseScreen; xwl_screen->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = xwl_close_screen; pScreen->CloseScreen = xwl_close_screen;

View File

@ -77,6 +77,7 @@ struct xwl_screen {
CloseScreenProcPtr CloseScreen; CloseScreenProcPtr CloseScreen;
RealizeWindowProcPtr RealizeWindow; RealizeWindowProcPtr RealizeWindow;
UnrealizeWindowProcPtr UnrealizeWindow; UnrealizeWindowProcPtr UnrealizeWindow;
DestroyWindowProcPtr DestroyWindow;
XYToWindowProcPtr XYToWindow; XYToWindowProcPtr XYToWindow;
struct xorg_list output_list; struct xorg_list output_list;
@ -172,26 +173,29 @@ struct xwl_window {
struct xorg_list link_damage; struct xorg_list link_damage;
struct wl_callback *frame_callback; struct wl_callback *frame_callback;
Bool allow_commits; Bool allow_commits;
#ifdef GLAMOR_HAS_GBM
/* present */
RRCrtcPtr present_crtc_fake;
struct xorg_list present_link;
WindowPtr present_window; WindowPtr present_window;
uint64_t present_msc;
uint64_t present_ust;
OsTimerPtr present_timer;
Bool present_timer_firing;
struct wl_callback *present_frame_callback;
struct wl_callback *present_sync_callback;
struct xorg_list present_event_list;
struct xorg_list present_release_queue;
#endif
}; };
#ifdef GLAMOR_HAS_GBM #ifdef GLAMOR_HAS_GBM
struct xwl_present_window {
struct xwl_screen *xwl_screen;
WindowPtr window;
struct xorg_list link;
RRCrtcPtr crtc_fake;
uint64_t msc;
uint64_t ust;
OsTimerPtr frame_timer;
Bool frame_timer_firing;
struct wl_callback *frame_callback;
struct wl_callback *sync_callback;
struct xorg_list event_list;
struct xorg_list release_queue;
};
struct xwl_present_event { struct xwl_present_event {
uint64_t event_id; uint64_t event_id;
uint64_t target_msc; uint64_t target_msc;
@ -200,8 +204,7 @@ struct xwl_present_event {
Bool pending; Bool pending;
Bool buffer_released; Bool buffer_released;
WindowPtr present_window; struct xwl_present_window *xwl_present_window;
struct xwl_window *xwl_window;
struct wl_buffer *buffer; struct wl_buffer *buffer;
struct xorg_list list; struct xorg_list list;
@ -433,7 +436,7 @@ Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window);
#ifdef GLAMOR_HAS_GBM #ifdef GLAMOR_HAS_GBM
Bool xwl_present_init(ScreenPtr screen); Bool xwl_present_init(ScreenPtr screen);
void xwl_present_cleanup(struct xwl_window *xwl_window, WindowPtr window); void xwl_present_cleanup(WindowPtr window);
#endif #endif
void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen); void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen);