Mesa (master): dri2: Avoid round-tripping on DRI2GetBuffers for the same set of buffers.

Eric Anholt anholt at kemper.freedesktop.org
Mon Feb 2 15:35:04 PST 2009


Module: Mesa
Branch: master
Commit: dd1c68f15123a889a3ce9d2afe724e272d163e32
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=dd1c68f15123a889a3ce9d2afe724e272d163e32

Author: Eric Anholt <eric at anholt.net>
Date:   Fri Jan 30 13:23:12 2009 -0800

dri2: Avoid round-tripping on DRI2GetBuffers for the same set of buffers.

We only wanted to request when asked for the same set of buffers when a resize
has happened.  We can just watch the protocol stream for a ConfigureNotify
and flag to do it then.

This is about a 5% win from doing two glViewport()s per frame in openarena.

---

 src/glx/x11/dri2_glx.c  |   52 +++++++++++++++++++++++++++++++++++++++++++++++
 src/glx/x11/glxclient.h |    1 +
 2 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c
index d16f809..41861d5 100644
--- a/src/glx/x11/dri2_glx.c
+++ b/src/glx/x11/dri2_glx.c
@@ -60,6 +60,9 @@ struct __GLXDRIdisplayPrivateRec {
     int driMajor;
     int driMinor;
     int driPatch;
+
+    unsigned long configureSeqno;
+    Bool (*oldConfigProc)(Display *, XEvent *, xEvent *);
 };
 
 struct __GLXDRIcontextPrivateRec {
@@ -73,6 +76,7 @@ struct __GLXDRIdrawablePrivateRec {
     __DRIbuffer buffers[5];
     int bufferCount;
     int width, height;
+    unsigned long configureSeqno;
 };
 
 static void dri2DestroyContext(__GLXDRIcontext *context,
@@ -166,6 +170,7 @@ static __GLXDRIdrawable *dri2CreateDrawable(__GLXscreenConfigs *psc,
     pdraw->base.xDrawable = xDrawable;
     pdraw->base.drawable = drawable;
     pdraw->base.psc = psc;
+    pdraw->configureSeqno = ~0;
 
     DRI2CreateDrawable(psc->dpy, xDrawable);
 
@@ -223,9 +228,30 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
 	       int *out_count, void *loaderPrivate)
 {
     __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
+    __GLXdisplayPrivate *dpyPriv = __glXInitialize(pdraw->base.psc->dpy);
+    __GLXDRIdisplayPrivate *pdp = (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;
     DRI2Buffer *buffers;
     int i;
 
+    /**
+     * Check if a ConfigureNotify has come in since we last asked for the
+     * buffers associated with this drawable.  If not, we can assume that they're
+     * the same set at glViewport time, and save a synchronous round-trip to the
+     * X Server.
+     */
+    if (pdraw->configureSeqno == pdp->configureSeqno &&
+	count == pdraw->bufferCount) {
+	for (i = 0; i < count; i++) {
+	    if (pdraw->buffers[i].attachment != attachments[i])
+		break;
+	}
+	if (i == count) {
+	    *out_count = pdraw->bufferCount;
+	    return pdraw->buffers;
+	}
+    }
+    pdraw->configureSeqno = pdp->configureSeqno;
+
     buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
 			     width, height, attachments, count, out_count);
     if (buffers == NULL)
@@ -233,6 +259,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
 
     pdraw->width = *width;
     pdraw->height = *height;
+    pdraw->bufferCount = *out_count;
 
     /* This assumes the DRI2 buffer attachment tokens matches the
      * __DRIbuffer tokens. */
@@ -365,6 +392,28 @@ static void dri2DestroyDisplay(__GLXDRIdisplay *dpy)
     Xfree(dpy);
 }
 
+/**
+ * Makes a note on receiving ConfigureNotify that we need to re-check the
+ * DRI2 buffers, as window sizes may have resulted in reallocation.
+ */
+static Bool dri2ConfigureNotifyProc(Display *dpy, XEvent *re, xEvent *event)
+{
+    __GLXdisplayPrivate *dpyPriv = __glXInitialize(dpy);
+    __GLXDRIdisplayPrivate *pdp;
+    Bool ret;
+
+    /* We should always be able to find our pdp, as it only gets torn down
+     * when the Display is torn down.
+     */
+    pdp = (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;
+
+    ret = pdp->oldConfigProc(dpy, re, event);
+
+    pdp->configureSeqno = re->xconfigure.serial;
+
+    return ret;
+}
+
 /*
  * Allocate, initialize and return a __DRIdisplayPrivate object.
  * This is called from __glXInitialize() when we are given a new
@@ -387,6 +436,9 @@ _X_HIDDEN __GLXDRIdisplay *dri2CreateDisplay(Display *dpy)
 	return NULL;
     }
 
+    pdp->oldConfigProc = XESetWireToEvent(dpy, ConfigureNotify,
+					  dri2ConfigureNotifyProc);
+
     pdp->driPatch = 0;
 
     pdp->base.destroyDisplay = dri2DestroyDisplay;
diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h
index 16f6074..bdc6287 100644
--- a/src/glx/x11/glxclient.h
+++ b/src/glx/x11/glxclient.h
@@ -602,6 +602,7 @@ extern void __glXSendLargeCommand(__GLXcontext *, const GLvoid *, GLint,
 				  const GLvoid *, GLint);
 
 /* Initialize the GLX extension for dpy */
+extern __GLXdisplayPrivate * __glXGetPrivateFromDisplay(Display *dpy);
 extern __GLXdisplayPrivate *__glXInitialize(Display*);
 
 /************************************************************************/



More information about the mesa-commit mailing list