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 <kenn...@whitecape.org> Cc: Keith Packard <kei...@keithp.com> Cc: Marek Olšák <marek.ol...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev