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, ®ion, &box, 0);
> +
> + DRI2CopyRegion(pDraw, ®ion, 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