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 <[email protected]> > 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 <[email protected]> > (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 <[email protected]> > 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 <[email protected]> > 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 <[email protected]> > Tested-by: Pierre Willenbrock <[email protected]> > (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 <[email protected]> > 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 <[email protected]> > Reviewed-by: Kristian Høgsberg <[email protected]> > > 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 <[email protected]> > Date: Fri Apr 24 12:09:21 2009 -0700 > > DRI2: Add interface for drivers to query DRI2 extension version > > Signed-off-by: Ian Romanick <[email protected]> > (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 <[email protected]> > Date: Thu Apr 16 12:10:34 2009 -0700 > > DRI2: Add missing front-buffer flush callback. > > Signed-off-by: Ian Romanick <[email protected]> > (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 <[email protected]> > 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 <[email protected]> > (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 <[email protected]> > 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 <[email protected]> > (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 <[email protected]> > 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 <[email protected]> > (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 <[email protected]> > 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 <[email protected]> > (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 > [email protected] > http://lists.freedesktop.org/mailman/listinfo/xorg-commit _______________________________________________ xorg mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/xorg
