diff options
author | Ian Romanick <ian.d.romanick@intel.com> | 2009-04-24 12:49:19 -0700 |
---|---|---|
committer | Ian Romanick <ian.d.romanick@intel.com> | 2009-04-24 12:49:19 -0700 |
commit | ff6c7764c2909e4126403b7211faa6c58556b341 (patch) | |
tree | 87301de7ca62ce0676def6b8c7ef2a75b8e10c98 | |
parent | 28ddfc88d8d547941c7f4713db527a3c2f9ec35a (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.ac | 2 | ||||
-rw-r--r-- | glx/glxdri2.c | 59 | ||||
-rw-r--r-- | hw/xfree86/dri2/dri2.c | 195 | ||||
-rw-r--r-- | hw/xfree86/dri2/dri2.h | 28 | ||||
-rw-r--r-- | hw/xfree86/dri2/dri2ext.c | 88 |
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) |
887 | fi | 887 | fi |
888 | 888 | ||
889 | PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 1.99.3], | 889 | PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 2.1], |
890 | [HAVE_DRI2PROTO=yes], [HAVE_DRI2PROTO=no]) | 890 | [HAVE_DRI2PROTO=yes], [HAVE_DRI2PROTO=no]) |
891 | case "$DRI2,$HAVE_DRI2PROTO" in | 891 | case "$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 | |||
446 | static __DRIbuffer * | ||
447 | dri2GetBuffersWithFormat(__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 | ||
459 | static const __DRIextension *loader_extensions[] = { | 504 | static 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 | ||
135 | DRI2BufferPtr | 135 | static int |
136 | DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height, | 136 | find_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 | |||
154 | static DRI2BufferPtr | ||
155 | allocate_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 | |||
177 | static DRI2BufferPtr * | ||
178 | do_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 | ||
282 | DRI2BufferPtr * | ||
283 | DRI2GetBuffers(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 | |||
290 | DRI2BufferPtr * | ||
291 | DRI2GetBuffersWithFormat(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 | |||
223 | int | 298 | int |
224 | DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, | 299 | DRI2CopyRegion(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, | |||
58 | typedef void (*DRI2WaitProcPtr)(WindowPtr pWin, | 59 | typedef void (*DRI2WaitProcPtr)(WindowPtr pWin, |
59 | unsigned int sequence); | 60 | unsigned int sequence); |
60 | 61 | ||
62 | typedef DRI2BufferPtr (*DRI2CreateBufferProcPtr)(DrawablePtr pDraw, | ||
63 | unsigned int attachment, | ||
64 | unsigned int format); | ||
65 | typedef 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 | |||
61 | typedef struct { | 73 | typedef 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 | ||
74 | extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr pScreen, | 94 | extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr pScreen, |
@@ -88,7 +108,7 @@ extern _X_EXPORT int DRI2CreateDrawable(DrawablePtr pDraw); | |||
88 | 108 | ||
89 | extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw); | 109 | extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw); |
90 | 110 | ||
91 | extern _X_EXPORT DRI2BufferPtr DRI2GetBuffers(DrawablePtr pDraw, | 111 | extern _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 | */ |
119 | extern _X_EXPORT void DRI2Version(int *major, int *minor); | 139 | extern _X_EXPORT void DRI2Version(int *major, int *minor); |
120 | 140 | ||
141 | extern _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 | ||
195 | static int | 195 | |
196 | ProcDRI2GetBuffers(ClientPtr client) | 196 | static void |
197 | send_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 | |||
243 | static int | ||
244 | ProcDRI2GetBuffers(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 | |||
266 | static int | ||
267 | ProcDRI2GetBuffersWithFormat(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 | } |