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