[Mesa-dev] [PATCH] glx/dri3: Implement LIBGL_SHOW_FPS=1 for DRI3/Present.

Kenneth Graunke kenneth at whitecape.org
Wed Oct 29 01:23:38 PDT 2014


v2: Use the UST value provided in the PRESENT_COMPLETE_NOTIFY event
    rather than gettimeofday(), which gives us the presentation time
    instead of the time when SwapBuffers was called.  Suggested by
    Keith Packard.  This relies on the fact that the X Present
    implementation uses microseconds for UST.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
Cc: Keith Packard <keithp at keithp.com>
Cc: Marek Olšák <marek.olsak at amd.com>
---
 src/glx/dri3_glx.c  | 33 ++++++++++++++++++++++++++++++++-
 src/glx/dri3_priv.h |  6 +++++-
 2 files changed, 37 insertions(+), 2 deletions(-)

Is this what you had in mind, Keith?  It seems to work fine as well,
and as long as we can rely on UST being in microseconds, it definitely
seems nicer.

diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index e8e5c4a..ff9c2f3 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -361,12 +361,34 @@ dri3_create_drawable(struct glx_screen *base, XID xDrawable,
    return &pdraw->base;
 }
 
+static void
+show_fps(struct dri3_drawable *draw)
+{
+   const int interval =
+      ((struct dri3_screen *) draw->base.psc)->show_fps_interval;
+
+   draw->frames++;
+
+   /* The Present extension uses microseconds for UST. */
+   if (draw->previous_ust + interval * 1000000 <= draw->ust) {
+      if (draw->previous_ust) {
+         fprintf(stderr, "libGL: FPS = %.1f\n",
+                 ((uint64_t)draw->frames * 1000000) /
+                 (double)(draw->ust - draw->previous_ust));
+      }
+      draw->frames = 0;
+      draw->previous_ust = draw->ust;
+   }
+}
+
 /*
  * Process one Present event
  */
 static void
 dri3_handle_present_event(struct dri3_drawable *priv, xcb_present_generic_event_t *ge)
 {
+   struct dri3_screen *psc = (struct dri3_screen *) priv->base.psc;
+
    switch (ge->evtype) {
    case XCB_PRESENT_CONFIGURE_NOTIFY: {
       xcb_present_configure_notify_event_t *ce = (void *) ge;
@@ -400,6 +422,10 @@ dri3_handle_present_event(struct dri3_drawable *priv, xcb_present_generic_event_
       }
       priv->ust = ce->ust;
       priv->msc = ce->msc;
+
+      if (psc->show_fps_interval) {
+         show_fps(priv);
+      }
       break;
    }
    case XCB_PRESENT_EVENT_IDLE_NOTIFY: {
@@ -1830,7 +1856,7 @@ dri3_create_screen(int screen, struct glx_display * priv)
    struct dri3_screen *psc;
    __GLXDRIscreen *psp;
    struct glx_config *configs = NULL, *visuals = NULL;
-   char *driverName, *deviceName;
+   char *driverName, *deviceName, *tmp;
    int i;
 
    psc = calloc(1, sizeof *psc);
@@ -1969,6 +1995,11 @@ dri3_create_screen(int screen, struct glx_display * priv)
    free(driverName);
    free(deviceName);
 
+   tmp = getenv("LIBGL_SHOW_FPS");
+   psc->show_fps_interval = tmp ? atoi(tmp) : 0;
+   if (psc->show_fps_interval < 0)
+      psc->show_fps_interval = 0;
+
    return &psc->base;
 
 handle_error:
diff --git a/src/glx/dri3_priv.h b/src/glx/dri3_priv.h
index bdfe224..8e46640 100644
--- a/src/glx/dri3_priv.h
+++ b/src/glx/dri3_priv.h
@@ -138,7 +138,7 @@ struct dri3_screen {
    int fd;
    int is_different_gpu;
 
-   Bool show_fps;
+   int show_fps_interval;
 };
 
 struct dri3_context
@@ -198,6 +198,10 @@ struct dri3_drawable {
    xcb_present_event_t eid;
    xcb_gcontext_t gc;
    xcb_special_event_t *special_event;
+
+   /* LIBGL_SHOW_FPS support */
+   uint64_t previous_ust;
+   unsigned frames;
 };
 
 
-- 
2.1.2



More information about the mesa-dev mailing list