[cairo] pixman BGRA support

Mark Kettenis kettenis at openbsd.org
Sun Mar 8 13:12:33 PDT 2009


Hi,

I'm trying to make Xorg work on a Tech Source Raptor GFX-8M graphics
card on OpenBSD/sparc64.  This card is based on the Number 9 I128-II
chip, which has a little-endian framebuffer, that essentially uses
ARGB pixel representation.  However, since I'm using it on a
big-endian machine, the pixel representation as seen by the host CPU
is BGRA.  As far as I can tell, the graphics hardware does not support
byte swapping in hardware like the ATI cards that Sun used in many of
their PCI framebuffers.

The diff below adds BGRA support to pixman.  I have diffs for Xrender
and cairo as well, that make firefox work fine (without them the most
obvious problem is that text seems to be drawn on a yellow
background).

Mark


diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index b47ba16..a451e80 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -120,6 +120,36 @@ fbFetch_x8b8g8r8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
 }
 
 static FASTCALL void
+fbFetch_b8g8r8a8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
+{
+    const uint32_t *bits = pict->bits + y*pict->rowstride;
+    const uint32_t *pixel = (uint32_t *)bits + x;
+    const uint32_t *end = pixel + width;
+    while (pixel < end) {
+	uint32_t p = READ(pict, pixel++);
+	*buffer++ = ((p & 0xff000000) >> 24) |
+	    ((p & 0x00ff0000) >> 8) |
+	    ((p & 0x0000ff00) << 8) |
+	    ((p & 0x000000ff) << 24);
+    }
+}
+
+static FASTCALL void
+fbFetch_b8g8r8x8 (bits_image_t *pict, int x, int y, int width, uint32_t *buffer)
+{
+    const uint32_t *bits = pict->bits + y*pict->rowstride;
+    const uint32_t *pixel = (uint32_t *)bits + x;
+    const uint32_t *end = pixel + width;
+    while (pixel < end) {
+	uint32_t p = READ(pict, pixel++);
+	*buffer++ = 0xff000000 |
+	    ((p & 0xff000000) >> 24) |
+	    ((p & 0x00ff0000) >> 8) |
+	    ((p & 0x0000ff00) << 8);
+    }
+}
+
+static FASTCALL void
 fbFetch_a2b10g10r10 (bits_image_t *pict, int x, int y, int width, uint64_t *buffer)
 {
     const uint32_t *bits = pict->bits + y*pict->rowstride;
@@ -693,6 +723,8 @@ fetchProc32 ACCESS(pixman_fetchProcForPicture32) (bits_image_t * pict)
     case PIXMAN_x8r8g8b8: return fbFetch_x8r8g8b8;
     case PIXMAN_a8b8g8r8: return fbFetch_a8b8g8r8;
     case PIXMAN_x8b8g8r8: return fbFetch_x8b8g8r8;
+    case PIXMAN_b8g8r8a8: return fbFetch_b8g8r8a8;
+    case PIXMAN_b8g8r8x8: return fbFetch_b8g8r8x8;
     /* These two require wide compositing */
     case PIXMAN_a2b10g10r10: return NULL;
     case PIXMAN_x2b10g10r10: return NULL;
@@ -844,6 +876,30 @@ fbFetchPixel_x8b8g8r8 (bits_image_t *pict, int offset, int line)
 }
 
 static FASTCALL uint32_t
+fbFetchPixel_b8g8r8a8 (bits_image_t *pict, int offset, int line)
+{
+    uint32_t *bits = pict->bits + line*pict->rowstride;
+    uint32_t  pixel = READ(pict, (uint32_t *)bits + offset);
+
+    return ((pixel & 0xff000000) >> 24 |
+	    (pixel & 0x00ff0000) >> 8 |
+	    (pixel & 0x0000ff00) << 8 |
+	    (pixel & 0x000000ff) << 24);
+}
+
+static FASTCALL uint32_t
+fbFetchPixel_b8g8r8x8 (bits_image_t *pict, int offset, int line)
+{
+    uint32_t *bits = pict->bits + line*pict->rowstride;
+    uint32_t  pixel = READ(pict, (uint32_t *)bits + offset);
+
+    return ((0xff000000) |
+	    (pixel & 0xff000000) >> 24 |
+	    (pixel & 0x00ff0000) >> 8 |
+	    (pixel & 0x0000ff00) << 8);
+}
+
+static FASTCALL uint32_t
 fbFetchPixel_r8g8b8 (bits_image_t *pict, int offset, int line)
 {
     uint32_t *bits = pict->bits + line*pict->rowstride;
@@ -1283,6 +1339,8 @@ fetchPixelProc32 ACCESS(pixman_fetchPixelProcForPicture32) (bits_image_t * pict)
     case PIXMAN_x8r8g8b8: return fbFetchPixel_x8r8g8b8;
     case PIXMAN_a8b8g8r8: return fbFetchPixel_a8b8g8r8;
     case PIXMAN_x8b8g8r8: return fbFetchPixel_x8b8g8r8;
+    case PIXMAN_b8g8r8a8: return fbFetchPixel_b8g8r8a8;
+    case PIXMAN_b8g8r8x8: return fbFetchPixel_b8g8r8x8;
     /* These two require wide compositing */
     case PIXMAN_a2b10g10r10: return fbFetchPixel32_generic_lossy;
     case PIXMAN_x2b10g10r10: return fbFetchPixel32_generic_lossy;
@@ -1428,6 +1486,33 @@ fbStore_x8b8g8r8 (pixman_image_t *image,
 }
 
 static FASTCALL void
+fbStore_b8g8r8a8 (pixman_image_t *image,
+		  uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
+{
+    int i;
+    uint32_t *pixel = (uint32_t *)bits + x;
+    for (i = 0; i < width; ++i)
+	WRITE(image, pixel++,
+	    ((values[i] >> 24) & 0x000000ff) |
+	    ((values[i] >>  8) & 0x0000ff00) |
+	    ((values[i] <<  8) & 0x00ff0000) |
+	    ((values[i] << 24) & 0xff000000));
+}
+
+static FASTCALL void
+fbStore_b8g8r8x8 (pixman_image_t *image,
+		  uint32_t *bits, const uint32_t *values, int x, int width, const pixman_indexed_t * indexed)
+{
+    int i;
+    uint32_t *pixel = (uint32_t *)bits + x;
+    for (i = 0; i < width; ++i)
+	WRITE(image, pixel++,
+	    ((values[i] >>  8) & 0x0000ff00) |
+	    ((values[i] <<  8) & 0x00ff0000) |
+	    ((values[i] << 24) & 0xff000000));
+}
+
+static FASTCALL void
 fbStore_r8g8b8 (pixman_image_t *image,
 		uint32_t *bits, const uint32_t *values, int x, int width,
 		const pixman_indexed_t * indexed)
@@ -1816,6 +1901,8 @@ storeProc32 ACCESS(pixman_storeProcForPicture32) (bits_image_t * pict)
     case PIXMAN_x8r8g8b8: return fbStore_x8r8g8b8;
     case PIXMAN_a8b8g8r8: return fbStore_a8b8g8r8;
     case PIXMAN_x8b8g8r8: return fbStore_x8b8g8r8;
+    case PIXMAN_b8g8r8a8: return fbStore_b8g8r8a8;
+    case PIXMAN_b8g8r8x8: return fbStore_b8g8r8x8;
 
         /* 24bpp formats */
     case PIXMAN_r8g8b8: return fbStore_r8g8b8;
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index e80c479..d3220cb 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -631,6 +631,8 @@ color_to_pixel (pixman_color_t *color,
 	  format == PIXMAN_x8r8g8b8	||
 	  format == PIXMAN_a8b8g8r8	||
 	  format == PIXMAN_x8b8g8r8	||
+	  format == PIXMAN_b8g8r8a8	||
+	  format == PIXMAN_b8g8r8x8	||
 	  format == PIXMAN_r5g6b5	||
 	  format == PIXMAN_b5g6r5	||
 	  format == PIXMAN_a8))
@@ -645,6 +647,13 @@ color_to_pixel (pixman_color_t *color,
 	    ((c & 0x0000ff00) >>  0) |
 	    ((c & 0x000000ff) << 16);
     }
+    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
+    {
+	c = ((c & 0xff000000) >> 24) |
+	    ((c & 0x00ff0000) >>  8) |
+	    ((c & 0x0000ff00) <<  8) |
+	    ((c & 0x000000ff) << 24);
+    }
 
     if (format == PIXMAN_a8)
 	c = c >> 24;
@@ -761,6 +770,8 @@ pixman_image_can_get_solid (pixman_image_t *image)
     case PIXMAN_x8r8g8b8:
     case PIXMAN_a8b8g8r8:
     case PIXMAN_x8b8g8r8:
+    case PIXMAN_b8g8r8a8:
+    case PIXMAN_b8g8r8x8:
     case PIXMAN_r8g8b8:
     case PIXMAN_b8g8r8:
     case PIXMAN_r5g6b5:
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index 6e04df6..8734dc5 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -461,6 +461,8 @@ pixman_format_supported_destination (pixman_format_code_t format)
     case PIXMAN_x8r8g8b8:
     case PIXMAN_a8b8g8r8:
     case PIXMAN_x8b8g8r8:
+    case PIXMAN_b8g8r8a8:
+    case PIXMAN_b8g8r8x8:
     case PIXMAN_r8g8b8:
     case PIXMAN_b8g8r8:
     case PIXMAN_r5g6b5:
@@ -531,6 +533,8 @@ pixman_format_supported_source (pixman_format_code_t format)
     case PIXMAN_x8r8g8b8:
     case PIXMAN_a8b8g8r8:
     case PIXMAN_x8b8g8r8:
+    case PIXMAN_b8g8r8a8:
+    case PIXMAN_b8g8r8x8:
     case PIXMAN_r8g8b8:
     case PIXMAN_b8g8r8:
     case PIXMAN_r5g6b5:
diff --git a/pixman/pixman.h b/pixman/pixman.h
index 49c39d5..d207b56 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -647,10 +647,12 @@ struct pixman_indexed
 #define PIXMAN_TYPE_GRAY	5
 #define PIXMAN_TYPE_YUY2	6
 #define PIXMAN_TYPE_YV12	7
+#define PIXMAN_TYPE_BGRA	8
 
 #define PIXMAN_FORMAT_COLOR(f)				\
 	(PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ARGB ||	\
-	 PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ABGR)
+	 PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ABGR ||	\
+	 PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_BGRA)
 
 /* 32bpp formats */
 typedef enum {
@@ -658,6 +660,8 @@ typedef enum {
     PIXMAN_x8r8g8b8 =	PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,8,8,8),
     PIXMAN_a8b8g8r8 =	PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,8,8,8,8),
     PIXMAN_x8b8g8r8 =	PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,0,8,8,8),
+    PIXMAN_b8g8r8a8 =	PIXMAN_FORMAT(32,PIXMAN_TYPE_BGRA,8,8,8,8),
+    PIXMAN_b8g8r8x8 =	PIXMAN_FORMAT(32,PIXMAN_TYPE_BGRA,0,8,8,8),
     PIXMAN_x2b10g10r10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,0,10,10,10),
     PIXMAN_a2b10g10r10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,2,10,10,10),
 



More information about the cairo mailing list