[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, &current_crtc, &current_ust, &current_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