xserver: Branch 'master' - 2 commits
Keith Packard
keithp at kemper.freedesktop.org
Mon Jul 6 13:11:11 PDT 2009
hw/xfree86/common/xf86Module.h | 2 +-
hw/xfree86/dri2/dri2.c | 37 ++++++++++++++++---------------------
hw/xfree86/dri2/dri2.h | 17 ++++++-----------
3 files changed, 23 insertions(+), 33 deletions(-)
New commits:
commit 5aec72745232dd61e60cfbf3acc4628d4fcd0315
Author: Keith Packard <keithp at keithp.com>
Date: Mon Jul 6 11:53:02 2009 -0700
Remove old DRI2 buffer alloc/free interfaces
These old interfaces are no longer supported by the server, removing them
requires bumping the video driver ABI. Note that this is not guaranteed to
be the last change in ABI version 6.
Signed-off-by: Keith Packard <keithp at keithp.com>
Reviewed-by: Eric Anholt <eric at anholt.net>
diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
index ded5216..4c64c35 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -82,7 +82,7 @@ typedef enum {
* mask is 0xFFFF0000.
*/
#define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4)
-#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(5, 0)
+#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(6, 0)
#define ABI_XINPUT_VERSION SET_ABI_VERSION(7, 0)
#define ABI_EXTENSION_VERSION SET_ABI_VERSION(2, 0)
#define ABI_FONT_VERSION SET_ABI_VERSION(0, 6)
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 3e8a7d4..8795cd1 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;
- DRI2Buffer2Ptr *buffers;
+ DRI2BufferPtr *buffers;
int bufferCount;
unsigned int pendingSequence;
} DRI2DrawableRec, *DRI2DrawablePtr;
@@ -64,9 +64,6 @@ typedef struct _DRI2Screen {
int fd;
unsigned int lastSequence;
- DRI2CreateBuffersProcPtr CreateBuffers;
- DRI2DestroyBuffersProcPtr DestroyBuffers;
-
DRI2CreateBufferProcPtr CreateBuffer;
DRI2DestroyBufferProcPtr DestroyBuffer;
DRI2CopyRegionProcPtr CopyRegion;
@@ -155,13 +152,13 @@ find_attachment(DRI2DrawablePtr pPriv, unsigned attachment)
return -1;
}
-static DRI2Buffer2Ptr
+static DRI2BufferPtr
allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
DRI2DrawablePtr pPriv,
unsigned int attachment, unsigned int format,
int dimensions_match)
{
- DRI2Buffer2Ptr buffer;
+ DRI2BufferPtr buffer;
int old_buf;
old_buf = find_attachment(pPriv, attachment);
@@ -178,14 +175,14 @@ allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
return buffer;
}
-static DRI2Buffer2Ptr *
+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);
- DRI2Buffer2Ptr *buffers;
+ DRI2BufferPtr *buffers;
int need_real_front = 0;
int need_fake_front = 0;
int have_fake_front = 0;
@@ -205,154 +202,64 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
buffers = xalloc((count + 1) * sizeof(buffers[0]));
- if (ds->CreateBuffer) {
- /* Version 2 API with CreateBuffer */
- 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);
-
- /* 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 (attachment == DRI2BufferBackLeft) {
- need_real_front++;
- front_format = format;
- }
-
- if (attachment == DRI2BufferFrontLeft) {
- need_real_front--;
- front_format = format;
-
- if (pDraw->type == DRAWABLE_WINDOW) {
- need_fake_front++;
- }
- }
-
- if (pDraw->type == DRAWABLE_WINDOW) {
- if (attachment == DRI2BufferFakeFrontLeft) {
- need_fake_front--;
- have_fake_front = 1;
- }
- }
- }
-
- if (need_real_front > 0) {
- buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv,
- DRI2BufferFrontLeft,
- front_format, dimensions_match);
- }
-
- if (need_fake_front > 0) {
- buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv,
- DRI2BufferFakeFrontLeft,
- front_format, dimensions_match);
- have_fake_front = 1;
+ 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);
+
+ /* 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 (attachment == DRI2BufferBackLeft) {
+ need_real_front++;
+ front_format = format;
}
- *out_count = i;
+ if (attachment == DRI2BufferFrontLeft) {
+ need_real_front--;
+ front_format = format;
-
- if (pPriv->buffers != NULL) {
- for (i = 0; i < pPriv->bufferCount; i++) {
- if (pPriv->buffers[i] != NULL) {
- (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
- }
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ need_fake_front++;
}
-
- xfree(pPriv->buffers);
}
- } else {
- DRI2BufferPtr buffers1;
- unsigned int temp_buf[32];
- unsigned int *temp = temp_buf;
- int i;
- int buffers_match = 1;
-
- /* Version 1 API with CreateBuffers */
- if ((count + 1) > 32) {
- temp = xalloc((count + 1) * sizeof(temp[0]));
- }
-
- for (i = 0; i < count; i++) {
- const unsigned attachment = *(attachments++);
-
- /* Version 1 doesn't deal with the format at all */
- if (has_format)
- attachments++;
-
- /*
- * Make sure the client also gets the front buffer when
- * it asks for a back buffer
- */
- if (attachment == DRI2BufferBackLeft)
- need_real_front++;
-
- /*
- * 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 (attachment == DRI2BufferFrontLeft) {
- need_real_front--;
- if (pDraw->type == DRAWABLE_WINDOW)
- need_fake_front++;
- }
- if (pDraw->type == DRAWABLE_WINDOW &&
- attachment == DRI2BufferFakeFrontLeft)
- {
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ if (attachment == DRI2BufferFakeFrontLeft) {
need_fake_front--;
have_fake_front = 1;
}
-
- temp[i] = attachment;
- }
-
- if (need_real_front > 0)
- temp[count++] = DRI2BufferFrontLeft;
-
- if (need_fake_front > 0) {
- temp[count++] = DRI2BufferFakeFrontLeft;
- have_fake_front = 1;
}
+ }
- if (count != pPriv->bufferCount)
- buffers_match = 0;
- else {
- for (i = 0; i < count; i++)
- if (pPriv->buffers[i]->attachment != temp[i]) {
- buffers_match = 0;
- break;
- }
- }
- if (pPriv->buffers == NULL || !dimensions_match || !buffers_match)
- {
- buffers1 = (*ds->CreateBuffers)(pDraw, temp, count);
- if (pPriv->buffers != NULL)
- (*ds->DestroyBuffers)(pDraw, (DRI2BufferPtr) pPriv->buffers[0],
- pPriv->bufferCount);
- }
- else
- buffers1 = (DRI2BufferPtr) pPriv->buffers[0];
+ if (need_real_front > 0) {
+ buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv,
+ DRI2BufferFrontLeft,
+ front_format, dimensions_match);
+ }
- for (i = 0; i < count; i++)
- buffers[i] = (DRI2Buffer2Ptr) &buffers1[i];
+ if (need_fake_front > 0) {
+ buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv,
+ DRI2BufferFakeFrontLeft,
+ front_format, dimensions_match);
+ have_fake_front = 1;
+ }
- *out_count = count;
+ *out_count = i;
- if (pPriv->buffers)
- xfree (pPriv->buffers);
- if (temp != temp_buf) {
- xfree(temp);
+ 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;
@@ -384,7 +291,7 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
return pPriv->buffers;
}
-DRI2Buffer2Ptr *
+DRI2BufferPtr *
DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
unsigned int *attachments, int count, int *out_count)
{
@@ -392,7 +299,7 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
out_count, FALSE);
}
-DRI2Buffer2Ptr *
+DRI2BufferPtr *
DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height,
unsigned int *attachments, int count, int *out_count)
{
@@ -449,14 +356,8 @@ DRI2DestroyDrawable(DrawablePtr pDraw)
if (pPriv->buffers != NULL) {
int i;
- if (ds->DestroyBuffer) {
- for (i = 0; i < pPriv->bufferCount; i++) {
- (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
- }
- } else {
- (*ds->DestroyBuffers)(pDraw, (DRI2BufferPtr) pPriv->buffers[0],
- pPriv->bufferCount);
- }
+ for (i = 0; i < pPriv->bufferCount; i++)
+ (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
xfree(pPriv->buffers);
}
@@ -510,6 +411,9 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
{
DRI2ScreenPtr ds;
+ if (info->version < 3)
+ return FALSE;
+
ds = xalloc(sizeof *ds);
if (!ds)
return FALSE;
@@ -518,32 +422,8 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
ds->driverName = info->driverName;
ds->deviceName = info->deviceName;
- /* Prefer the new one-at-a-time buffer API */
- if (info->version >= 2 && info->CreateBuffer && info->DestroyBuffer) {
- ds->CreateBuffer = info->CreateBuffer;
- ds->DestroyBuffer = info->DestroyBuffer;
- ds->CreateBuffers = NULL;
- ds->DestroyBuffers = NULL;
- } else if (info->CreateBuffers && info->DestroyBuffers) {
- xf86DrvMsg(pScreen->myNum, X_WARNING,
- "[DRI2] Version 1 API (broken front buffer rendering)\n");
- ds->CreateBuffer = NULL;
- ds->DestroyBuffer = NULL;
- ds->CreateBuffers = info->CreateBuffers;
- ds->DestroyBuffers = info->DestroyBuffers;
- } else {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] Missing buffer management functions\n");
- xfree(ds);
- return FALSE;
- }
-
- if (!info->CopyRegion) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] Missing copy region function\n");
- xfree(ds);
- return FALSE;
- }
+ ds->CreateBuffer = info->CreateBuffer;
+ ds->DestroyBuffer = info->DestroyBuffer;
ds->CopyRegion = info->CopyRegion;
dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index 22ee983..175471a 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -35,26 +35,18 @@
#include <X11/extensions/dri2tokens.h>
-/* Version 1 structure (for ABI compatibility) */
+/* Version 2 structure (with format at the end) */
typedef struct {
unsigned int attachment;
unsigned int name;
unsigned int pitch;
unsigned int cpp;
unsigned int flags;
+ unsigned int format;
void *driverPrivate;
} DRI2BufferRec, *DRI2BufferPtr;
-/* Version 2 structure (with format at the end) */
-typedef struct {
- unsigned int attachment;
- unsigned int name;
- unsigned int pitch;
- unsigned int cpp;
- unsigned int flags;
- void *driverPrivate;
- unsigned int format;
-} DRI2Buffer2Rec, *DRI2Buffer2Ptr;
+typedef DRI2BufferRec DRI2Buffer2Rec, *DRI2Buffer2Ptr;
typedef DRI2BufferPtr (*DRI2CreateBuffersProcPtr)(DrawablePtr pDraw,
unsigned int *attachments,
@@ -70,16 +62,16 @@ typedef void (*DRI2CopyRegionProcPtr)(DrawablePtr pDraw,
typedef void (*DRI2WaitProcPtr)(WindowPtr pWin,
unsigned int sequence);
-typedef DRI2Buffer2Ptr (*DRI2CreateBufferProcPtr)(DrawablePtr pDraw,
+typedef DRI2BufferPtr (*DRI2CreateBufferProcPtr)(DrawablePtr pDraw,
unsigned int attachment,
unsigned int format);
typedef void (*DRI2DestroyBufferProcPtr)(DrawablePtr pDraw,
- DRI2Buffer2Ptr buffer);
+ DRI2BufferPtr buffer);
/**
* Version of the DRI2InfoRec structure defined in this header
*/
-#define DRI2INFOREC_VERSION 2
+#define DRI2INFOREC_VERSION 3
typedef struct {
unsigned int version; /**< Version of this struct */
@@ -87,18 +79,10 @@ typedef struct {
const char *driverName;
const char *deviceName;
- DRI2CreateBuffersProcPtr CreateBuffers;
- DRI2DestroyBuffersProcPtr DestroyBuffers;
- DRI2CopyRegionProcPtr CopyRegion;
- DRI2WaitProcPtr Wait;
-
- /**
- * \name Fields added in version 2 of the structure.
- */
- /*@{*/
DRI2CreateBufferProcPtr CreateBuffer;
DRI2DestroyBufferProcPtr DestroyBuffer;
- /*@}*/
+ DRI2CopyRegionProcPtr CopyRegion;
+ DRI2WaitProcPtr Wait;
} DRI2InfoRec, *DRI2InfoPtr;
@@ -119,7 +103,7 @@ extern _X_EXPORT int DRI2CreateDrawable(DrawablePtr pDraw);
extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw);
-extern _X_EXPORT DRI2Buffer2Ptr *DRI2GetBuffers(DrawablePtr pDraw,
+extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffers(DrawablePtr pDraw,
int *width,
int *height,
unsigned int *attachments,
@@ -149,7 +133,7 @@ extern _X_EXPORT int DRI2CopyRegion(DrawablePtr pDraw,
*/
extern _X_EXPORT void DRI2Version(int *major, int *minor);
-extern _X_EXPORT DRI2Buffer2Ptr *DRI2GetBuffersWithFormat(DrawablePtr pDraw,
+extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffersWithFormat(DrawablePtr pDraw,
int *width, int *height, unsigned int *attachments, int count,
int *out_count);
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index ea160ac..029dce8 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -195,7 +195,7 @@ ProcDRI2DestroyDrawable(ClientPtr client)
static void
send_buffers_reply(ClientPtr client, DrawablePtr pDrawable,
- DRI2Buffer2Ptr *buffers, int count, int width, int height)
+ DRI2BufferPtr *buffers, int count, int width, int height)
{
xDRI2GetBuffersReply rep;
int skip = 0;
@@ -245,7 +245,7 @@ ProcDRI2GetBuffers(ClientPtr client)
{
REQUEST(xDRI2GetBuffersReq);
DrawablePtr pDrawable;
- DRI2Buffer2Ptr *buffers;
+ DRI2BufferPtr *buffers;
int status, width, height, count;
unsigned int *attachments;
@@ -268,7 +268,7 @@ ProcDRI2GetBuffersWithFormat(ClientPtr client)
{
REQUEST(xDRI2GetBuffersReq);
DrawablePtr pDrawable;
- DRI2Buffer2Ptr *buffers;
+ DRI2BufferPtr *buffers;
int status, width, height, count;
unsigned int *attachments;
commit 2e2c5b216cc1c7a9bc26bd2c68226aaed5fc52ca
Author: Keith Packard <keithp at keithp.com>
Date: Wed Jul 1 14:01:57 2009 -0700
dri2: Preserve compatibility with 1.6 DRI2 API/ABI
The old DRI2 buffer allocation API wasn't great, but there's no reason to
make the server stop working with those drivers. This patch has the
X server adapting to the API provided by the driver, using the new API where
available and falling back to the old API as necessary. A warning will be
placed in the log file when the old API is in use.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index aead33b..3e8a7d4 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;
+ DRI2Buffer2Ptr *buffers;
int bufferCount;
unsigned int pendingSequence;
} DRI2DrawableRec, *DRI2DrawablePtr;
@@ -63,6 +63,10 @@ typedef struct _DRI2Screen {
const char *deviceName;
int fd;
unsigned int lastSequence;
+
+ DRI2CreateBuffersProcPtr CreateBuffers;
+ DRI2DestroyBuffersProcPtr DestroyBuffers;
+
DRI2CreateBufferProcPtr CreateBuffer;
DRI2DestroyBufferProcPtr DestroyBuffer;
DRI2CopyRegionProcPtr CopyRegion;
@@ -133,17 +137,17 @@ DRI2CreateDrawable(DrawablePtr pDraw)
}
static int
-find_attachment(DRI2BufferPtr *buffer_list, int count, unsigned attachment)
+find_attachment(DRI2DrawablePtr pPriv, unsigned attachment)
{
int i;
- if (buffer_list == NULL) {
+ if (pPriv->buffers == NULL) {
return -1;
}
- for (i = 0; i < count; i++) {
- if ((buffer_list[i] != NULL)
- && (buffer_list[i]->attachment == attachment)) {
+ for (i = 0; i < pPriv->bufferCount; i++) {
+ if ((pPriv->buffers[i] != NULL)
+ && (pPriv->buffers[i]->attachment == attachment)) {
return i;
}
}
@@ -151,16 +155,16 @@ find_attachment(DRI2BufferPtr *buffer_list, int count, unsigned attachment)
return -1;
}
-static DRI2BufferPtr
+static DRI2Buffer2Ptr
allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
DRI2DrawablePtr pPriv,
unsigned int attachment, unsigned int format,
int dimensions_match)
{
- DRI2BufferPtr buffer;
+ DRI2Buffer2Ptr buffer;
int old_buf;
- old_buf = find_attachment(pPriv->buffers, pPriv->bufferCount, attachment);
+ old_buf = find_attachment(pPriv, attachment);
if ((old_buf < 0)
|| !dimensions_match
@@ -174,14 +178,14 @@ allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
return buffer;
}
-static DRI2BufferPtr *
+static DRI2Buffer2Ptr *
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;
+ DRI2Buffer2Ptr *buffers;
int need_real_front = 0;
int need_fake_front = 0;
int have_fake_front = 0;
@@ -201,68 +205,156 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
buffers = xalloc((count + 1) * sizeof(buffers[0]));
- for (i = 0; i < count; i++) {
- const unsigned attachment = *(attachments++);
- const unsigned format = (has_format) ? *(attachments++) : 0;
+ if (ds->CreateBuffer) {
+ /* Version 2 API with CreateBuffer */
+ 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);
+
+ /* 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 (attachment == DRI2BufferBackLeft) {
+ need_real_front++;
+ front_format = format;
+ }
+
+ if (attachment == DRI2BufferFrontLeft) {
+ need_real_front--;
+ front_format = format;
+
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ need_fake_front++;
+ }
+ }
- buffers[i] = allocate_or_reuse_buffer(pDraw, ds, pPriv, attachment,
- format, dimensions_match);
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ if (attachment == DRI2BufferFakeFrontLeft) {
+ need_fake_front--;
+ have_fake_front = 1;
+ }
+ }
+ }
+ if (need_real_front > 0) {
+ buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv,
+ DRI2BufferFrontLeft,
+ front_format, dimensions_match);
+ }
- /* 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 (attachment == DRI2BufferBackLeft) {
- need_real_front++;
- front_format = format;
+ if (need_fake_front > 0) {
+ buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv,
+ DRI2BufferFakeFrontLeft,
+ front_format, dimensions_match);
+ have_fake_front = 1;
}
- if (attachment == DRI2BufferFrontLeft) {
- need_real_front--;
- front_format = format;
+ *out_count = i;
- if (pDraw->type == DRAWABLE_WINDOW) {
- need_fake_front++;
+
+ 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);
+ }
+ } else {
+ DRI2BufferPtr buffers1;
+ unsigned int temp_buf[32];
+ unsigned int *temp = temp_buf;
+ int i;
+ int buffers_match = 1;
+
+ /* Version 1 API with CreateBuffers */
+
+ if ((count + 1) > 32) {
+ temp = xalloc((count + 1) * sizeof(temp[0]));
}
- if (pDraw->type == DRAWABLE_WINDOW) {
- if (attachment == DRI2BufferFakeFrontLeft) {
+ for (i = 0; i < count; i++) {
+ const unsigned attachment = *(attachments++);
+
+ /* Version 1 doesn't deal with the format at all */
+ if (has_format)
+ attachments++;
+
+ /*
+ * Make sure the client also gets the front buffer when
+ * it asks for a back buffer
+ */
+ if (attachment == DRI2BufferBackLeft)
+ need_real_front++;
+
+ /*
+ * 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 (attachment == DRI2BufferFrontLeft) {
+ need_real_front--;
+ if (pDraw->type == DRAWABLE_WINDOW)
+ need_fake_front++;
+ }
+ if (pDraw->type == DRAWABLE_WINDOW &&
+ attachment == DRI2BufferFakeFrontLeft)
+ {
need_fake_front--;
have_fake_front = 1;
}
+
+ temp[i] = attachment;
}
- }
- if (need_real_front > 0) {
- buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv,
- DRI2BufferFrontLeft,
- front_format, dimensions_match);
- }
+ if (need_real_front > 0)
+ temp[count++] = DRI2BufferFrontLeft;
- if (need_fake_front > 0) {
- buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv,
- DRI2BufferFakeFrontLeft,
- front_format, dimensions_match);
- have_fake_front = 1;
- }
+ if (need_fake_front > 0) {
+ temp[count++] = DRI2BufferFakeFrontLeft;
+ have_fake_front = 1;
+ }
+
+ if (count != pPriv->bufferCount)
+ buffers_match = 0;
+ else {
+ for (i = 0; i < count; i++)
+ if (pPriv->buffers[i]->attachment != temp[i]) {
+ buffers_match = 0;
+ break;
+ }
+ }
+ if (pPriv->buffers == NULL || !dimensions_match || !buffers_match)
+ {
+ buffers1 = (*ds->CreateBuffers)(pDraw, temp, count);
+ if (pPriv->buffers != NULL)
+ (*ds->DestroyBuffers)(pDraw, (DRI2BufferPtr) pPriv->buffers[0],
+ pPriv->bufferCount);
+ }
+ else
+ buffers1 = (DRI2BufferPtr) pPriv->buffers[0];
- *out_count = i;
+ for (i = 0; i < count; i++)
+ buffers[i] = (DRI2Buffer2Ptr) &buffers1[i];
+ *out_count = count;
- if (pPriv->buffers != NULL) {
- for (i = 0; i < pPriv->bufferCount; i++) {
- if (pPriv->buffers[i] != NULL) {
- (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
- }
- }
+ if (pPriv->buffers)
+ xfree (pPriv->buffers);
- xfree(pPriv->buffers);
+ if (temp != temp_buf) {
+ xfree(temp);
+ }
}
-
pPriv->buffers = buffers;
pPriv->bufferCount = *out_count;
pPriv->width = pDraw->width;
@@ -292,7 +384,7 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
return pPriv->buffers;
}
-DRI2BufferPtr *
+DRI2Buffer2Ptr *
DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
unsigned int *attachments, int count, int *out_count)
{
@@ -300,7 +392,7 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
out_count, FALSE);
}
-DRI2BufferPtr *
+DRI2Buffer2Ptr *
DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height,
unsigned int *attachments, int count, int *out_count)
{
@@ -326,13 +418,13 @@ DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
for (i = 0; i < pPriv->bufferCount; i++)
{
if (pPriv->buffers[i]->attachment == dest)
- pDestBuffer = pPriv->buffers[i];
+ pDestBuffer = (DRI2BufferPtr) pPriv->buffers[i];
if (pPriv->buffers[i]->attachment == src)
- pSrcBuffer = pPriv->buffers[i];
+ pSrcBuffer = (DRI2BufferPtr) pPriv->buffers[i];
}
if (pSrcBuffer == NULL || pDestBuffer == NULL)
return BadValue;
-
+
(*ds->CopyRegion)(pDraw, pRegion, pDestBuffer, pSrcBuffer);
return Success;
@@ -349,7 +441,7 @@ DRI2DestroyDrawable(DrawablePtr pDraw)
pPriv = DRI2GetDrawable(pDraw);
if (pPriv == NULL)
return;
-
+
pPriv->refCount--;
if (pPriv->refCount > 0)
return;
@@ -357,8 +449,13 @@ DRI2DestroyDrawable(DrawablePtr pDraw)
if (pPriv->buffers != NULL) {
int i;
- for (i = 0; i < pPriv->bufferCount; i++) {
- (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
+ if (ds->DestroyBuffer) {
+ for (i = 0; i < pPriv->bufferCount; i++) {
+ (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
+ }
+ } else {
+ (*ds->DestroyBuffers)(pDraw, (DRI2BufferPtr) pPriv->buffers[0],
+ pPriv->bufferCount);
}
xfree(pPriv->buffers);
@@ -417,18 +514,36 @@ 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->CreateBuffer = info->CreateBuffer;
- ds->DestroyBuffer = info->DestroyBuffer;
+
+ /* Prefer the new one-at-a-time buffer API */
+ if (info->version >= 2 && info->CreateBuffer && info->DestroyBuffer) {
+ ds->CreateBuffer = info->CreateBuffer;
+ ds->DestroyBuffer = info->DestroyBuffer;
+ ds->CreateBuffers = NULL;
+ ds->DestroyBuffers = NULL;
+ } else if (info->CreateBuffers && info->DestroyBuffers) {
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[DRI2] Version 1 API (broken front buffer rendering)\n");
+ ds->CreateBuffer = NULL;
+ ds->DestroyBuffer = NULL;
+ ds->CreateBuffers = info->CreateBuffers;
+ ds->DestroyBuffers = info->DestroyBuffers;
+ } else {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] Missing buffer management functions\n");
+ xfree(ds);
+ return FALSE;
+ }
+
+ if (!info->CopyRegion) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] Missing copy region function\n");
+ xfree(ds);
+ return FALSE;
+ }
ds->CopyRegion = info->CopyRegion;
dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index b3d02a9..22ee983 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -35,16 +35,27 @@
#include <X11/extensions/dri2tokens.h>
+/* Version 1 structure (for ABI compatibility) */
typedef struct {
unsigned int attachment;
unsigned int name;
unsigned int pitch;
unsigned int cpp;
unsigned int flags;
- unsigned int format;
void *driverPrivate;
} DRI2BufferRec, *DRI2BufferPtr;
+/* Version 2 structure (with format at the end) */
+typedef struct {
+ unsigned int attachment;
+ unsigned int name;
+ unsigned int pitch;
+ unsigned int cpp;
+ unsigned int flags;
+ void *driverPrivate;
+ unsigned int format;
+} DRI2Buffer2Rec, *DRI2Buffer2Ptr;
+
typedef DRI2BufferPtr (*DRI2CreateBuffersProcPtr)(DrawablePtr pDraw,
unsigned int *attachments,
int count);
@@ -59,11 +70,11 @@ typedef void (*DRI2CopyRegionProcPtr)(DrawablePtr pDraw,
typedef void (*DRI2WaitProcPtr)(WindowPtr pWin,
unsigned int sequence);
-typedef DRI2BufferPtr (*DRI2CreateBufferProcPtr)(DrawablePtr pDraw,
+typedef DRI2Buffer2Ptr (*DRI2CreateBufferProcPtr)(DrawablePtr pDraw,
unsigned int attachment,
unsigned int format);
typedef void (*DRI2DestroyBufferProcPtr)(DrawablePtr pDraw,
- DRI2BufferPtr buffer);
+ DRI2Buffer2Ptr buffer);
/**
* Version of the DRI2InfoRec structure defined in this header
@@ -108,7 +119,7 @@ extern _X_EXPORT int DRI2CreateDrawable(DrawablePtr pDraw);
extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw);
-extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffers(DrawablePtr pDraw,
+extern _X_EXPORT DRI2Buffer2Ptr *DRI2GetBuffers(DrawablePtr pDraw,
int *width,
int *height,
unsigned int *attachments,
@@ -138,7 +149,7 @@ extern _X_EXPORT int DRI2CopyRegion(DrawablePtr pDraw,
*/
extern _X_EXPORT void DRI2Version(int *major, int *minor);
-extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffersWithFormat(DrawablePtr pDraw,
+extern _X_EXPORT DRI2Buffer2Ptr *DRI2GetBuffersWithFormat(DrawablePtr pDraw,
int *width, int *height, unsigned int *attachments, int count,
int *out_count);
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index 029dce8..ea160ac 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -195,7 +195,7 @@ ProcDRI2DestroyDrawable(ClientPtr client)
static void
send_buffers_reply(ClientPtr client, DrawablePtr pDrawable,
- DRI2BufferPtr *buffers, int count, int width, int height)
+ DRI2Buffer2Ptr *buffers, int count, int width, int height)
{
xDRI2GetBuffersReply rep;
int skip = 0;
@@ -245,7 +245,7 @@ ProcDRI2GetBuffers(ClientPtr client)
{
REQUEST(xDRI2GetBuffersReq);
DrawablePtr pDrawable;
- DRI2BufferPtr *buffers;
+ DRI2Buffer2Ptr *buffers;
int status, width, height, count;
unsigned int *attachments;
@@ -268,7 +268,7 @@ ProcDRI2GetBuffersWithFormat(ClientPtr client)
{
REQUEST(xDRI2GetBuffersReq);
DrawablePtr pDrawable;
- DRI2BufferPtr *buffers;
+ DRI2Buffer2Ptr *buffers;
int status, width, height, count;
unsigned int *attachments;
More information about the xorg-commit
mailing list