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 <subd...@gmail.com> --- present/Makefile.am | 3 +- present/meson.build | 1 + present/present_priv.h | 44 ++++++++++- present/present_scmd.c | 153 ++++-------------------------------- present/present_vblank.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 258 insertions(+), 140 deletions(-) create mode 100644 present/present_vblank.c diff --git a/present/Makefile.am b/present/Makefile.am index 3b458fd..3d3d38d 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 bbe0de5..801e810 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 738c8aa..077a823 100644 --- a/present/present_priv.h +++ b/present/present_priv.h @@ -176,6 +176,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 @@ -325,9 +336,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 @@ -352,4 +360,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 f40e5ab..86b2508 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 */ @@ -171,22 +160,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) { @@ -800,79 +773,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; - - 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)) - { - 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)) - { - vblank->flip = TRUE; - } - } - - 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)) { @@ -886,12 +806,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 @@ -957,39 +871,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 0000000..0f1c3e6 --- /dev/null +++ b/present/present_vblank.c @@ -0,0 +1,197 @@ +/* + * 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; + + 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; + + 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)) + { + 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)) + { + vblank->flip = TRUE; + } + } + + 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); +} -- 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