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....@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 *



_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to