On Fri, 2009-01-30 at 13:32 -0800, Eric Anholt wrote:
> This is about a 5% win from doing two glViewport()s per frame in openarena.

We talked about this in IRC on Friday.  I'm okay with the code changes.
I think they do the right thing.  I would like to see some documentation
in the code around needsGetBuffers explaining what's going one.  I'm at
least somewhat familiar with how this stuff works, and it took quite a
bit of time for you to explain it to me.

Reviewed-by: Ian Romanick <[email protected]>

> ---
>  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;
> +    }
>  }
>  
> 

Attachment: signature.asc
Description: This is a digitally signed message part

------------------------------------------------------------------------------
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