diff options
author | Roman Gilg <subdiff@gmail.com> | 2018-03-13 16:00:36 +0100 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2018-03-28 14:36:16 -0400 |
commit | 5365ece70a75a05df3d6351767d19c3edcf0305d (patch) | |
tree | 6d0308192b9fd84e4592d6f5c8d7a6880ded10c2 /present | |
parent | c5c50c6db1e71e976596750277b1a618704c04aa (diff) |
present: Move vblank functionality in seperate file
With the new internal flip mode API move vblank creation
and so on into a seperate file, such that it can be shared
between flip modes.
Signed-off-by: Roman Gilg <subdiff@gmail.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Diffstat (limited to 'present')
-rw-r--r-- | present/Makefile.am | 3 | ||||
-rw-r--r-- | present/meson.build | 1 | ||||
-rw-r--r-- | present/present_priv.h | 44 | ||||
-rw-r--r-- | present/present_scmd.c | 156 | ||||
-rw-r--r-- | present/present_vblank.c | 200 |
5 files changed, 261 insertions, 143 deletions
diff --git a/present/Makefile.am b/present/Makefile.am index 3b458fdbc..3d3d38d76 100644 --- a/present/Makefile.am +++ b/present/Makefile.am @@ -13,6 +13,7 @@ libpresent_la_SOURCES = \ present_priv.h \ present_request.c \ present_scmd.c \ - present_screen.c + present_screen.c \ + present_vblank.c sdk_HEADERS = present.h presentext.h diff --git a/present/meson.build b/present/meson.build index 859a99152..d22cd09a7 100644 --- a/present/meson.build +++ b/present/meson.build @@ -7,6 +7,7 @@ srcs_present = [ 'present_request.c', 'present_scmd.c', 'present_screen.c', + 'present_vblank.c', ] libxserver_present = static_library('libxserver_present', diff --git a/present/present_priv.h b/present/present_priv.h index 8908061c0..dc6654e77 100644 --- a/present/present_priv.h +++ b/present/present_priv.h @@ -179,6 +179,17 @@ present_window_priv_ptr present_get_window_priv(WindowPtr window, Bool create); /* + * Returns: + * TRUE if the first MSC value is after the second one + * FALSE if the first MSC value is equal to or before the second one + */ +static inline Bool +msc_is_after(uint64_t test, uint64_t reference) +{ + return (int64_t)(test - reference) > 0; +} + +/* * present.c */ void @@ -328,9 +339,6 @@ void present_abort_vblank(ScreenPtr screen, RRCrtcPtr crtc, uint64_t event_id, uint64_t msc); void -present_vblank_destroy(present_vblank_ptr vblank); - -void present_flip_destroy(ScreenPtr screen); void @@ -355,4 +363,34 @@ present_scmd_init_mode_hooks(present_screen_priv_ptr screen_priv); * present_screen.c */ +/* + * present_vblank.c + */ +void +present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_t ust, uint64_t crtc_msc); + +present_vblank_ptr +present_vblank_create(WindowPtr window, + PixmapPtr pixmap, + CARD32 serial, + RegionPtr valid, + RegionPtr update, + int16_t x_off, + int16_t y_off, + RRCrtcPtr target_crtc, + SyncFence *wait_fence, + SyncFence *idle_fence, + uint32_t options, + const uint32_t *capabilities, + present_notify_ptr notifies, + int num_notifies, + uint64_t *target_msc, + uint64_t crtc_msc); + +void +present_vblank_scrap(present_vblank_ptr vblank); + +void +present_vblank_destroy(present_vblank_ptr vblank); + #endif /* _PRESENT_PRIV_H_ */ diff --git a/present/present_scmd.c b/present/present_scmd.c index 17a1758d8..1e11d3505 100644 --- a/present/present_scmd.c +++ b/present/present_scmd.c @@ -48,17 +48,6 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc); /* * Returns: - * TRUE if the first MSC value is after the second one - * FALSE if the first MSC value is equal to or before the second one - */ -static Bool -msc_is_after(uint64_t test, uint64_t reference) -{ - return (int64_t)(test - reference) > 0; -} - -/* - * Returns: * TRUE if the first MSC value is equal to or after the second one * FALSE if the first MSC value is before the second one */ @@ -180,22 +169,6 @@ present_flip(RRCrtcPtr crtc, return (*screen_priv->info->flip) (crtc, event_id, target_msc, pixmap, sync_flip); } -static void -present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_t ust, uint64_t crtc_msc) -{ - int n; - - if (vblank->window) - present_send_complete_notify(vblank->window, kind, mode, vblank->serial, ust, crtc_msc - vblank->msc_offset); - for (n = 0; n < vblank->num_notifies; n++) { - WindowPtr window = vblank->notifies[n].window; - CARD32 serial = vblank->notifies[n].serial; - - if (window) - present_send_complete_notify(window, kind, mode, serial, ust, crtc_msc - vblank->msc_offset); - } -} - RRCrtcPtr present_get_crtc(WindowPtr window) { @@ -773,7 +746,6 @@ present_pixmap(WindowPtr window, ScreenPtr screen = window->drawable.pScreen; present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE); present_screen_priv_ptr screen_priv = present_screen_priv(screen); - PresentFlipReason reason = PRESENT_FLIP_REASON_UNKNOWN; if (!window_priv) return BadAlloc; @@ -854,81 +826,26 @@ present_pixmap(WindowPtr window, } } - vblank = calloc (1, sizeof (present_vblank_rec)); + vblank = present_vblank_create(window, + pixmap, + serial, + valid, + update, + x_off, + y_off, + target_crtc, + wait_fence, + idle_fence, + options, + screen_priv->info ? &screen_priv->info->capabilities : NULL, + notifies, + num_notifies, + &target_msc, + crtc_msc); + if (!vblank) return BadAlloc; - xorg_list_append(&vblank->window_list, &window_priv->vblank); - xorg_list_init(&vblank->event_queue); - - vblank->screen = screen; - vblank->window = window; - vblank->pixmap = pixmap; - present_scmd_create_event_id(vblank); - - if (pixmap) { - vblank->kind = PresentCompleteKindPixmap; - pixmap->refcnt++; - } else - vblank->kind = PresentCompleteKindNotifyMSC; - - vblank->serial = serial; - - if (valid) { - vblank->valid = RegionDuplicate(valid); - if (!vblank->valid) - goto no_mem; - } - if (update) { - vblank->update = RegionDuplicate(update); - if (!vblank->update) - goto no_mem; - } - - vblank->x_off = x_off; - vblank->y_off = y_off; - vblank->target_msc = target_msc; - vblank->crtc = target_crtc; - vblank->msc_offset = window_priv->msc_offset; - vblank->notifies = notifies; - vblank->num_notifies = num_notifies; - vblank->has_suboptimal = (options & PresentOptionSuboptimal); - - if (pixmap != NULL && - !(options & PresentOptionCopy) && - screen_priv->info) { - if (msc_is_after(target_msc, crtc_msc) && - present_check_flip (target_crtc, window, pixmap, TRUE, valid, x_off, y_off, &reason)) - { - vblank->flip = TRUE; - vblank->sync_flip = TRUE; - target_msc--; - } else if ((screen_priv->info->capabilities & PresentCapabilityAsync) && - present_check_flip (target_crtc, window, pixmap, FALSE, valid, x_off, y_off, &reason)) - { - vblank->flip = TRUE; - } - } - vblank->reason = reason; - - if (wait_fence) { - vblank->wait_fence = present_fence_create(wait_fence); - if (!vblank->wait_fence) - goto no_mem; - } - - if (idle_fence) { - vblank->idle_fence = present_fence_create(idle_fence); - if (!vblank->idle_fence) - goto no_mem; - } - - if (pixmap) - DebugPresent(("q %lld %p %8lld: %08lx -> %08lx (crtc %p) flip %d vsync %d serial %d\n", - vblank->event_id, vblank, target_msc, - vblank->pixmap->drawable.id, vblank->window->drawable.id, - target_crtc, vblank->flip, vblank->sync_flip, vblank->serial)); - xorg_list_append(&vblank->event_queue, &present_exec_queue); vblank->queued = TRUE; if (msc_is_after(target_msc, crtc_msc)) { @@ -942,12 +859,6 @@ present_pixmap(WindowPtr window, present_execute(vblank, ust, crtc_msc); return Success; - -no_mem: - ret = BadAlloc; - vblank->notifies = NULL; - present_vblank_destroy(vblank); - return ret; } void @@ -1013,39 +924,6 @@ present_flip_destroy(ScreenPtr screen) } void -present_vblank_destroy(present_vblank_ptr vblank) -{ - /* Remove vblank from window and screen lists */ - xorg_list_del(&vblank->window_list); - - DebugPresent(("\td %lld %p %8lld: %08lx -> %08lx\n", - vblank->event_id, vblank, vblank->target_msc, - vblank->pixmap ? vblank->pixmap->drawable.id : 0, - vblank->window ? vblank->window->drawable.id : 0)); - - /* Drop pixmap reference */ - if (vblank->pixmap) - dixDestroyPixmap(vblank->pixmap, vblank->pixmap->drawable.id); - - /* Free regions */ - if (vblank->valid) - RegionDestroy(vblank->valid); - if (vblank->update) - RegionDestroy(vblank->update); - - if (vblank->wait_fence) - present_fence_destroy(vblank->wait_fence); - - if (vblank->idle_fence) - present_fence_destroy(vblank->idle_fence); - - if (vblank->notifies) - present_destroy_notifies(vblank->notifies, vblank->num_notifies); - - free(vblank); -} - -void present_scmd_init_mode_hooks(present_screen_priv_ptr screen_priv) { screen_priv->check_flip = &present_check_flip; diff --git a/present/present_vblank.c b/present/present_vblank.c new file mode 100644 index 000000000..6265dffa5 --- /dev/null +++ b/present/present_vblank.c @@ -0,0 +1,200 @@ +/* + * Copyright © 2013 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include "present_priv.h" + +void +present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_t ust, uint64_t crtc_msc) +{ + int n; + + if (vblank->window) + present_send_complete_notify(vblank->window, kind, mode, vblank->serial, ust, crtc_msc - vblank->msc_offset); + for (n = 0; n < vblank->num_notifies; n++) { + WindowPtr window = vblank->notifies[n].window; + CARD32 serial = vblank->notifies[n].serial; + + if (window) + present_send_complete_notify(window, kind, mode, serial, ust, crtc_msc - vblank->msc_offset); + } +} + +present_vblank_ptr +present_vblank_create(WindowPtr window, + PixmapPtr pixmap, + CARD32 serial, + RegionPtr valid, + RegionPtr update, + int16_t x_off, + int16_t y_off, + RRCrtcPtr target_crtc, + SyncFence *wait_fence, + SyncFence *idle_fence, + uint32_t options, + const uint32_t *capabilities, + present_notify_ptr notifies, + int num_notifies, + uint64_t *target_msc, + uint64_t crtc_msc) +{ + ScreenPtr screen = window->drawable.pScreen; + present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE); + present_screen_priv_ptr screen_priv = present_screen_priv(screen); + present_vblank_ptr vblank; + PresentFlipReason reason = PRESENT_FLIP_REASON_UNKNOWN; + + vblank = calloc (1, sizeof (present_vblank_rec)); + if (!vblank) + return NULL; + + xorg_list_append(&vblank->window_list, &window_priv->vblank); + xorg_list_init(&vblank->event_queue); + + vblank->screen = screen; + vblank->window = window; + vblank->pixmap = pixmap; + + screen_priv->create_event_id(vblank); + + if (pixmap) { + vblank->kind = PresentCompleteKindPixmap; + pixmap->refcnt++; + } else + vblank->kind = PresentCompleteKindNotifyMSC; + + vblank->serial = serial; + + if (valid) { + vblank->valid = RegionDuplicate(valid); + if (!vblank->valid) + goto no_mem; + } + if (update) { + vblank->update = RegionDuplicate(update); + if (!vblank->update) + goto no_mem; + } + + vblank->x_off = x_off; + vblank->y_off = y_off; + vblank->target_msc = *target_msc; + vblank->crtc = target_crtc; + vblank->msc_offset = window_priv->msc_offset; + vblank->notifies = notifies; + vblank->num_notifies = num_notifies; + vblank->has_suboptimal = (options & PresentOptionSuboptimal); + + if (pixmap != NULL && + !(options & PresentOptionCopy) && + capabilities) { + if (msc_is_after(*target_msc, crtc_msc) && + screen_priv->check_flip (target_crtc, window, pixmap, TRUE, valid, x_off, y_off, &reason)) + { + vblank->flip = TRUE; + vblank->sync_flip = TRUE; + *target_msc = *target_msc - 1; + } else if ((*capabilities & PresentCapabilityAsync) && + screen_priv->check_flip (target_crtc, window, pixmap, FALSE, valid, x_off, y_off, &reason)) + { + vblank->flip = TRUE; + } + } + vblank->reason = reason; + + if (wait_fence) { + vblank->wait_fence = present_fence_create(wait_fence); + if (!vblank->wait_fence) + goto no_mem; + } + + if (idle_fence) { + vblank->idle_fence = present_fence_create(idle_fence); + if (!vblank->idle_fence) + goto no_mem; + } + + if (pixmap) + DebugPresent(("q %lld %p %8lld: %08lx -> %08lx (crtc %p) flip %d vsync %d serial %d\n", + vblank->event_id, vblank, *target_msc, + vblank->pixmap->drawable.id, vblank->window->drawable.id, + target_crtc, vblank->flip, vblank->sync_flip, vblank->serial)); + return vblank; + +no_mem: + vblank->notifies = NULL; + present_vblank_destroy(vblank); + return NULL; +} + +void +present_vblank_scrap(present_vblank_ptr vblank) +{ + DebugPresent(("\tx %lld %p %8lld: %08lx -> %08lx (crtc %p)\n", + vblank->event_id, vblank, vblank->target_msc, + vblank->pixmap->drawable.id, vblank->window->drawable.id, + vblank->crtc)); + + present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence); + present_fence_destroy(vblank->idle_fence); + dixDestroyPixmap(vblank->pixmap, vblank->pixmap->drawable.id); + + vblank->pixmap = NULL; + vblank->idle_fence = NULL; + vblank->flip = FALSE; +} + +void +present_vblank_destroy(present_vblank_ptr vblank) +{ + /* Remove vblank from window and screen lists */ + xorg_list_del(&vblank->window_list); + + DebugPresent(("\td %lld %p %8lld: %08lx -> %08lx\n", + vblank->event_id, vblank, vblank->target_msc, + vblank->pixmap ? vblank->pixmap->drawable.id : 0, + vblank->window ? vblank->window->drawable.id : 0)); + + /* Drop pixmap reference */ + if (vblank->pixmap) + dixDestroyPixmap(vblank->pixmap, vblank->pixmap->drawable.id); + + /* Free regions */ + if (vblank->valid) + RegionDestroy(vblank->valid); + if (vblank->update) + RegionDestroy(vblank->update); + + if (vblank->wait_fence) + present_fence_destroy(vblank->wait_fence); + + if (vblank->idle_fence) + present_fence_destroy(vblank->idle_fence); + + if (vblank->notifies) + present_destroy_notifies(vblank->notifies, vblank->num_notifies); + + free(vblank); +} |