Hi. present_vblank_screen_close doesn't seem to get called from anywhere? Is there some magic that I am missing?
Regards, Mark. On 7 August 2014 07:21, Keith Packard <[email protected]> wrote: > present_vblank_window_queue asks for a callback function to be invoked > when a specific (absolute or relative) frame starts. This allows for > vblank-synchronized rendering operations without needing > driver-specific hooks. > > Signed-off-by: Keith Packard <[email protected]> > --- > present/Makefile.am | 5 +- > present/present.c | 14 ++-- > present/present_priv.h | 27 +++++++ > present/present_screen.c | 2 + > present/present_vblank.c | 192 > +++++++++++++++++++++++++++++++++++++++++++++++ > present/present_vblank.h | 68 +++++++++++++++++ > 6 files changed, 300 insertions(+), 8 deletions(-) > create mode 100644 present/present_vblank.c > create mode 100644 present/present_vblank.h > > diff --git a/present/Makefile.am b/present/Makefile.am > index 7fea669..64c8be4 100644 > --- a/present/Makefile.am > +++ b/present/Makefile.am > @@ -12,6 +12,7 @@ libpresent_la_SOURCES = \ > present_notify.c \ > present_priv.h \ > present_request.c \ > - present_screen.c > + present_screen.c \ > + present_vblank.c > > -sdk_HEADERS = present.h presentext.h > +sdk_HEADERS = present.h presentext.h present_vblank.h > diff --git a/present/present.c b/present/present.c > index af98ef7..744cb99 100644 > --- a/present/present.c > +++ b/present/present.c > @@ -32,7 +32,7 @@ > #include <time.h> > #endif > > -static uint64_t present_event_id; > +uint64_t present_event_id; > static struct xorg_list present_exec_queue; > static struct xorg_list present_flip_queue; > > @@ -85,7 +85,7 @@ present_flip_pending_pixmap(ScreenPtr screen) > > if (!screen_priv->flip_pending) > return NULL; > - > + > return screen_priv->flip_pending->pixmap; > } > > @@ -235,7 +235,7 @@ present_query_capabilities(RRCrtcPtr crtc) > return screen_priv->info->capabilities; > } > > -static int > +int > present_get_ust_msc(ScreenPtr screen, RRCrtcPtr crtc, uint64_t *ust, > uint64_t *msc) > { > present_screen_priv_ptr screen_priv = present_screen_priv(screen); > @@ -261,7 +261,7 @@ present_flush(WindowPtr window) > (*screen_priv->info->flush) (window); > } > > -static int > +int > present_queue_vblank(ScreenPtr screen, > RRCrtcPtr crtc, > uint64_t event_id, > @@ -279,7 +279,7 @@ present_queue_vblank(ScreenPtr screen, > return ret; > } > > -static uint64_t > +uint64_t > present_window_to_crtc_msc(WindowPtr window, RRCrtcPtr crtc, uint64_t > window_msc, uint64_t new_msc) > { > present_window_priv_ptr window_priv = > present_get_window_priv(window, TRUE); > @@ -368,7 +368,7 @@ present_set_tree_pixmap_visit(WindowPtr window, void > *data) > (*screen->SetWindowPixmap)(window, visit->new); > return WT_WALKCHILDREN; > } > - > + > static void > present_set_tree_pixmap(WindowPtr window, PixmapPtr pixmap) > { > @@ -499,6 +499,8 @@ present_event_notify(uint64_t event_id, uint64_t ust, > uint64_t msc) > return; > } > } > + > + present_vblank_event_notify(event_id, ust, msc); > } > > void > diff --git a/present/present_priv.h b/present/present_priv.h > index 1542726..a409e97 100644 > --- a/present/present_priv.h > +++ b/present/present_priv.h > @@ -37,6 +37,8 @@ > > extern int present_request; > > +extern uint64_t present_event_id; > + > extern DevPrivateKeyRec present_screen_private_key; > > typedef struct present_fence *present_fence_ptr; > @@ -158,6 +160,18 @@ extern RESTYPE present_event_type; > /* > * present.c > */ > +uint64_t > +present_window_to_crtc_msc(WindowPtr window, RRCrtcPtr crtc, uint64_t > window_msc, uint64_t new_msc); > + > +int > +present_get_ust_msc(ScreenPtr screen, RRCrtcPtr crtc, uint64_t *ust, > uint64_t *msc); > + > +int > +present_queue_vblank(ScreenPtr screen, > + RRCrtcPtr crtc, > + uint64_t event_id, > + uint64_t msc); > + > int > present_pixmap(WindowPtr window, > PixmapPtr pixmap, > @@ -308,4 +322,17 @@ sproc_present_dispatch(ClientPtr client); > * present_screen.c > */ > > +/* > + * present_vblank.c > + */ > + > +void > +present_vblank_event_notify(uint64_t event_id, uint64_t msc, uint64_t utc); > + > +void > +present_vblank_screen_init(ScreenPtr screen); > + > +void > +present_vblank_screen_close(ScreenPtr screen); > + > #endif /* _PRESENT_PRIV_H_ */ > diff --git a/present/present_screen.c b/present/present_screen.c > index 2f91ac7..bfffae9 100644 > --- a/present/present_screen.c > +++ b/present/present_screen.c > @@ -195,6 +195,8 @@ present_screen_init(ScreenPtr screen, > present_screen_info_ptr info) > present_fake_screen_init(screen); > } > > + present_vblank_screen_init(screen); > + > return TRUE; > } > > diff --git a/present/present_vblank.c b/present/present_vblank.c > new file mode 100644 > index 0000000..deebade > --- /dev/null > +++ b/present/present_vblank.c > @@ -0,0 +1,192 @@ > +/* > + * Copyright © 2014 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" > +#include "present_vblank.h" > + > +typedef struct { > + struct xorg_list list; > + uint64_t event_id; > + WindowPtr window; > + uint64_t msc_offset; > + present_vblank_window_callback callback; > + uint32_t flags; > + void *closure; > +} present_queue_t; > + > +static struct xorg_list present_queue; > + > +int > +present_vblank_window_get(WindowPtr window, > + RRCrtcPtr *crtc, > + uint64_t *ust, > + uint64_t *window_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); > + uint64_t msc_offset, crtc_msc; > + RRCrtcPtr target_crtc; > + > + if (!window_priv) > + return BadAlloc; > + > + if (!screen_priv || !screen_priv->info) > + target_crtc = NULL; > + else { > + target_crtc = window_priv->crtc; > + > + if (!target_crtc || target_crtc == PresentCrtcNeverSet) > + target_crtc = present_get_crtc(window); > + } > + > + present_get_ust_msc(screen, target_crtc, ust, &crtc_msc); > + > + msc_offset = present_window_to_crtc_msc(window, target_crtc, 0, > crtc_msc); > + > + *window_msc = crtc_msc - msc_offset; > + *crtc = window_priv->crtc; > + > + return Success; > +} > + > +uint64_t > +present_vblank_window_queue(WindowPtr window, > + enum present_whence whence, > + uint64_t window_msc, > + uint32_t flags, > + present_vblank_window_callback callback, > + void *closure) > +{ > + present_window_priv_ptr window_priv = > present_get_window_priv(window, TRUE); > + present_queue_t *q; > + RRCrtcPtr current_crtc; > + uint64_t current_ust, current_msc; > + uint64_t event_id; > + > + if (!window_priv) > + return PRESENT_VBLANK_QUEUE_FAILED; > + > + if (present_vblank_window_get(window, ¤t_crtc, ¤t_ust, > ¤t_msc) != Success) > + return PRESENT_VBLANK_QUEUE_FAILED; > + > + q = calloc(1, sizeof (present_queue_t)); > + if (!q) > + return PRESENT_VBLANK_QUEUE_FAILED; > + > + event_id = ++present_event_id; > + > + q->window = window; > + q->callback = callback; > + q->msc_offset = window_priv->msc_offset; > + > + if (whence == present_whence_relative) > + window_msc += current_msc; > + > + q->flags = flags; > + q->closure = closure; > + > + q->event_id = event_id; > + xorg_list_add(&q->list, &present_queue); > + > + if ((int64_t) (window_msc - current_msc) <= 0) { > + DebugPresent(("ve %lld %p %8lld (request %8lld)\n", > + (long long) event_id, q, > + (long long) current_msc, > + (long long) window_msc)); > + present_vblank_event_notify(event_id, current_ust, current_msc + > q->msc_offset); > + event_id = PRESENT_VBLANK_QUEUE_EXECUTED; > + } else { > + DebugPresent(("vq %lld %p %8lld (request %8lld)\n", > + (long long) event_id, q, > + (long long) current_msc, (long long) q->msc)); > + present_queue_vblank(window->drawable.pScreen, > + current_crtc, > + q->event_id, > + window_msc + q->msc_offset); > + } > + > + return event_id; > +} > + > +Bool > +present_vblank_cancel(ScreenPtr screen, uint64_t event_id) > +{ > + present_queue_t *q, *tmp; > + > + xorg_list_for_each_entry_safe(q, tmp, &present_queue, list) { > + if (q->event_id == event_id) { > + xorg_list_del(&q->list); > + /* could call the driver to cancel the event */ > + free(q); > + return TRUE; > + } > + } > + return FALSE; > +} > + > +static void > +present_queue_notify(present_queue_t *q, uint64_t ust, uint64_t crtc_msc) > +{ > + xorg_list_del(&q->list); > + (*q->callback)(q->window, q->closure, ust, crtc_msc - q->msc_offset); > + free(q); > +} > + > +static void > +present_queue_abort(present_queue_t *q) > +{ > + present_queue_notify(q, 0, q->msc_offset); > +} > + > +void > +present_vblank_event_notify(uint64_t event_id, uint64_t ust, uint64_t > crtc_msc) > +{ > + present_queue_t *q, *tmp; > + > + xorg_list_for_each_entry_safe(q, tmp, &present_queue, list) { > + if (q->event_id == event_id) { > + DebugPresent(("\tvn %8lld %p %8lld\n", > + (long long) q->event_id, q, (long long) msc)); > + present_queue_notify(q, ust, crtc_msc); > + } > + } > +} > + > +void > +present_vblank_screen_init(ScreenPtr screen) > +{ > + xorg_list_init(&present_queue); > +} > + > +void > +present_vblank_screen_close(ScreenPtr screen) > +{ > + present_queue_t *q, *tmp; > + > + xorg_list_for_each_entry_safe(q, tmp, &present_queue, list) > + present_queue_abort(q); > +} > diff --git a/present/present_vblank.h b/present/present_vblank.h > new file mode 100644 > index 0000000..4479014 > --- /dev/null > +++ b/present/present_vblank.h > @@ -0,0 +1,68 @@ > +/* > + * Copyright © 2014 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. > + */ > + > +#ifndef _PRESENT_VBLANK_H_ > +#define _PRESENT_VBLANK_H_ > + > +#include <X11/X.h> > +#include "scrnintstr.h" > +#include "misc.h" > +#include "list.h" > +#include "windowstr.h" > +#include "dixstruct.h" > +#include "present.h" > +#include <syncsdk.h> > +#include <syncsrv.h> > +#include <xfixes.h> > +#include <randrstr.h> > + > +enum present_whence { > + present_whence_absolute, > + present_whence_relative > +}; > + > +typedef void (*present_vblank_window_callback) (WindowPtr window, > + void *closure, > + uint64_t ust, > + uint64_t msc); > + > +extern _X_EXPORT int > +present_vblank_window_get(WindowPtr window, > + RRCrtcPtr *crtc, > + uint64_t *ust, > + uint64_t *msc); > + > +#define PRESENT_VBLANK_QUEUE_FAILED ((uint64_t) 0) > +#define PRESENT_VBLANK_QUEUE_EXECUTED ((uint64_t) -1) > + > +extern _X_EXPORT uint64_t > +present_vblank_window_queue(WindowPtr window, > + enum present_whence whence, > + uint64_t msc, > + uint32_t flags, > + present_vblank_window_callback callback, > + void *closure); > + > +extern _X_EXPORT Bool > +present_vblank_cancel(ScreenPtr screen, uint64_t id); > + > +#endif /* _PRESENT_VBLANK_H_ */ > -- > 2.0.1 > > _______________________________________________ > [email protected]: X.Org development > Archives: http://lists.x.org/archives/xorg-devel > Info: http://lists.x.org/mailman/listinfo/xorg-devel _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
