xserver: Branch 'server-1.6-branch' - 10 commits

Brice Goglin Brice.Goglin at ens-lyon.org
Wed Jun 24 04:34:57 PDT 2009


Hello Ian,

This backport breaks the ABI (somewhere between 4cb4c210 and 6be19e8f, I
couldn't finish the bisect). The server reproducibly freezes a couple
seconds after Gnome startup with Intel 2.7.99.901, KMS and 2.6.30 on
i945. Rebuildind the Intel driver against updated Xserver and DRI2 proto
fixes the problem.

Brice




Ian Romanick wrote:
>  configure.ac              |    2 
>  glx/glxdri2.c             |   82 +++++++++++++++--
>  hw/xfree86/dri2/dri2.c    |  217 ++++++++++++++++++++++++++++++++++++++++------
>  hw/xfree86/dri2/dri2.h    |   46 +++++++++
>  hw/xfree86/dri2/dri2ext.c |   96 ++++++++++++++++----
>  5 files changed, 387 insertions(+), 56 deletions(-)
>
> New commits:
> commit 6be19e8f43086fb4b7fb30a47b89b5f3eed798ef
> Author: Ian Romanick <ian.d.romanick at intel.com>
> Date:   Wed Apr 8 14:54:30 2009 -0700
>
>     Use a #define instead of a magic number
>     
>     The number of buffers is likely to change in the future, so having
>     this as a define is the right way to go.
>     
>     Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
>     (cherry picked from commit 03aebed519986c4dd03e02b3b3d4af1f64595ca7)
>
> diff --git a/glx/glxdri2.c b/glx/glxdri2.c
> index c671670..f2682d4 100644
> --- a/glx/glxdri2.c
> +++ b/glx/glxdri2.c
> @@ -82,6 +82,8 @@ struct __GLXDRIcontext {
>      __DRIcontext	*driContext;
>  };
>  
> +#define MAX_DRAWABLE_BUFFERS 5
> +
>  struct __GLXDRIdrawable {
>      __GLXdrawable	 base;
>      __DRIdrawable	*driDrawable;
> @@ -90,7 +92,7 @@ struct __GLXDRIdrawable {
>      /* Dimensions as last reported by DRI2GetBuffers. */
>      int width;
>      int height;
> -    __DRIbuffer buffers[5];
> +    __DRIbuffer buffers[MAX_DRAWABLE_BUFFERS];
>      int count;
>  };
>  
> @@ -365,7 +367,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
>  
>      buffers = DRI2GetBuffers(private->base.pDraw,
>  			     width, height, attachments, count, out_count);
> -    if (*out_count > 5) {
> +    if (*out_count > MAX_DRAWABLE_BUFFERS) {
>  	*out_count = 0;
>  	return NULL;
>      }
> commit 540d5b87a4e24d85ec46620dfedd7bd7979180ea
> Author: Jerome Glisse <glisse at freedesktop.org>
> Date:   Mon May 11 22:52:46 2009 +0200
>
>     DRI2: update DRI2 private drawable width & height according to X drawable
>     (cherry picked from commit f250eea2e90fc50bec5214c2f41132b95edc2c46)
>
> diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
> index 1d49d7c..385c5e8 100644
> --- a/hw/xfree86/dri2/dri2.c
> +++ b/hw/xfree86/dri2/dri2.c
> @@ -257,6 +257,8 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
>  
>      pPriv->buffers = buffers;
>      pPriv->bufferCount = *out_count;
> +    pPriv->width = pDraw->width;
> +    pPriv->height = pDraw->height;
>      *width = pPriv->width;
>      *height = pPriv->height;
>  
> commit ec9f1ae32474bc0507a3c66e63bdf2835d467a34
> Author: Ian Romanick <ian.d.romanick at intel.com>
> Date:   Mon Apr 27 15:11:10 2009 -0700
>
>     DRI2: Force allocation of real-front buffer for non-windows as well
>     
>     For redirected rendering we end up with pixmaps (which the app thinks are
>     windows) that are double buffered.
>     
>     Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
>     Tested-by: Pierre Willenbrock <pierre at pirsoft.de>
>     (cherry picked from commit 0d9d3f3e361f769822caedccf4c2a58cc9930ecc)
>
> diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
> index 9ded048..1d49d7c 100644
> --- a/hw/xfree86/dri2/dri2.c
> +++ b/hw/xfree86/dri2/dri2.c
> @@ -206,18 +206,21 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
>  	 * attachments.  The counting logic in the loop accounts for the case
>  	 * where the client requests both the fake and real front-buffer.
>  	 */
> -	if (pDraw->type == DRAWABLE_WINDOW) {
> -	    if (attachment == DRI2BufferBackLeft) {
> -		need_real_front++;
> -		front_format = format;
> -	    }
> +	if (attachment == DRI2BufferBackLeft) {
> +	    need_real_front++;
> +	    front_format = format;
> +	}
>  
> -	    if (attachment == DRI2BufferFrontLeft) {
> -		need_real_front--;
> +	if (attachment == DRI2BufferFrontLeft) {
> +	    need_real_front--;
> +	    front_format = format;
> +
> +	    if (pDraw->type == DRAWABLE_WINDOW) {
>  		need_fake_front++;
> -		front_format = format;
>  	    }
> +	}
>  
> +	if (pDraw->type == DRAWABLE_WINDOW) {
>  	    if (attachment == DRI2BufferFakeFrontLeft) {
>  		need_fake_front--;
>  		have_fake_front = 1;
> commit 4fad615d689c61c6c3a000295a1fa755359737cb
> Author: Ian Romanick <ian.d.romanick at intel.com>
> Date:   Fri Apr 24 12:49:19 2009 -0700
>
>     DRI2: Implement protocol for DRI2GetBuffersWithFormat
>     
>     This change implements the protocol for DRI2GetBuffersWithFormat, but
>     the bulk of the differences are the changes to the extension / driver
>     interface to make this function work.  The old CreateBuffers and
>     DeleteBuffers routines are replaced with CreateBuffer and DeleteBuffer
>     (both singular).
>     
>     This allows drivers to allocate buffers for a drawable one at a time.
>     As a result, 3D drivers can now allocate the (fake) front-buffer for a
>     window only when it is needed.  Since 3D drivers only ask for the
>     front-buffer on demand, the real front-buffer is always created.  This
>     allows CopyRegion impelemenations of SwapBuffers to continue working.
>     As with previous version of this code, if the client asks for the
>     front-buffer for a window, we instead give it the fake front-buffer.
>     
>     Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
>     Reviewed-by: Kristian Høgsberg <krh at redhat.com>
>
> diff --git a/configure.ac b/configure.ac
> index af4ba4f..1f0fddd 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -859,7 +859,7 @@ if test "x$DRI" = xyes; then
>  	AC_SUBST(GL_CFLAGS)
>  fi
>  
> -PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 1.99.3],
> +PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 2.1],
>                    [HAVE_DRI2PROTO=yes], [HAVE_DRI2PROTO=no])
>  case "$DRI2,$HAVE_DRI2PROTO" in
>  	yes,no)
> diff --git a/glx/glxdri2.c b/glx/glxdri2.c
> index 84d2c03..c671670 100644
> --- a/glx/glxdri2.c
> +++ b/glx/glxdri2.c
> @@ -359,7 +359,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
>  	       int *out_count, void *loaderPrivate)
>  {
>      __GLXDRIdrawable *private = loaderPrivate;
> -    DRI2BufferPtr buffers;
> +    DRI2BufferPtr *buffers;
>      int i;
>      int j;
>  
> @@ -380,15 +380,59 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
>  	/* Do not send the real front buffer of a window to the client.
>  	 */
>  	if ((private->base.pDraw->type == DRAWABLE_WINDOW)
> -	    && (buffers[i].attachment == DRI2BufferFrontLeft)) {
> +	    && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
>  	    continue;
>  	}
>  
> -	private->buffers[j].attachment = buffers[i].attachment;
> -	private->buffers[j].name = buffers[i].name;
> -	private->buffers[j].pitch = buffers[i].pitch;
> -	private->buffers[j].cpp = buffers[i].cpp;
> -	private->buffers[j].flags = buffers[i].flags;
> +	private->buffers[j].attachment = buffers[i]->attachment;
> +	private->buffers[j].name = buffers[i]->name;
> +	private->buffers[j].pitch = buffers[i]->pitch;
> +	private->buffers[j].cpp = buffers[i]->cpp;
> +	private->buffers[j].flags = buffers[i]->flags;
> +	j++;
> +    }
> +
> +    *out_count = j;
> +    return private->buffers;
> +}
> +
> +static __DRIbuffer *
> +dri2GetBuffersWithFormat(__DRIdrawable *driDrawable,
> +			 int *width, int *height,
> +			 unsigned int *attachments, int count,
> +			 int *out_count, void *loaderPrivate)
> +{
> +    __GLXDRIdrawable *private = loaderPrivate;
> +    DRI2BufferPtr *buffers;
> +    int i;
> +    int j = 0;
> +
> +    buffers = DRI2GetBuffersWithFormat(private->base.pDraw,
> +				       width, height, attachments, count,
> +				       out_count);
> +    if (*out_count > MAX_DRAWABLE_BUFFERS) {
> +	*out_count = 0;
> +	return NULL;
> +    }
> +
> +    private->width = *width;
> +    private->height = *height;
> +
> +    /* This assumes the DRI2 buffer attachment tokens matches the
> +     * __DRIbuffer tokens. */
> +    for (i = 0; i < *out_count; i++) {
> +	/* Do not send the real front buffer of a window to the client.
> +	 */
> +	if ((private->base.pDraw->type == DRAWABLE_WINDOW)
> +	    && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
> +	    continue;
> +	}
> +
> +	private->buffers[j].attachment = buffers[i]->attachment;
> +	private->buffers[j].name = buffers[i]->name;
> +	private->buffers[j].pitch = buffers[i]->pitch;
> +	private->buffers[j].cpp = buffers[i]->cpp;
> +	private->buffers[j].flags = buffers[i]->flags;
>  	j++;
>      }
>  
> @@ -407,6 +451,7 @@ static const __DRIdri2LoaderExtension loaderExtension = {
>      { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
>      dri2GetBuffers,
>      dri2FlushFrontBuffer,
> +    dri2GetBuffersWithFormat,
>  };
>  
>  static const __DRIextension *loader_extensions[] = {
> diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
> index 80de18f..9ded048 100644
> --- a/hw/xfree86/dri2/dri2.c
> +++ b/hw/xfree86/dri2/dri2.c
> @@ -53,7 +53,7 @@ typedef struct _DRI2Drawable {
>      unsigned int	 refCount;
>      int			 width;
>      int			 height;
> -    DRI2BufferPtr	 buffers;
> +    DRI2BufferPtr	*buffers;
>      int			 bufferCount;
>      unsigned int	 pendingSequence;
>  } DRI2DrawableRec, *DRI2DrawablePtr;
> @@ -63,8 +63,8 @@ typedef struct _DRI2Screen {
>      const char			*deviceName;
>      int				 fd;
>      unsigned int		 lastSequence;
> -    DRI2CreateBuffersProcPtr	 CreateBuffers;
> -    DRI2DestroyBuffersProcPtr	 DestroyBuffers;
> +    DRI2CreateBufferProcPtr	 CreateBuffer;
> +    DRI2DestroyBufferProcPtr	 DestroyBuffer;
>      DRI2CopyRegionProcPtr	 CopyRegion;
>  
>      HandleExposuresProcPtr       HandleExposures;
> @@ -132,71 +132,130 @@ DRI2CreateDrawable(DrawablePtr pDraw)
>      return Success;
>  }
>  
> -DRI2BufferPtr
> -DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
> -	       unsigned int *attachments, int count, int *out_count)
> +static int
> +find_attachment(DRI2BufferPtr *buffer_list, int count, unsigned attachment)
> +{
> +    int i;
> +
> +    if (buffer_list == NULL) {
> +	return -1;
> +    }
> +
> +    for (i = 0; i < count; i++) {
> +	if ((buffer_list[i] != NULL)
> +	    && (buffer_list[i]->attachment == attachment)) {
> +	    return i;
> +	}
> +    }
> +
> +    return -1;
> +}
> +
> +static DRI2BufferPtr
> +allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
> +			 DRI2DrawablePtr pPriv,
> +			 unsigned int attachment, unsigned int format,
> +			 int dimensions_match)
> +{
> +    DRI2BufferPtr buffer;
> +    int old_buf;
> +
> +    old_buf = find_attachment(pPriv->buffers, pPriv->bufferCount, attachment);
> +
> +    if ((old_buf < 0)
> +	|| !dimensions_match
> +	|| (pPriv->buffers[old_buf]->format != format)) {
> +	buffer = (*ds->CreateBuffer)(pDraw, attachment, format);
> +    } else {
> +	buffer = pPriv->buffers[old_buf];
> +	pPriv->buffers[old_buf] = NULL;
> +    }
> +
> +    return buffer;
> +}
> +
> +static DRI2BufferPtr *
> +do_get_buffers(DrawablePtr pDraw, int *width, int *height,
> +	       unsigned int *attachments, int count, int *out_count,
> +	       int has_format)
>  {
>      DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen);
>      DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
> -    DRI2BufferPtr   buffers;
> -    unsigned int temp_buf[32];
> -    unsigned int *temp = temp_buf;
> +    DRI2BufferPtr  *buffers;
> +    int need_real_front = 0;
> +    int need_fake_front = 0;
>      int have_fake_front = 0;
> +    int front_format = 0;
> +    const int dimensions_match = (pDraw->width == pPriv->width)
> +	&& (pDraw->height == pPriv->height);
> +    int i;
>  
>  
> -    /* If the drawable is a window and the front-buffer is requested, silently
> -     * add the fake front-buffer to the list of requested attachments.  The
> -     * counting logic in the loop accounts for the case where the client
> -     * requests both the fake and real front-buffer.
> -     */
> -    if (pDraw->type == DRAWABLE_WINDOW) {
> -	int need_fake_front = 0;
> -	int i;
> +    buffers = xalloc((count + 1) * sizeof(buffers[0]));
>  
> -	if ((count + 1) > 32) {
> -	    temp = xalloc((count + 1) * sizeof(temp[0]));
> -	}
> +    for (i = 0; i < count; i++) {
> +	const unsigned attachment = *(attachments++);
> +	const unsigned format = (has_format) ? *(attachments++) : 0;
> +
> +	buffers[i] = allocate_or_reuse_buffer(pDraw, ds, pPriv, attachment,
> +					      format, dimensions_match);
>  
> -	for (i = 0; i < count; i++) {
> -	    if (attachments[i] == DRI2BufferFrontLeft) {
> +
> +	/* If the drawable is a window and the front-buffer is requested,
> +	 * silently add the fake front-buffer to the list of requested
> +	 * attachments.  The counting logic in the loop accounts for the case
> +	 * where the client requests both the fake and real front-buffer.
> +	 */
> +	if (pDraw->type == DRAWABLE_WINDOW) {
> +	    if (attachment == DRI2BufferBackLeft) {
> +		need_real_front++;
> +		front_format = format;
> +	    }
> +
> +	    if (attachment == DRI2BufferFrontLeft) {
> +		need_real_front--;
>  		need_fake_front++;
> +		front_format = format;
>  	    }
>  
> -	    if (attachments[i] == DRI2BufferFakeFrontLeft) {
> +	    if (attachment == DRI2BufferFakeFrontLeft) {
>  		need_fake_front--;
>  		have_fake_front = 1;
>  	    }
> -
> -	    temp[i] = attachments[i];
> -	}
> -
> -	if (need_fake_front > 0) {
> -	    temp[i] = DRI2BufferFakeFrontLeft;
> -	    count++;
> -	    have_fake_front = 1;
> -	    attachments = temp;
>  	}
>      }
>  
> +    if (need_real_front > 0) {
> +	buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv,
> +						DRI2BufferFrontLeft,
> +						front_format, dimensions_match);
> +    }
>  
> -    if (pPriv->buffers == NULL ||
> -	pDraw->width != pPriv->width || pDraw->height != pPriv->height)
> -    {
> -	buffers = (*ds->CreateBuffers)(pDraw, attachments, count);
> -	(*ds->DestroyBuffers)(pDraw, pPriv->buffers, pPriv->bufferCount);
> -	pPriv->buffers = buffers;
> -	pPriv->bufferCount = count;
> -	pPriv->width = pDraw->width;
> -	pPriv->height = pDraw->height;
> +    if (need_fake_front > 0) {
> +	buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv,
> +						DRI2BufferFakeFrontLeft,
> +						front_format, dimensions_match);
> +	have_fake_front = 1;
>      }
>  
> -    if (temp != temp_buf) {
> -	xfree(temp);
> +    *out_count = i;
> +
> +
> +    if (pPriv->buffers != NULL) {
> +	for (i = 0; i < pPriv->bufferCount; i++) {
> +	    if (pPriv->buffers[i] != NULL) {
> +		(*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
> +	    }
> +	}
> +
> +	xfree(pPriv->buffers);
>      }
>  
> +
> +    pPriv->buffers = buffers;
> +    pPriv->bufferCount = *out_count;
>      *width = pPriv->width;
>      *height = pPriv->height;
> -    *out_count = pPriv->bufferCount;
>  
>  
>      /* If the client is getting a fake front-buffer, pre-fill it with the
> @@ -220,6 +279,22 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
>      return pPriv->buffers;
>  }
>  
> +DRI2BufferPtr *
> +DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
> +	       unsigned int *attachments, int count, int *out_count)
> +{
> +    return do_get_buffers(pDraw, width, height, attachments, count,
> +			  out_count, FALSE);
> +}
> +
> +DRI2BufferPtr *
> +DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height,
> +			 unsigned int *attachments, int count, int *out_count)
> +{
> +    return do_get_buffers(pDraw, width, height, attachments, count,
> +			  out_count, TRUE);
> +}
> +
>  int
>  DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
>  	       unsigned int dest, unsigned int src)
> @@ -237,10 +312,10 @@ DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
>      pSrcBuffer = NULL;
>      for (i = 0; i < pPriv->bufferCount; i++)
>      {
> -	if (pPriv->buffers[i].attachment == dest)
> -	    pDestBuffer = &pPriv->buffers[i];
> -	if (pPriv->buffers[i].attachment == src)
> -	    pSrcBuffer = &pPriv->buffers[i];
> +	if (pPriv->buffers[i]->attachment == dest)
> +	    pDestBuffer = pPriv->buffers[i];
> +	if (pPriv->buffers[i]->attachment == src)
> +	    pSrcBuffer = pPriv->buffers[i];
>      }
>      if (pSrcBuffer == NULL || pDestBuffer == NULL)
>  	return BadValue;
> @@ -266,7 +341,16 @@ DRI2DestroyDrawable(DrawablePtr pDraw)
>      if (pPriv->refCount > 0)
>  	return;
>  
> -    (*ds->DestroyBuffers)(pDraw, pPriv->buffers, pPriv->bufferCount);
> +    if (pPriv->buffers != NULL) {
> +	int i;
> +
> +	for (i = 0; i < pPriv->bufferCount; i++) {
> +	    (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
> +	}
> +
> +	xfree(pPriv->buffers);
> +    }
> +
>      xfree(pPriv);
>  
>      if (pDraw->type == DRAWABLE_WINDOW)
> @@ -320,11 +404,18 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
>      if (!ds)
>  	return FALSE;
>  
> +    if ((info->version < 2)
> +	|| (info->CreateBuffer == NULL)
> +	|| (info->DestroyBuffer == NULL)) {
> +	return FALSE;
> +    }
> +
> +
>      ds->fd	       = info->fd;
>      ds->driverName     = info->driverName;
>      ds->deviceName     = info->deviceName;
> -    ds->CreateBuffers  = info->CreateBuffers;
> -    ds->DestroyBuffers = info->DestroyBuffers;
> +    ds->CreateBuffer   = info->CreateBuffer;
> +    ds->DestroyBuffer  = info->DestroyBuffer;
>      ds->CopyRegion     = info->CopyRegion;
>  
>      dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
> @@ -371,7 +462,7 @@ static XF86ModuleVersionInfo DRI2VersRec =
>      MODINFOSTRING1,
>      MODINFOSTRING2,
>      XORG_VERSION_CURRENT,
> -    1, 0, 0,
> +    1, 1, 0,
>      ABI_CLASS_EXTENSION,
>      ABI_EXTENSION_VERSION,
>      MOD_CLASS_NONE,
> diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
> index e6c4b97..c9a0d3f 100644
> --- a/hw/xfree86/dri2/dri2.h
> +++ b/hw/xfree86/dri2/dri2.h
> @@ -41,6 +41,7 @@ typedef struct {
>      unsigned int pitch;
>      unsigned int cpp;
>      unsigned int flags;
> +    unsigned int format;
>      void *driverPrivate;
>  } DRI2BufferRec, *DRI2BufferPtr;
>  
> @@ -58,8 +59,19 @@ typedef void		(*DRI2CopyRegionProcPtr)(DrawablePtr pDraw,
>  typedef void		(*DRI2WaitProcPtr)(WindowPtr pWin,
>  					   unsigned int sequence);
>  
> +typedef DRI2BufferPtr	(*DRI2CreateBufferProcPtr)(DrawablePtr pDraw,
> +						   unsigned int attachment,
> +						   unsigned int format);
> +typedef void		(*DRI2DestroyBufferProcPtr)(DrawablePtr pDraw,
> +						    DRI2BufferPtr buffer);
> +
> +/**
> + * Version of the DRI2InfoRec structure defined in this header
> + */
> +#define DRI2INFOREC_VERSION 2
> +
>  typedef struct {
> -    unsigned int version;	/* Version of this struct */
> +    unsigned int version;	/**< Version of this struct */
>      int fd;
>      const char *driverName;
>      const char *deviceName;
> @@ -69,6 +81,14 @@ typedef struct {
>      DRI2CopyRegionProcPtr	CopyRegion;
>      DRI2WaitProcPtr		Wait;
>  
> +    /**
> +     * \name Fields added in version 2 of the structure.
> +     */
> +    /*@{*/
> +    DRI2CreateBufferProcPtr	CreateBuffer;
> +    DRI2DestroyBufferProcPtr	DestroyBuffer;
> +    /*@}*/
> +
>  }  DRI2InfoRec, *DRI2InfoPtr;
>  
>  Bool DRI2ScreenInit(ScreenPtr	pScreen,
> @@ -88,7 +108,7 @@ int DRI2CreateDrawable(DrawablePtr pDraw);
>  
>  void DRI2DestroyDrawable(DrawablePtr pDraw);
>  
> -DRI2BufferPtr DRI2GetBuffers(DrawablePtr pDraw,
> +DRI2BufferPtr *DRI2GetBuffers(DrawablePtr pDraw,
>  			     int *width,
>  			     int *height,
>  			     unsigned int *attachments,
> @@ -118,4 +138,8 @@ int DRI2CopyRegion(DrawablePtr pDraw,
>   */
>  extern _X_EXPORT void DRI2Version(int *major, int *minor);
>  
> +extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffersWithFormat(DrawablePtr pDraw,
> +	int *width, int *height, unsigned int *attachments, int count,
> +	int *out_count);
> +
>  #endif
> diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
> index ccc1bbb..97b96fa 100644
> --- a/hw/xfree86/dri2/dri2ext.c
> +++ b/hw/xfree86/dri2/dri2ext.c
> @@ -81,7 +81,7 @@ ProcDRI2QueryVersion(ClientPtr client)
>      rep.length = 0;
>      rep.sequenceNumber = client->sequence;
>      rep.majorVersion = 1;
> -    rep.minorVersion = 0;
> +    rep.minorVersion = 1;
>  
>      if (client->swapped) {
>      	swaps(&rep.sequenceNumber, n);
> @@ -193,32 +193,20 @@ ProcDRI2DestroyDrawable(ClientPtr client)
>      return client->noClientException;
>  }
>  
> -static int
> -ProcDRI2GetBuffers(ClientPtr client)
> +
> +static void
> +send_buffers_reply(ClientPtr client, DrawablePtr pDrawable,
> +		   DRI2BufferPtr *buffers, int count, int width, int height)
>  {
> -    REQUEST(xDRI2GetBuffersReq);
>      xDRI2GetBuffersReply rep;
> -    DrawablePtr pDrawable;
> -    DRI2BufferPtr buffers;
> -    int i, status, width, height, count;
> -    unsigned int *attachments;
> -    xDRI2Buffer buffer;
> -    int skip;
> +    int skip = 0;
> +    int i;
>  
> -    REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4);
> -    if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
> -	return status;
> -
> -    attachments = (unsigned int *) &stuff[1];
> -    buffers = DRI2GetBuffers(pDrawable, &width, &height,
> -			     attachments, stuff->count, &count);
> -
> -    skip = 0;
>      if (pDrawable->type == DRAWABLE_WINDOW) {
>  	for (i = 0; i < count; i++) {
>  	    /* Do not send the real front buffer of a window to the client.
>  	     */
> -	    if (buffers[i].attachment == DRI2BufferFrontLeft) {
> +	    if (buffers[i]->attachment == DRI2BufferFrontLeft) {
>  		skip++;
>  		continue;
>  	    }
> @@ -234,20 +222,66 @@ ProcDRI2GetBuffers(ClientPtr client)
>      WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep);
>  
>      for (i = 0; i < count; i++) {
> +	xDRI2Buffer buffer;
> +
>  	/* Do not send the real front buffer of a window to the client.
>  	 */
>  	if ((pDrawable->type == DRAWABLE_WINDOW)
> -	    && (buffers[i].attachment == DRI2BufferFrontLeft)) {
> +	    && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
>  	    continue;
>  	}
>  
> -	buffer.attachment = buffers[i].attachment;
> -	buffer.name = buffers[i].name;
> -	buffer.pitch = buffers[i].pitch;
> -	buffer.cpp = buffers[i].cpp;
> -	buffer.flags = buffers[i].flags;
> +	buffer.attachment = buffers[i]->attachment;
> +	buffer.name = buffers[i]->name;
> +	buffer.pitch = buffers[i]->pitch;
> +	buffer.cpp = buffers[i]->cpp;
> +	buffer.flags = buffers[i]->flags;
>  	WriteToClient(client, sizeof(xDRI2Buffer), &buffer);
>      }
> +}
> +
> +
> +static int
> +ProcDRI2GetBuffers(ClientPtr client)
> +{
> +    REQUEST(xDRI2GetBuffersReq);
> +    DrawablePtr pDrawable;
> +    DRI2BufferPtr *buffers;
> +    int status, width, height, count;
> +    unsigned int *attachments;
> +
> +    REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4);
> +    if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
> +	return status;
> +
> +    attachments = (unsigned int *) &stuff[1];
> +    buffers = DRI2GetBuffers(pDrawable, &width, &height,
> +			     attachments, stuff->count, &count);
> +
> +
> +    send_buffers_reply(client, pDrawable, buffers, count, width, height);
> +
> +    return client->noClientException;
> +}
> +
> +static int
> +ProcDRI2GetBuffersWithFormat(ClientPtr client)
> +{
> +    REQUEST(xDRI2GetBuffersReq);
> +    DrawablePtr pDrawable;
> +    DRI2BufferPtr *buffers;
> +    int status, width, height, count;
> +    unsigned int *attachments;
> +
> +    REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * (2 * 4));
> +    if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
> +	return status;
> +
> +    attachments = (unsigned int *) &stuff[1];
> +    buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height,
> +				       attachments, stuff->count, &count);
> +
> +    send_buffers_reply(client, pDrawable, buffers, count, width, height);
>  
>      return client->noClientException;
>  }
> @@ -314,6 +348,8 @@ ProcDRI2Dispatch (ClientPtr client)
>  	return ProcDRI2GetBuffers(client);
>      case X_DRI2CopyRegion:
>  	return ProcDRI2CopyRegion(client);
> +    case X_DRI2GetBuffersWithFormat:
> +	return ProcDRI2GetBuffersWithFormat(client);
>      default:
>  	return BadRequest;
>      }
> commit 98c3c21735197fbd2c8166c9bdabf055e14c9009
> Author: Ian Romanick <ian.d.romanick at intel.com>
> Date:   Fri Apr 24 12:09:21 2009 -0700
>
>     DRI2: Add interface for drivers to query DRI2 extension version
>     
>     Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
>     (cherry picked from commit 28ddfc88d8d547941c7f4713db527a3c2f9ec35a)
>
> diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
> index 0b52a0f..80de18f 100644
> --- a/hw/xfree86/dri2/dri2.c
> +++ b/hw/xfree86/dri2/dri2.c
> @@ -380,3 +380,12 @@ static XF86ModuleVersionInfo DRI2VersRec =
>  
>  _X_EXPORT XF86ModuleData dri2ModuleData = { &DRI2VersRec, DRI2Setup, NULL };
>  
> +void
> +DRI2Version(int *major, int *minor)
> +{
> +    if (major != NULL)
> +	*major = DRI2VersRec.majorversion;
> +
> +    if (minor != NULL)
> +	*minor = DRI2VersRec.minorversion;
> +}
> diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
> index 5e7fd65..e6c4b97 100644
> --- a/hw/xfree86/dri2/dri2.h
> +++ b/hw/xfree86/dri2/dri2.h
> @@ -100,4 +100,22 @@ int DRI2CopyRegion(DrawablePtr pDraw,
>  		   unsigned int dest,
>  		   unsigned int src);
>  
> +/**
> + * Determine the major and minor version of the DRI2 extension.
> + *
> + * Provides a mechanism to other modules (e.g., 2D drivers) to determine the
> + * version of the DRI2 extension.  While it is possible to peek directly at
> + * the \c XF86ModuleData from a layered module, such a module will fail to
> + * load (due to an unresolved symbol) if the DRI2 extension is not loaded.
> + *
> + * \param major  Location to store the major verion of the DRI2 extension
> + * \param minor  Location to store the minor verion of the DRI2 extension
> + *
> + * \note
> + * This interface was added some time after the initial release of the DRI2
> + * module.  Layered modules that wish to use this interface must first test
> + * its existance by calling \c xf86LoaderCheckSymbol.
> + */
> +extern _X_EXPORT void DRI2Version(int *major, int *minor);
> +
>  #endif
> commit 4cb4c210c365fd40ad314e0707eb38811f240a12
> Author: Ian Romanick <ian.d.romanick at intel.com>
> Date:   Thu Apr 16 12:10:34 2009 -0700
>
>     DRI2: Add missing front-buffer flush callback.
>     
>     Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
>     (cherry picked from commit d1e916d29be8b470cbc8cadcf6e83991fdbc5a9f)
>
> diff --git a/glx/glxdri2.c b/glx/glxdri2.c
> index 0daf9aa..84d2c03 100644
> --- a/glx/glxdri2.c
> +++ b/glx/glxdri2.c
> @@ -396,9 +396,17 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
>      return private->buffers;
>  }
>  
> +static void 
> +dri2FlushFrontBuffer(__DRIdrawable *driDrawable, void *loaderPrivate)
> +{
> +    (void) driDrawable;
> +    __glXDRIdrawableWaitGL((__GLXdrawable *) loaderPrivate);
> +}
> +
>  static const __DRIdri2LoaderExtension loaderExtension = {
>      { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
>      dri2GetBuffers,
> +    dri2FlushFrontBuffer,
>  };
>  
>  static const __DRIextension *loader_extensions[] = {
> commit aa13faef2b1464f808e04de9826c6b8b8b91ae89
> Author: Ian Romanick <ian.d.romanick at intel.com>
> Date:   Wed Apr 15 11:13:48 2009 -0700
>
>     DRI2: Don't leave empty entries in private->buffers
>     
>     This should fix bug #21130.
>     
>     Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
>     (cherry picked from commit de1e43181bd670877b994db221ad8a04b5d63324)
>
> diff --git a/glx/glxdri2.c b/glx/glxdri2.c
> index 4596cc5..0daf9aa 100644
> --- a/glx/glxdri2.c
> +++ b/glx/glxdri2.c
> @@ -361,7 +361,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
>      __GLXDRIdrawable *private = loaderPrivate;
>      DRI2BufferPtr buffers;
>      int i;
> -    int skip = 0;
> +    int j;
>  
>      buffers = DRI2GetBuffers(private->base.pDraw,
>  			     width, height, attachments, count, out_count);
> @@ -375,23 +375,24 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
>  
>      /* This assumes the DRI2 buffer attachment tokens matches the
>       * __DRIbuffer tokens. */
> +    j = 0;
>      for (i = 0; i < *out_count; i++) {
>  	/* Do not send the real front buffer of a window to the client.
>  	 */
>  	if ((private->base.pDraw->type == DRAWABLE_WINDOW)
>  	    && (buffers[i].attachment == DRI2BufferFrontLeft)) {
> -	    skip++;
>  	    continue;
>  	}
>  
> -	private->buffers[i].attachment = buffers[i].attachment;
> -	private->buffers[i].name = buffers[i].name;
> -	private->buffers[i].pitch = buffers[i].pitch;
> -	private->buffers[i].cpp = buffers[i].cpp;
> -	private->buffers[i].flags = buffers[i].flags;
> +	private->buffers[j].attachment = buffers[i].attachment;
> +	private->buffers[j].name = buffers[i].name;
> +	private->buffers[j].pitch = buffers[i].pitch;
> +	private->buffers[j].cpp = buffers[i].cpp;
> +	private->buffers[j].flags = buffers[i].flags;
> +	j++;
>      }
>  
> -    *out_count -= skip;
> +    *out_count = j;
>      return private->buffers;
>  }
>  
> commit d7277296ed7aea7bd41b3489d4ceef750d400206
> Author: Ian Romanick <ian.d.romanick at intel.com>
> Date:   Thu Apr 9 14:38:24 2009 -0700
>
>     DRI2: Synchronize the contents of the real and fake front-buffers
>     
>     Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
>     (cherry picked from commit 567cf67959b30432ae30f4851ec17b3a375ab838)
>
> diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
> index 351d02b..0b52a0f 100644
> --- a/hw/xfree86/dri2/dri2.c
> +++ b/hw/xfree86/dri2/dri2.c
> @@ -141,6 +141,7 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
>      DRI2BufferPtr   buffers;
>      unsigned int temp_buf[32];
>      unsigned int *temp = temp_buf;
> +    int have_fake_front = 0;
>  
>  
>      /* If the drawable is a window and the front-buffer is requested, silently
> @@ -163,6 +164,7 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
>  
>  	    if (attachments[i] == DRI2BufferFakeFrontLeft) {
>  		need_fake_front--;
> +		have_fake_front = 1;
>  	    }
>  
>  	    temp[i] = attachments[i];
> @@ -171,6 +173,7 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
>  	if (need_fake_front > 0) {
>  	    temp[i] = DRI2BufferFakeFrontLeft;
>  	    count++;
> +	    have_fake_front = 1;
>  	    attachments = temp;
>  	}
>      }
> @@ -195,6 +198,25 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
>      *height = pPriv->height;
>      *out_count = pPriv->bufferCount;
>  
> +
> +    /* If the client is getting a fake front-buffer, pre-fill it with the
> +     * contents of the real front-buffer.  This ensures correct operation of
> +     * applications that call glXWaitX before calling glDrawBuffer.
> +     */
> +    if (have_fake_front) {
> +	BoxRec box;
> +	RegionRec region;
> +
> +	box.x1 = 0;
> +	box.y1 = 0;
> +	box.x2 = pPriv->width;
> +	box.y2 = pPriv->height;
> +	REGION_INIT(pDraw->pScreen, &region, &box, 0);
> +
> +	DRI2CopyRegion(pDraw, &region, DRI2BufferFakeFrontLeft,
> +		       DRI2BufferFrontLeft);
> +    }
> +
>      return pPriv->buffers;
>  }
>  
> commit 73b786f7e7f46d40bf3b039538540c2e25f45947
> Author: Ian Romanick <ian.d.romanick at intel.com>
> Date:   Thu Apr 9 14:31:01 2009 -0700
>
>     DRI2: Do not send the real front buffer of a window to the client
>     
>     Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
>     (cherry picked from commit f1a995d1496d73741731e32f475097c44a8da972)
>
> diff --git a/glx/glxdri2.c b/glx/glxdri2.c
> index 4544a2c..4596cc5 100644
> --- a/glx/glxdri2.c
> +++ b/glx/glxdri2.c
> @@ -361,6 +361,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
>      __GLXDRIdrawable *private = loaderPrivate;
>      DRI2BufferPtr buffers;
>      int i;
> +    int skip = 0;
>  
>      buffers = DRI2GetBuffers(private->base.pDraw,
>  			     width, height, attachments, count, out_count);
> @@ -375,6 +376,14 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
>      /* This assumes the DRI2 buffer attachment tokens matches the
>       * __DRIbuffer tokens. */
>      for (i = 0; i < *out_count; i++) {
> +	/* Do not send the real front buffer of a window to the client.
> +	 */
> +	if ((private->base.pDraw->type == DRAWABLE_WINDOW)
> +	    && (buffers[i].attachment == DRI2BufferFrontLeft)) {
> +	    skip++;
> +	    continue;
> +	}
> +
>  	private->buffers[i].attachment = buffers[i].attachment;
>  	private->buffers[i].name = buffers[i].name;
>  	private->buffers[i].pitch = buffers[i].pitch;
> @@ -382,6 +391,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
>  	private->buffers[i].flags = buffers[i].flags;
>      }
>  
> +    *out_count -= skip;
>      return private->buffers;
>  }
>  
> diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
> index 1409777..ccc1bbb 100644
> --- a/hw/xfree86/dri2/dri2ext.c
> +++ b/hw/xfree86/dri2/dri2ext.c
> @@ -203,6 +203,7 @@ ProcDRI2GetBuffers(ClientPtr client)
>      int i, status, width, height, count;
>      unsigned int *attachments;
>      xDRI2Buffer buffer;
> +    int skip;
>  
>      REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4);
>      if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
> @@ -212,15 +213,34 @@ ProcDRI2GetBuffers(ClientPtr client)
>      buffers = DRI2GetBuffers(pDrawable, &width, &height,
>  			     attachments, stuff->count, &count);
>  
> +    skip = 0;
> +    if (pDrawable->type == DRAWABLE_WINDOW) {
> +	for (i = 0; i < count; i++) {
> +	    /* Do not send the real front buffer of a window to the client.
> +	     */
> +	    if (buffers[i].attachment == DRI2BufferFrontLeft) {
> +		skip++;
> +		continue;
> +	    }
> +	}
> +    }
> +
>      rep.type = X_Reply;
> -    rep.length = count * sizeof(xDRI2Buffer) / 4;
> +    rep.length = (count - skip) * sizeof(xDRI2Buffer) / 4;
>      rep.sequenceNumber = client->sequence;
>      rep.width = width;
>      rep.height = height;
> -    rep.count = count;
> +    rep.count = count - skip;
>      WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep);
>  
>      for (i = 0; i < count; i++) {
> +	/* Do not send the real front buffer of a window to the client.
> +	 */
> +	if ((pDrawable->type == DRAWABLE_WINDOW)
> +	    && (buffers[i].attachment == DRI2BufferFrontLeft)) {
> +	    continue;
> +	}
> +
>  	buffer.attachment = buffers[i].attachment;
>  	buffer.name = buffers[i].name;
>  	buffer.pitch = buffers[i].pitch;
> commit 32d250a881341ece8a1f1d78359adc1b265b5174
> Author: Ian Romanick <ian.d.romanick at intel.com>
> Date:   Wed Apr 8 15:44:34 2009 -0700
>
>     DRI2: Add fake front-buffer to request list for windows
>     
>     If a front-buffer is requested for a window, add the fake front-buffer
>     to the list of requested buffers.
>     
>     Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
>     (cherry picked from commit aa2928325fe51d94a636dde9c090e8f54a311a12)
>
> diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
> index 0f2e24b..351d02b 100644
> --- a/hw/xfree86/dri2/dri2.c
> +++ b/hw/xfree86/dri2/dri2.c
> @@ -139,6 +139,42 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
>      DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen);
>      DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
>      DRI2BufferPtr   buffers;
> +    unsigned int temp_buf[32];
> +    unsigned int *temp = temp_buf;
> +
> +
> +    /* If the drawable is a window and the front-buffer is requested, silently
> +     * add the fake front-buffer to the list of requested attachments.  The
> +     * counting logic in the loop accounts for the case where the client
> +     * requests both the fake and real front-buffer.
> +     */
> +    if (pDraw->type == DRAWABLE_WINDOW) {
> +	int need_fake_front = 0;
> +	int i;
> +
> +	if ((count + 1) > 32) {
> +	    temp = xalloc((count + 1) * sizeof(temp[0]));
> +	}
> +
> +	for (i = 0; i < count; i++) {
> +	    if (attachments[i] == DRI2BufferFrontLeft) {
> +		need_fake_front++;
> +	    }
> +
> +	    if (attachments[i] == DRI2BufferFakeFrontLeft) {
> +		need_fake_front--;
> +	    }
> +
> +	    temp[i] = attachments[i];
> +	}
> +
> +	if (need_fake_front > 0) {
> +	    temp[i] = DRI2BufferFakeFrontLeft;
> +	    count++;
> +	    attachments = temp;
> +	}
> +    }
> +
>  
>      if (pPriv->buffers == NULL ||
>  	pDraw->width != pPriv->width || pDraw->height != pPriv->height)
> @@ -151,6 +187,10 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
>  	pPriv->height = pDraw->height;
>      }
>  
> +    if (temp != temp_buf) {
> +	xfree(temp);
> +    }
> +
>      *width = pPriv->width;
>      *height = pPriv->height;
>      *out_count = pPriv->bufferCount;
>   
> ------------------------------------------------------------------------
>
> _______________________________________________
> xorg-commit mailing list
> xorg-commit at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/xorg-commit




More information about the xorg mailing list