This is about a 5% win from doing two glViewport()s per frame in openarena.
---
 include/GL/internal/dri_interface.h        |    8 +++++-
 src/glx/x11/dri2_glx.c                     |   41 ++++++++++++++++++++++++++++
 src/glx/x11/glxclient.h                    |    1 +
 src/mesa/drivers/dri/intel/intel_context.c |   36 +++++++++++++++++-------
 4 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/include/GL/internal/dri_interface.h 
b/include/GL/internal/dri_interface.h
index 27cc1be..0ac03b5 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -636,7 +636,7 @@ struct __DRIbufferRec {
 };
 
 #define __DRI_DRI2_LOADER "DRI_DRI2Loader"
-#define __DRI_DRI2_LOADER_VERSION 1
+#define __DRI_DRI2_LOADER_VERSION 2
 struct __DRIdri2LoaderExtensionRec {
     __DRIextension base;
 
@@ -644,6 +644,12 @@ struct __DRIdri2LoaderExtensionRec {
                               int *width, int *height,
                               unsigned int *attachments, int count,
                               int *out_count, void *loaderPrivate);
+    /**
+     * Optional extension, returns whether getBuffers needs to be called
+     * due to window system events.
+     */
+    GLboolean (*needsGetBuffers)(__DRIdrawable *drawable,
+                                void *loaderPrivate);
 };
 
 /**
diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c
index d16f809..6c36121 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);
 
@@ -249,9 +254,27 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
     return pdraw->buffers;
 }
 
+static GLboolean dri2NeedsGetBuffers(__DRIdrawable *drawable,
+                                    void *loaderPrivate)
+{
+    __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
+    __GLXdisplayPrivate *dpyPriv = __glXInitialize(pdraw->base.psc->dpy);
+    __GLXDRIdisplayPrivate *pdp;
+
+    pdp = (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;
+
+    if (pdraw->configureSeqno != pdp->configureSeqno) {
+       pdraw->configureSeqno = pdp->configureSeqno;
+       return GL_TRUE;
+    }
+
+    return GL_FALSE;
+}
+
 static const __DRIdri2LoaderExtension dri2LoaderExtension = {
     { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
     dri2GetBuffers,
+    dri2NeedsGetBuffers,
 };
 
 static const __DRIextension *loader_extensions[] = {
@@ -365,6 +388,21 @@ static void dri2DestroyDisplay(__GLXDRIdisplay *dpy)
     Xfree(dpy);
 }
 
+static Bool dri2ConfigureNotifyProc(Display *dpy, XEvent *re, xEvent *event)
+{
+    __GLXdisplayPrivate *dpyPriv = __glXInitialize(dpy);
+    __GLXDRIdisplayPrivate *pdp;
+    Bool ret;
+
+    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 +425,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*);
 
 /************************************************************************/
diff --git a/src/mesa/drivers/dri/intel/intel_context.c 
b/src/mesa/drivers/dri/intel/intel_context.c
index 0d9487b..06360e5 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -296,20 +296,36 @@ intel_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei 
w, GLsizei h)
     __DRIcontext *driContext = intel->driContext;
     void (*old_viewport)(GLcontext *ctx, GLint x, GLint y,
                         GLsizei w, GLsizei h);
+    GLboolean updated = GL_FALSE;
+    __DRIdri2LoaderExtension *dri2loader = 
driContext->driScreenPriv->dri2.loader;
 
     if (!driContext->driScreenPriv->dri2.enabled)
        return;
 
-    intel_update_renderbuffers(driContext, driContext->driDrawablePriv);
-    if (driContext->driDrawablePriv != driContext->driReadablePriv)
-       intel_update_renderbuffers(driContext, driContext->driReadablePriv);
+    if (dri2loader->base.version < 2 ||
+       dri2loader->needsGetBuffers == NULL ||
+       dri2loader->needsGetBuffers(driContext->driDrawablePriv,
+                                   
driContext->driDrawablePriv->loaderPrivate)) {
+       updated = GL_TRUE;
+       intel_update_renderbuffers(driContext, driContext->driDrawablePriv);
+    }
+    if (driContext->driDrawablePriv != driContext->driReadablePriv &&
+       (dri2loader->base.version < 2 ||
+        dri2loader->needsGetBuffers == NULL ||
+        dri2loader->needsGetBuffers(driContext->driReadablePriv,
+                                    
driContext->driReadablePriv->loaderPrivate))) {
+       intel_update_renderbuffers(driContext, driContext->driReadablePriv);
+       updated = GL_TRUE;
+    }
 
-    old_viewport = ctx->Driver.Viewport;
-    ctx->Driver.Viewport = NULL;
-    intel->driDrawable = driContext->driDrawablePriv;
-    intelWindowMoved(intel);
-    intel_draw_buffer(ctx, intel->ctx.DrawBuffer);
-    ctx->Driver.Viewport = old_viewport;
+    if (updated) {
+       old_viewport = ctx->Driver.Viewport;
+       ctx->Driver.Viewport = NULL;
+       intel->driDrawable = driContext->driDrawablePriv;
+       intelWindowMoved(intel);
+       intel_draw_buffer(ctx, intel->ctx.DrawBuffer);
+       ctx->Driver.Viewport = old_viewport;
+    }
 }
 
 
-- 
1.5.6.5


------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
Mesa3d-dev mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to