[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