summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2014-03-14 18:53:42 -0700
committerKenneth Graunke <[email protected]>2014-10-29 15:13:58 -0700
commit26122e09a304061e46690e1b9da2e36a527b3e2e (patch)
tree2c22a14cb1dbcf5ebf733b41e6d462418a14fee3
parent62b07b934ecce1f370f3566ad3613341ff86aba1 (diff)
glx/dri3: Implement LIBGL_SHOW_FPS=1 for DRI3/Present.
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 DRI3/Present implementations use microseconds for UST. v3: Properly ignore PresentCompleteKindMSCNotify; multiply in 64 bits (caught by Keith Packard). Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Keith Packard <[email protected]> [v3] Reviewed-by: Marek Olšák <[email protected]> [v1]
-rw-r--r--src/glx/dri3_glx.c32
-rw-r--r--src/glx/dri3_priv.h6
2 files changed, 36 insertions, 2 deletions
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index e8e5c4ab28a..a9ff73b36f4 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, uint64_t current_ust)
+{
+ const uint64_t interval =
+ ((struct dri3_screen *) draw->base.psc)->show_fps_interval;
+
+ draw->frames++;
+
+ /* DRI3+Present together uses microseconds for UST. */
+ if (draw->previous_ust + interval * 1000000 <= current_ust) {
+ if (draw->previous_ust) {
+ fprintf(stderr, "libGL: FPS = %.1f\n",
+ ((uint64_t) draw->frames * 1000000) /
+ (double)(current_ust - draw->previous_ust));
+ }
+ draw->frames = 0;
+ draw->previous_ust = current_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;
@@ -395,6 +417,9 @@ dri3_handle_present_event(struct dri3_drawable *priv, xcb_present_generic_event_
break;
}
dri3_update_num_back(priv);
+
+ if (psc->show_fps_interval)
+ show_fps(priv, ce->ust);
} else {
priv->recv_msc_serial = ce->serial;
}
@@ -1830,7 +1855,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 +1994,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 bdfe224fed0..8e466407b89 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;
};