[PATCH 4/6] present: Create an internal server API to perform operations at vblank time
Mark Marshall
markmarshall14 at gmail.com
Thu Aug 7 00:04:09 PDT 2014
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 <keithp at keithp.com> 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 <keithp at keithp.com>
> ---
> 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
>
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel
More information about the xorg-devel
mailing list