summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2009-04-24 12:49:19 -0700
committerIan Romanick <ian.d.romanick@intel.com>2009-04-24 12:49:19 -0700
commitff6c7764c2909e4126403b7211faa6c58556b341 (patch)
tree87301de7ca62ce0676def6b8c7ef2a75b8e10c98
parent28ddfc88d8d547941c7f4713db527a3c2f9ec35a (diff)
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@intel.com> Reviewed-by: Kristian Høgsberg <krh@redhat.com>
-rw-r--r--configure.ac2
-rw-r--r--glx/glxdri2.c59
-rw-r--r--hw/xfree86/dri2/dri2.c195
-rw-r--r--hw/xfree86/dri2/dri2.h28
-rw-r--r--hw/xfree86/dri2/dri2ext.c88
5 files changed, 284 insertions, 88 deletions
diff --git a/configure.ac b/configure.ac
index f0317bd76..9eadabced 100644
--- a/configure.ac
+++ b/configure.ac
@@ -886,7 +886,7 @@ if test "x$DRI" = xyes; then
886 AC_SUBST(DRIPROTO_CFLAGS) 886 AC_SUBST(DRIPROTO_CFLAGS)
887fi 887fi
888 888
889PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 1.99.3], 889PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 2.1],
890 [HAVE_DRI2PROTO=yes], [HAVE_DRI2PROTO=no]) 890 [HAVE_DRI2PROTO=yes], [HAVE_DRI2PROTO=no])
891case "$DRI2,$HAVE_DRI2PROTO" in 891case "$DRI2,$HAVE_DRI2PROTO" in
892 yes,no) 892 yes,no)
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 612defb3f..529b2df10 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -406,7 +406,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
406 int *out_count, void *loaderPrivate) 406 int *out_count, void *loaderPrivate)
407{ 407{
408 __GLXDRIdrawable *private = loaderPrivate; 408 __GLXDRIdrawable *private = loaderPrivate;
409 DRI2BufferPtr buffers; 409 DRI2BufferPtr *buffers;
410 int i; 410 int i;
411 int j; 411 int j;
412 412
@@ -427,15 +427,59 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
427 /* Do not send the real front buffer of a window to the client. 427 /* Do not send the real front buffer of a window to the client.
428 */ 428 */
429 if ((private->base.pDraw->type == DRAWABLE_WINDOW) 429 if ((private->base.pDraw->type == DRAWABLE_WINDOW)
430 && (buffers[i].attachment == DRI2BufferFrontLeft)) { 430 && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
431 continue; 431 continue;
432 } 432 }
433 433
434 private->buffers[j].attachment = buffers[i].attachment; 434 private->buffers[j].attachment = buffers[i]->attachment;
435 private->buffers[j].name = buffers[i].name; 435 private->buffers[j].name = buffers[i]->name;
436 private->buffers[j].pitch = buffers[i].pitch; 436 private->buffers[j].pitch = buffers[i]->pitch;
437 private->buffers[j].cpp = buffers[i].cpp; 437 private->buffers[j].cpp = buffers[i]->cpp;
438 private->buffers[j].flags = buffers[i].flags; 438 private->buffers[j].flags = buffers[i]->flags;
439 j++;
440 }
441
442 *out_count = j;
443 return private->buffers;
444}
445
446static __DRIbuffer *
447dri2GetBuffersWithFormat(__DRIdrawable *driDrawable,
448 int *width, int *height,
449 unsigned int *attachments, int count,
450 int *out_count, void *loaderPrivate)
451{
452 __GLXDRIdrawable *private = loaderPrivate;
453 DRI2BufferPtr *buffers;
454 int i;
455 int j = 0;
456
457 buffers = DRI2GetBuffersWithFormat(private->base.pDraw,
458 width, height, attachments, count,
459 out_count);
460 if (*out_count > MAX_DRAWABLE_BUFFERS) {
461 *out_count = 0;
462 return NULL;
463 }
464
465 private->width = *width;
466 private->height = *height;
467
468 /* This assumes the DRI2 buffer attachment tokens matches the
469 * __DRIbuffer tokens. */
470 for (i = 0; i < *out_count; i++) {
471 /* Do not send the real front buffer of a window to the client.
472 */
473 if ((private->base.pDraw->type == DRAWABLE_WINDOW)
474 && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
475 continue;
476 }
477
478 private->buffers[j].attachment = buffers[i]->attachment;
479 private->buffers[j].name = buffers[i]->name;
480 private->buffers[j].pitch = buffers[i]->pitch;
481 private->buffers[j].cpp = buffers[i]->cpp;
482 private->buffers[j].flags = buffers[i]->flags;
439 j++; 483 j++;
440 } 484 }
441 485
@@ -454,6 +498,7 @@ static const __DRIdri2LoaderExtension loaderExtension = {
454 { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION }, 498 { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
455 dri2GetBuffers, 499 dri2GetBuffers,
456 dri2FlushFrontBuffer, 500 dri2FlushFrontBuffer,
501 dri2GetBuffersWithFormat,
457}; 502};
458 503
459static const __DRIextension *loader_extensions[] = { 504static const __DRIextension *loader_extensions[] = {
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 80de18f86..9ded048eb 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -53,7 +53,7 @@ typedef struct _DRI2Drawable {
53 unsigned int refCount; 53 unsigned int refCount;
54 int width; 54 int width;
55 int height; 55 int height;
56 DRI2BufferPtr buffers; 56 DRI2BufferPtr *buffers;
57 int bufferCount; 57 int bufferCount;
58 unsigned int pendingSequence; 58 unsigned int pendingSequence;
59} DRI2DrawableRec, *DRI2DrawablePtr; 59} DRI2DrawableRec, *DRI2DrawablePtr;
@@ -63,8 +63,8 @@ typedef struct _DRI2Screen {
63 const char *deviceName; 63 const char *deviceName;
64 int fd; 64 int fd;
65 unsigned int lastSequence; 65 unsigned int lastSequence;
66 DRI2CreateBuffersProcPtr CreateBuffers; 66 DRI2CreateBufferProcPtr CreateBuffer;
67 DRI2DestroyBuffersProcPtr DestroyBuffers; 67 DRI2DestroyBufferProcPtr DestroyBuffer;
68 DRI2CopyRegionProcPtr CopyRegion; 68 DRI2CopyRegionProcPtr CopyRegion;
69 69
70 HandleExposuresProcPtr HandleExposures; 70 HandleExposuresProcPtr HandleExposures;
@@ -132,71 +132,130 @@ DRI2CreateDrawable(DrawablePtr pDraw)
132 return Success; 132 return Success;
133} 133}
134 134
135DRI2BufferPtr 135static int
136DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height, 136find_attachment(DRI2BufferPtr *buffer_list, int count, unsigned attachment)
137 unsigned int *attachments, int count, int *out_count) 137{
138 int i;
139
140 if (buffer_list == NULL) {
141 return -1;
142 }
143
144 for (i = 0; i < count; i++) {
145 if ((buffer_list[i] != NULL)
146 && (buffer_list[i]->attachment == attachment)) {
147 return i;
148 }
149 }
150
151 return -1;
152}
153
154static DRI2BufferPtr
155allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
156 DRI2DrawablePtr pPriv,
157 unsigned int attachment, unsigned int format,
158 int dimensions_match)
159{
160 DRI2BufferPtr buffer;
161 int old_buf;
162
163 old_buf = find_attachment(pPriv->buffers, pPriv->bufferCount, attachment);
164
165 if ((old_buf < 0)
166 || !dimensions_match
167 || (pPriv->buffers[old_buf]->format != format)) {
168 buffer = (*ds->CreateBuffer)(pDraw, attachment, format);
169 } else {
170 buffer = pPriv->buffers[old_buf];
171 pPriv->buffers[old_buf] = NULL;
172 }
173
174 return buffer;
175}
176
177static DRI2BufferPtr *
178do_get_buffers(DrawablePtr pDraw, int *width, int *height,
179 unsigned int *attachments, int count, int *out_count,
180 int has_format)
138{ 181{
139 DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); 182 DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
140 DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw); 183 DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
141 DRI2BufferPtr buffers; 184 DRI2BufferPtr *buffers;
142 unsigned int temp_buf[32]; 185 int need_real_front = 0;
143 unsigned int *temp = temp_buf; 186 int need_fake_front = 0;
144 int have_fake_front = 0; 187 int have_fake_front = 0;
188 int front_format = 0;
189 const int dimensions_match = (pDraw->width == pPriv->width)
190 && (pDraw->height == pPriv->height);
191 int i;
145 192
146 193
147 /* If the drawable is a window and the front-buffer is requested, silently 194 buffers = xalloc((count + 1) * sizeof(buffers[0]));
148 * add the fake front-buffer to the list of requested attachments. The
149 * counting logic in the loop accounts for the case where the client
150 * requests both the fake and real front-buffer.
151 */
152 if (pDraw->type == DRAWABLE_WINDOW) {
153 int need_fake_front = 0;
154 int i;
155 195
156 if ((count + 1) > 32) { 196 for (i = 0; i < count; i++) {
157 temp = xalloc((count + 1) * sizeof(temp[0])); 197 const unsigned attachment = *(attachments++);
158 } 198 const unsigned format = (has_format) ? *(attachments++) : 0;
199
200 buffers[i] = allocate_or_reuse_buffer(pDraw, ds, pPriv, attachment,
201 format, dimensions_match);
159 202
160 for (i = 0; i < count; i++) { 203
161 if (attachments[i] == DRI2BufferFrontLeft) { 204 /* If the drawable is a window and the front-buffer is requested,
205 * silently add the fake front-buffer to the list of requested
206 * attachments. The counting logic in the loop accounts for the case
207 * where the client requests both the fake and real front-buffer.
208 */
209 if (pDraw->type == DRAWABLE_WINDOW) {
210 if (attachment == DRI2BufferBackLeft) {
211 need_real_front++;
212 front_format = format;
213 }
214
215 if (attachment == DRI2BufferFrontLeft) {
216 need_real_front--;
162 need_fake_front++; 217 need_fake_front++;
218 front_format = format;
163 } 219 }
164 220
165 if (attachments[i] == DRI2BufferFakeFrontLeft) { 221 if (attachment == DRI2BufferFakeFrontLeft) {
166 need_fake_front--; 222 need_fake_front--;
167 have_fake_front = 1; 223 have_fake_front = 1;
168 } 224 }
169
170 temp[i] = attachments[i];
171 }
172
173 if (need_fake_front > 0) {
174 temp[i] = DRI2BufferFakeFrontLeft;
175 count++;
176 have_fake_front = 1;
177 attachments = temp;
178 } 225 }
179 } 226 }
180 227
228 if (need_real_front > 0) {
229 buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv,
230 DRI2BufferFrontLeft,
231 front_format, dimensions_match);
232 }
181 233
182 if (pPriv->buffers == NULL || 234 if (need_fake_front > 0) {
183 pDraw->width != pPriv->width || pDraw->height != pPriv->height) 235 buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv,
184 { 236 DRI2BufferFakeFrontLeft,
185 buffers = (*ds->CreateBuffers)(pDraw, attachments, count); 237 front_format, dimensions_match);
186 (*ds->DestroyBuffers)(pDraw, pPriv->buffers, pPriv->bufferCount); 238 have_fake_front = 1;
187 pPriv->buffers = buffers;
188 pPriv->bufferCount = count;
189 pPriv->width = pDraw->width;
190 pPriv->height = pDraw->height;
191 } 239 }
192 240
193 if (temp != temp_buf) { 241 *out_count = i;
194 xfree(temp); 242
243
244 if (pPriv->buffers != NULL) {
245 for (i = 0; i < pPriv->bufferCount; i++) {
246 if (pPriv->buffers[i] != NULL) {
247 (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
248 }
249 }
250
251 xfree(pPriv->buffers);
195 } 252 }
196 253
254
255 pPriv->buffers = buffers;
256 pPriv->bufferCount = *out_count;
197 *width = pPriv->width; 257 *width = pPriv->width;
198 *height = pPriv->height; 258 *height = pPriv->height;
199 *out_count = pPriv->bufferCount;
200 259
201 260
202 /* If the client is getting a fake front-buffer, pre-fill it with the 261 /* 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,
220 return pPriv->buffers; 279 return pPriv->buffers;
221} 280}
222 281
282DRI2BufferPtr *
283DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
284 unsigned int *attachments, int count, int *out_count)
285{
286 return do_get_buffers(pDraw, width, height, attachments, count,
287 out_count, FALSE);
288}
289
290DRI2BufferPtr *
291DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height,
292 unsigned int *attachments, int count, int *out_count)
293{
294 return do_get_buffers(pDraw, width, height, attachments, count,
295 out_count, TRUE);
296}
297
223int 298int
224DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, 299DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
225 unsigned int dest, unsigned int src) 300 unsigned int dest, unsigned int src)
@@ -237,10 +312,10 @@ DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
237 pSrcBuffer = NULL; 312 pSrcBuffer = NULL;
238 for (i = 0; i < pPriv->bufferCount; i++) 313 for (i = 0; i < pPriv->bufferCount; i++)
239 { 314 {
240 if (pPriv->buffers[i].attachment == dest) 315 if (pPriv->buffers[i]->attachment == dest)
241 pDestBuffer = &pPriv->buffers[i]; 316 pDestBuffer = pPriv->buffers[i];
242 if (pPriv->buffers[i].attachment == src) 317 if (pPriv->buffers[i]->attachment == src)
243 pSrcBuffer = &pPriv->buffers[i]; 318 pSrcBuffer = pPriv->buffers[i];
244 } 319 }
245 if (pSrcBuffer == NULL || pDestBuffer == NULL) 320 if (pSrcBuffer == NULL || pDestBuffer == NULL)
246 return BadValue; 321 return BadValue;
@@ -266,7 +341,16 @@ DRI2DestroyDrawable(DrawablePtr pDraw)
266 if (pPriv->refCount > 0) 341 if (pPriv->refCount > 0)
267 return; 342 return;
268 343
269 (*ds->DestroyBuffers)(pDraw, pPriv->buffers, pPriv->bufferCount); 344 if (pPriv->buffers != NULL) {
345 int i;
346
347 for (i = 0; i < pPriv->bufferCount; i++) {
348 (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
349 }
350
351 xfree(pPriv->buffers);
352 }
353
270 xfree(pPriv); 354 xfree(pPriv);
271 355
272 if (pDraw->type == DRAWABLE_WINDOW) 356 if (pDraw->type == DRAWABLE_WINDOW)
@@ -320,11 +404,18 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
320 if (!ds) 404 if (!ds)
321 return FALSE; 405 return FALSE;
322 406
407 if ((info->version < 2)
408 || (info->CreateBuffer == NULL)
409 || (info->DestroyBuffer == NULL)) {
410 return FALSE;
411 }
412
413
323 ds->fd = info->fd; 414 ds->fd = info->fd;
324 ds->driverName = info->driverName; 415 ds->driverName = info->driverName;
325 ds->deviceName = info->deviceName; 416 ds->deviceName = info->deviceName;
326 ds->CreateBuffers = info->CreateBuffers; 417 ds->CreateBuffer = info->CreateBuffer;
327 ds->DestroyBuffers = info->DestroyBuffers; 418 ds->DestroyBuffer = info->DestroyBuffer;
328 ds->CopyRegion = info->CopyRegion; 419 ds->CopyRegion = info->CopyRegion;
329 420
330 dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds); 421 dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
@@ -371,7 +462,7 @@ static XF86ModuleVersionInfo DRI2VersRec =
371 MODINFOSTRING1, 462 MODINFOSTRING1,
372 MODINFOSTRING2, 463 MODINFOSTRING2,
373 XORG_VERSION_CURRENT, 464 XORG_VERSION_CURRENT,
374 1, 0, 0, 465 1, 1, 0,
375 ABI_CLASS_EXTENSION, 466 ABI_CLASS_EXTENSION,
376 ABI_EXTENSION_VERSION, 467 ABI_EXTENSION_VERSION,
377 MOD_CLASS_NONE, 468 MOD_CLASS_NONE,
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index 9d7d6dc80..b3d02a99e 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -41,6 +41,7 @@ typedef struct {
41 unsigned int pitch; 41 unsigned int pitch;
42 unsigned int cpp; 42 unsigned int cpp;
43 unsigned int flags; 43 unsigned int flags;
44 unsigned int format;
44 void *driverPrivate; 45 void *driverPrivate;
45} DRI2BufferRec, *DRI2BufferPtr; 46} DRI2BufferRec, *DRI2BufferPtr;
46 47
@@ -58,8 +59,19 @@ typedef void (*DRI2CopyRegionProcPtr)(DrawablePtr pDraw,
58typedef void (*DRI2WaitProcPtr)(WindowPtr pWin, 59typedef void (*DRI2WaitProcPtr)(WindowPtr pWin,
59 unsigned int sequence); 60 unsigned int sequence);
60 61
62typedef DRI2BufferPtr (*DRI2CreateBufferProcPtr)(DrawablePtr pDraw,
63 unsigned int attachment,
64 unsigned int format);
65typedef void (*DRI2DestroyBufferProcPtr)(DrawablePtr pDraw,
66 DRI2BufferPtr buffer);
67
68/**
69 * Version of the DRI2InfoRec structure defined in this header
70 */
71#define DRI2INFOREC_VERSION 2
72
61typedef struct { 73typedef struct {
62 unsigned int version; /* Version of this struct */ 74 unsigned int version; /**< Version of this struct */
63 int fd; 75 int fd;
64 const char *driverName; 76 const char *driverName;
65 const char *deviceName; 77 const char *deviceName;
@@ -69,6 +81,14 @@ typedef struct {
69 DRI2CopyRegionProcPtr CopyRegion; 81 DRI2CopyRegionProcPtr CopyRegion;
70 DRI2WaitProcPtr Wait; 82 DRI2WaitProcPtr Wait;
71 83
84 /**
85 * \name Fields added in version 2 of the structure.
86 */
87 /*@{*/
88 DRI2CreateBufferProcPtr CreateBuffer;
89 DRI2DestroyBufferProcPtr DestroyBuffer;
90 /*@}*/
91
72} DRI2InfoRec, *DRI2InfoPtr; 92} DRI2InfoRec, *DRI2InfoPtr;
73 93
74extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr pScreen, 94extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr pScreen,
@@ -88,7 +108,7 @@ extern _X_EXPORT int DRI2CreateDrawable(DrawablePtr pDraw);
88 108
89extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw); 109extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw);
90 110
91extern _X_EXPORT DRI2BufferPtr DRI2GetBuffers(DrawablePtr pDraw, 111extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffers(DrawablePtr pDraw,
92 int *width, 112 int *width,
93 int *height, 113 int *height,
94 unsigned int *attachments, 114 unsigned int *attachments,
@@ -118,4 +138,8 @@ extern _X_EXPORT int DRI2CopyRegion(DrawablePtr pDraw,
118 */ 138 */
119extern _X_EXPORT void DRI2Version(int *major, int *minor); 139extern _X_EXPORT void DRI2Version(int *major, int *minor);
120 140
141extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffersWithFormat(DrawablePtr pDraw,
142 int *width, int *height, unsigned int *attachments, int count,
143 int *out_count);
144
121#endif 145#endif
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index 23f312149..029dce84e 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -80,7 +80,7 @@ ProcDRI2QueryVersion(ClientPtr client)
80 rep.length = 0; 80 rep.length = 0;
81 rep.sequenceNumber = client->sequence; 81 rep.sequenceNumber = client->sequence;
82 rep.majorVersion = 1; 82 rep.majorVersion = 1;
83 rep.minorVersion = 0; 83 rep.minorVersion = 1;
84 84
85 if (client->swapped) { 85 if (client->swapped) {
86 swaps(&rep.sequenceNumber, n); 86 swaps(&rep.sequenceNumber, n);
@@ -192,32 +192,20 @@ ProcDRI2DestroyDrawable(ClientPtr client)
192 return client->noClientException; 192 return client->noClientException;
193} 193}
194 194
195static int 195
196ProcDRI2GetBuffers(ClientPtr client) 196static void
197send_buffers_reply(ClientPtr client, DrawablePtr pDrawable,
198 DRI2BufferPtr *buffers, int count, int width, int height)
197{ 199{
198 REQUEST(xDRI2GetBuffersReq);
199 xDRI2GetBuffersReply rep; 200 xDRI2GetBuffersReply rep;
200 DrawablePtr pDrawable; 201 int skip = 0;
201 DRI2BufferPtr buffers; 202 int i;
202 int i, status, width, height, count;
203 unsigned int *attachments;
204 xDRI2Buffer buffer;
205 int skip;
206 203
207 REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4);
208 if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
209 return status;
210
211 attachments = (unsigned int *) &stuff[1];
212 buffers = DRI2GetBuffers(pDrawable, &width, &height,
213 attachments, stuff->count, &count);
214
215 skip = 0;
216 if (pDrawable->type == DRAWABLE_WINDOW) { 204 if (pDrawable->type == DRAWABLE_WINDOW) {
217 for (i = 0; i < count; i++) { 205 for (i = 0; i < count; i++) {
218 /* Do not send the real front buffer of a window to the client. 206 /* Do not send the real front buffer of a window to the client.
219 */ 207 */
220 if (buffers[i].attachment == DRI2BufferFrontLeft) { 208 if (buffers[i]->attachment == DRI2BufferFrontLeft) {
221 skip++; 209 skip++;
222 continue; 210 continue;
223 } 211 }
@@ -233,20 +221,66 @@ ProcDRI2GetBuffers(ClientPtr client)
233 WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep); 221 WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep);
234 222
235 for (i = 0; i < count; i++) { 223 for (i = 0; i < count; i++) {
224 xDRI2Buffer buffer;
225
236 /* Do not send the real front buffer of a window to the client. 226 /* Do not send the real front buffer of a window to the client.
237 */ 227 */
238 if ((pDrawable->type == DRAWABLE_WINDOW) 228 if ((pDrawable->type == DRAWABLE_WINDOW)
239 && (buffers[i].attachment == DRI2BufferFrontLeft)) { 229 && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
240 continue; 230 continue;
241 } 231 }
242 232
243 buffer.attachment = buffers[i].attachment; 233 buffer.attachment = buffers[i]->attachment;
244 buffer.name = buffers[i].name; 234 buffer.name = buffers[i]->name;
245 buffer.pitch = buffers[i].pitch; 235 buffer.pitch = buffers[i]->pitch;
246 buffer.cpp = buffers[i].cpp; 236 buffer.cpp = buffers[i]->cpp;
247 buffer.flags = buffers[i].flags; 237 buffer.flags = buffers[i]->flags;
248 WriteToClient(client, sizeof(xDRI2Buffer), &buffer); 238 WriteToClient(client, sizeof(xDRI2Buffer), &buffer);
249 } 239 }
240}
241
242
243static int
244ProcDRI2GetBuffers(ClientPtr client)
245{
246 REQUEST(xDRI2GetBuffersReq);
247 DrawablePtr pDrawable;
248 DRI2BufferPtr *buffers;
249 int status, width, height, count;
250 unsigned int *attachments;
251
252 REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4);
253 if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
254 return status;
255
256 attachments = (unsigned int *) &stuff[1];
257 buffers = DRI2GetBuffers(pDrawable, &width, &height,
258 attachments, stuff->count, &count);
259
260
261 send_buffers_reply(client, pDrawable, buffers, count, width, height);
262
263 return client->noClientException;
264}
265
266static int
267ProcDRI2GetBuffersWithFormat(ClientPtr client)
268{
269 REQUEST(xDRI2GetBuffersReq);
270 DrawablePtr pDrawable;
271 DRI2BufferPtr *buffers;
272 int status, width, height, count;
273 unsigned int *attachments;
274
275 REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * (2 * 4));
276 if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
277 return status;
278
279 attachments = (unsigned int *) &stuff[1];
280 buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height,
281 attachments, stuff->count, &count);
282
283 send_buffers_reply(client, pDrawable, buffers, count, width, height);
250 284
251 return client->noClientException; 285 return client->noClientException;
252} 286}
@@ -313,6 +347,8 @@ ProcDRI2Dispatch (ClientPtr client)
313 return ProcDRI2GetBuffers(client); 347 return ProcDRI2GetBuffers(client);
314 case X_DRI2CopyRegion: 348 case X_DRI2CopyRegion:
315 return ProcDRI2CopyRegion(client); 349 return ProcDRI2CopyRegion(client);
350 case X_DRI2GetBuffersWithFormat:
351 return ProcDRI2GetBuffersWithFormat(client);
316 default: 352 default:
317 return BadRequest; 353 return BadRequest;
318 } 354 }