[Mesa-dev] [PATCH 13/14] vl/dri3: implement functions for get and set timestamp
Leo Liu
leo.liu at amd.com
Wed May 11 21:08:33 UTC 2016
On 05/11/2016 04:16 PM, Axel Davy wrote:
> Hi,
>
> The present extension has something exactly to set the target ust for
> the presentation: PresentOptionUST
>
> Unfortunately, while it is in the spec it looks like the option is
> totally ignored, and thus it will be totally buggy (you are supposed
> to pass ust instead of msc...).
Exactly. using ust instead of msc just except the first frame, will
answer further with next question.
>
> However PresentNotifyMSC should work well (assuming recent enough
> Xserver) and give you the current screen ust (and msc).
>
> I see you use it when last_ust hasn't been filled already. But why
> not using it all the time ?
The player call get timestamp before rendering and presentation, so for
the first frame we have to use msc instead,
and later we all use ust.
> Do some apps assume it's the ust of the last presented buffer ? The
> doc of the vdpau function doesn't
> seem to tell you should assume that.
>
> Could you add a comment to explain your next_msc calculation ?
>
Player calculate time stamp based on get time and vsync, and pass by, we
calculate the next msc based on this , last msc and time of vsync.
Basically this and using ust(msc for the first frame) are the exact same
idea based on existing vl/dri, which is working well for different players.
Thanks,
Leo
> Axel
>
> On 11/05/2016 17:06, Leo Liu wrote:
>> Signed-off-by: Leo Liu <leo.liu at amd.com>
>> ---
>> src/gallium/auxiliary/vl/vl_winsys_dri3.c | 59
>> +++++++++++++++++++++++++++----
>> 1 file changed, 53 insertions(+), 6 deletions(-)
>>
>> diff --git a/src/gallium/auxiliary/vl/vl_winsys_dri3.c
>> b/src/gallium/auxiliary/vl/vl_winsys_dri3.c
>> index f917e4b..d8e8319 100644
>> --- a/src/gallium/auxiliary/vl/vl_winsys_dri3.c
>> +++ b/src/gallium/auxiliary/vl/vl_winsys_dri3.c
>> @@ -79,6 +79,8 @@ struct vl_dri3_screen
>> uint32_t send_msc_serial, recv_msc_serial;
>> uint64_t send_sbc, recv_sbc;
>> int64_t last_ust, ns_frame, last_msc, next_msc;
>> +
>> + bool flushed;
>> };
>> static void
>> @@ -467,19 +469,30 @@ vl_dri3_flush_frontbuffer(struct pipe_screen
>> *screen,
>> if (!back)
>> return;
>> + if (scrn->flushed) {
>> + while (scrn->special_event && scrn->recv_sbc < scrn->send_sbc)
>> + if (!dri3_wait_present_events(scrn))
>> + return;
>> + }
>> +
>> xshmfence_reset(back->shm_fence);
>> back->busy = true;
>> xcb_present_pixmap(scrn->conn,
>> scrn->drawable,
>> back->pixmap,
>> - 0, 0, 0, 0, 0,
>> + (uint32_t)(++scrn->send_sbc),
>> + 0, 0, 0, 0,
>> None, None,
>> back->sync_fence,
>> - options, 0, 0, 0, 0, NULL);
>> + options,
>> + scrn->next_msc,
>> + 0, 0, 0, NULL);
>> xcb_flush(scrn->conn);
>> + scrn->flushed = true;
>> +
>> return;
>> }
>> @@ -494,6 +507,13 @@ vl_dri3_screen_texture_from_drawable(struct
>> vl_screen *vscreen, void *drawable)
>> if (!dri3_set_drawable(scrn, (Drawable)drawable))
>> return NULL;
>> + if (scrn->flushed) {
>> + while (scrn->special_event && scrn->recv_sbc < scrn->send_sbc)
>> + if (!dri3_wait_present_events(scrn))
>> + return NULL;
>> + }
>> + scrn->flushed = false;
>> +
>> buffer = (scrn->is_pixmap) ?
>> dri3_get_front_buffer(scrn) :
>> dri3_get_back_buffer(scrn);
>> @@ -516,15 +536,42 @@ vl_dri3_screen_get_dirty_area(struct vl_screen
>> *vscreen)
>> static uint64_t
>> vl_dri3_screen_get_timestamp(struct vl_screen *vscreen, void
>> *drawable)
>> {
>> - /* TODO */
>> - return 0;
>> + struct vl_dri3_screen *scrn = (struct vl_dri3_screen *)vscreen;
>> +
>> + assert(scrn);
>> +
>> + if (!dri3_set_drawable(scrn, (Drawable)drawable))
>> + return 0;
>> +
>> + if (!scrn->last_ust) {
>> + xcb_present_notify_msc(scrn->conn,
>> + scrn->drawable,
>> + ++scrn->send_msc_serial,
>> + 0, 0, 0);
>> + xcb_flush(scrn->conn);
>> +
>> + while (scrn->special_event &&
>> + scrn->send_msc_serial > scrn->recv_msc_serial) {
>> + if (!dri3_wait_present_events(scrn))
>> + return 0;
>> + }
>> + }
>> +
>> + return scrn->last_ust;
>> }
>> static void
>> vl_dri3_screen_set_next_timestamp(struct vl_screen *vscreen,
>> uint64_t stamp)
>> {
>> - /* TODO */
>> - return;
>> + struct vl_dri3_screen *scrn = (struct vl_dri3_screen *)vscreen;
>> +
>> + assert(scrn);
>> +
>> + if (stamp && scrn->last_ust && scrn->ns_frame && scrn->last_msc)
>> + scrn->next_msc = ((int64_t)stamp - scrn->last_ust +
>> scrn->ns_frame/2) /
>> + scrn->ns_frame + scrn->last_msc;
>> + else
>> + scrn->next_msc = 0;
>> }
>> static void *
>
>
More information about the mesa-dev
mailing list