[cairo] fbcompose.c: Final merge

Billy Biggs vektor at dumbterm.net
Wed Aug 10 20:41:45 PDT 2005


  Attached is the latest patch to cairo's pixman for merging fbcompose.c
from xserver.  With the latest commits from today, the only test which
fails on this code is "clip-operator".  I have convinced myself that the
results in pixman are incorrect, and that the new output after this
patch should replace the reference image.

  There are two operators that fail, each in different ways.

  - xor fails on fbCombineXorU.  The pixman code uses this algorithm:
      "x_c = (x_c * a) / 255   + (y_c * b) / 255"  while xserver does:
      "x_c = (x_c * a + y_c * b) / 255".  The difference is in the
    precision used for the intermediate calculation before the division
    by 255.  Since the xserver code has higher precision, I think it is
    more correct.

  - saturate fails on fbCombineSaturateU.  The alpha in pixman is
    calculated as "as = (~d_alpha  << 8) / s_alpha" when da > sa while
    xserver uses  "as = (~d_alpha * 255) / s_alpha".  I think xserver is
    correct here.

  I've also attached the diff between fbcompose.c in xserver against the
port to pixman.

  OK to commit? :)

  -Billy

-------------- next part --------------
A non-text attachment was scrubbed...
Name: fbcompose-merge.diff.gz
Type: application/x-gunzip
Size: 7082 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20050810/40d05329/fbcompose-merge.diff.bin
-------------- next part --------------
--- ../../../../xfake/xserver/fb/fbcompose.c	2005-08-10 23:17:31.732137304 -0400
+++ fbcompose.c	2005-08-10 23:16:31.035364616 -0400
@@ -26,13 +26,45 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
-#include "fb.h"
+#include <stdio.h>
+#include "pixman-xserver-compat.h"
+#include "fbpict.h"
 
 #ifdef RENDER
 
-#include "picturestr.h"
-#include "mipict.h"
-#include "fbpict.h"
+#include "pixregionint.h"
+
+// #define PIXMAN_CONVOLUTION
+// #define PIXMAN_GRADIENTS
+// #define PIXMAN_INDEXED_FORMATS
+
+static Bool
+PictureTransformPoint3d (pixman_transform_t *transform,
+                         PictVector *vector)
+{
+    PictVector	    result;
+    int		    i, j;
+    xFixed_32_32    partial;
+    xFixed_48_16    v;
+
+    for (j = 0; j < 3; j++)
+    {
+	v = 0;
+	for (i = 0; i < 3; i++)
+	{
+	    partial = ((xFixed_48_16) transform->matrix[j][i] *
+		       (xFixed_48_16) vector->vector[i]);
+	    v += partial >> 16;
+	}
+	if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+	    return FALSE;
+	result.vector[j] = (xFixed) v;
+    }
+    if (!result.vector[2])
+	return FALSE;
+    *vector = result;
+    return TRUE;
+}
 
 #define mod(a,b)	((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
 
@@ -509,7 +541,7 @@
 
 static fetchProc fetchProcForPicture (PicturePtr pict)
 {
-    switch(pict->format) {
+    switch(pict->format_code) {
     case PICT_a8r8g8b8: return fbFetch_a8r8g8b8;
     case PICT_x8r8g8b8: return fbFetch_x8r8g8b8;
     case PICT_a8b8g8r8: return fbFetch_a8b8g8r8;
@@ -937,7 +969,7 @@
 
 static fetchPixelProc fetchPixelProcForPicture (PicturePtr pict)
 {
-    switch(pict->format) {
+    switch(pict->format_code) {
     case PICT_a8r8g8b8: return fbFetchPixel_a8r8g8b8;
     case PICT_x8r8g8b8: return fbFetchPixel_x8r8g8b8;
     case PICT_a8b8g8r8: return fbFetchPixel_a8b8g8r8;
@@ -1374,7 +1406,7 @@
 
 static storeProc storeProcForPicture (PicturePtr pict)
 {
-    switch(pict->format) {
+    switch(pict->format_code) {
     case PICT_a8r8g8b8: return fbStore_a8r8g8b8;
     case PICT_x8r8g8b8: return fbStore_x8r8g8b8;
     case PICT_a8b8g8r8: return fbStore_a8b8g8r8;
@@ -2604,7 +2636,11 @@
     CARD32 color;
     CARD32 *end;
     fetchPixelProc fetch = fetchPixelProcForPicture(pict);
+#ifdef PIXMAN_INDEXED_FORMATS
     miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
+#else
+    miIndexedPtr indexed = 0;
+#endif
 
     fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
     bits += yoff*stride + (xoff*bpp >> FB_SHIFT);
@@ -2623,7 +2659,11 @@
     int bpp;
     int xoff, yoff;
     fetchProc fetch = fetchProcForPicture(pict);
+#ifdef PIXMAN_INDEXED_FORMATS
     miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
+#else
+    miIndexedPtr indexed = 0;
+#endif
 
     fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
     x += xoff;
@@ -2634,11 +2674,10 @@
     fetch(bits, x, width, buffer, indexed);
 }
 
-#define MOD(a,b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b))
 #define DIV(a,b) ((((a) < 0) == ((b) < 0)) ? (a) / (b) :\
         ((a) - (b) + 1 - (((b) < 0) << 1)) / (b))
 
-
+#ifdef PIXMAN_GRADIENTS
 static CARD32 gradientPixel(const SourcePictPtr pGradient, xFixed_48_16 pos, unsigned int spread)
 {
     int ipos = (pos * PICT_GRADIENT_STOPTABLE_SIZE - 1) >> 16;
@@ -2848,7 +2887,7 @@
         }
     }
 }
-
+#endif /* PIXMAN_GRADIENTS */
 
 
 static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
@@ -2862,7 +2901,11 @@
     PictVector  unit;
     int         i;
     BoxRec	box;
+#ifdef PIXMAN_INDEXED_FORMATS
     miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
+#else
+    miIndexedPtr indexed = 0;
+#endif
 
     fetch = fetchPixelProcForPicture(pict);
 
@@ -2887,10 +2930,10 @@
         unit.vector[2] = 0;
     }
 
-    if (pict->filter == PictFilterNearest)
+    if (pict->filter == PIXMAN_FILTER_NEAREST || pict->filter == PIXMAN_FILTER_FAST)
     {
         if (pict->repeat == RepeatNormal) {
-            if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
+            if (PIXREGION_NUM_RECTS(pict->pCompositeClip) == 1) {
                 box = pict->pCompositeClip->extents;
                 for (i = 0; i < width; ++i) {
                     if (!v.vector[2]) {
@@ -2911,7 +2954,7 @@
                     } else {
                         y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
                         x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width);
-                        if (POINT_IN_REGION (0, pict->pCompositeClip, x, y, &box))
+                        if (pixman_region_contains_point (pict->pCompositeClip, x, y, &box))
                             buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
                         else
                             buffer[i] = 0;
@@ -2922,7 +2965,7 @@
                 }
             }
         } else {
-            if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
+            if (PIXREGION_NUM_RECTS(pict->pCompositeClip) == 1) {
                 box = pict->pCompositeClip->extents;
                 for (i = 0; i < width; ++i) {
                     if (!v.vector[2]) {
@@ -2944,7 +2987,7 @@
                     } else {
                         y = DIV(v.vector[1],v.vector[2]);
                         x = DIV(v.vector[0],v.vector[2]);
-                        if (POINT_IN_REGION (0, pict->pCompositeClip, x, y, &box))
+                        if (pixman_region_contains_point (pict->pCompositeClip, x, y, &box))
                             buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
                         else
                             buffer[i] = 0;
@@ -2955,9 +2998,9 @@
                 }
             }
         }
-    } else if (pict->filter == PictFilterBilinear) {
+    } else if (pict->filter == PIXMAN_FILTER_BILINEAR || pict->filter == PIXMAN_FILTER_GOOD || pict->filter == PIXMAN_FILTER_BEST) {
         if (pict->repeat == RepeatNormal) {
-            if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
+            if (PIXREGION_NUM_RECTS(pict->pCompositeClip) == 1) {
                 box = pict->pCompositeClip->extents;
                 for (i = 0; i < width; ++i) {
                     if (!v.vector[2]) {
@@ -3035,14 +3078,14 @@
 
                         b = bits + (y1 + pict->pDrawable->y)*stride;
 
-                        tl = POINT_IN_REGION(0, pict->pCompositeClip, x1, y1, &box)
+                        tl = pixman_region_contains_point(pict->pCompositeClip, x1, y1, &box)
                              ? fetch(b, x1 + pict->pDrawable->x, indexed) : 0;
-                        tr = POINT_IN_REGION(0, pict->pCompositeClip, x2, y1, &box)
+                        tr = pixman_region_contains_point(pict->pCompositeClip, x2, y1, &box)
                              ? fetch(b, x2 + pict->pDrawable->x, indexed) : 0;
                         b = bits + (y2 + pict->pDrawable->y)*stride;
-                        bl = POINT_IN_REGION(0, pict->pCompositeClip, x1, y2, &box)
+                        bl = pixman_region_contains_point(pict->pCompositeClip, x1, y2, &box)
                              ? fetch(b, x1 + pict->pDrawable->x, indexed) : 0;
-                        br = POINT_IN_REGION(0, pict->pCompositeClip, x2, y2, &box)
+                        br = pixman_region_contains_point(pict->pCompositeClip, x2, y2, &box)
                              ? fetch(b, x2 + pict->pDrawable->x, indexed) : 0;
 
                         r = 0;
@@ -3060,7 +3103,7 @@
                 }
             }
         } else {
-            if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
+            if (PIXREGION_NUM_RECTS(pict->pCompositeClip) == 1) {
                 box = pict->pCompositeClip->extents;
                 for (i = 0; i < width; ++i) {
                     if (!v.vector[2]) {
@@ -3136,14 +3179,14 @@
                         b = bits + (y1 + pict->pDrawable->y)*stride;
                         x_off = x1 + pict->pDrawable->x;
 
-                        tl = POINT_IN_REGION(0, pict->pCompositeClip, x1, y1, &box)
+                        tl = pixman_region_contains_point(pict->pCompositeClip, x1, y1, &box)
                              ? fetch(b, x_off, indexed) : 0;
-                        tr = POINT_IN_REGION(0, pict->pCompositeClip, x2, y1, &box)
+                        tr = pixman_region_contains_point(pict->pCompositeClip, x2, y1, &box)
                              ? fetch(b, x_off + 1, indexed) : 0;
                         b += stride;
-                        bl = POINT_IN_REGION(0, pict->pCompositeClip, x1, y2, &box)
+                        bl = pixman_region_contains_point(pict->pCompositeClip, x1, y2, &box)
                              ? fetch(b, x_off, indexed) : 0;
-                        br = POINT_IN_REGION(0, pict->pCompositeClip, x2, y2, &box)
+                        br = pixman_region_contains_point(pict->pCompositeClip, x2, y2, &box)
                              ? fetch(b, x_off + 1, indexed) : 0;
 
                         r = 0;
@@ -3161,6 +3204,7 @@
                 }
             }
         }
+#ifdef PIXMAN_CONVOLUTION
     } else if (pict->filter == PictFilterConvolution) {
         xFixed *params = pict->filter_params;
         INT32 cwidth = xFixedToInt(params[0]);
@@ -3190,7 +3234,7 @@
                     for (x = x1; x < x2; x++) {
                         if (*p) {
                             int tx = (pict->repeat == RepeatNormal) ? MOD (x, pict->pDrawable->width) : x;
-                            if (POINT_IN_REGION (0, pict->pCompositeClip, tx, ty, &box)) {
+                            if (pixman_region_contains_point (pict->pCompositeClip, tx, ty, &box)) {
                                 FbBits *b = bits + (ty + pict->pDrawable->y)*stride;
                                 CARD32 c = fetch(b, tx + pict->pDrawable->x, indexed);
 
@@ -3218,6 +3262,7 @@
             v.vector[1] += unit.vector[1];
             v.vector[2] += unit.vector[2];
         }
+#endif
     }
 }
 
@@ -3257,7 +3302,11 @@
     int bpp;
     int xoff, yoff;
     storeProc store = storeProcForPicture(pict);
+#ifdef PIXMAN_INDEXED_FORMATS
     miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
+#else
+    miIndexedPtr indexed = 0;
+#endif
 
     fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
     x += xoff;
@@ -3276,7 +3325,11 @@
     int ax, ay;
     storeProc store;
     storeProc astore;
+#ifdef PIXMAN_INDEXED_FORMATS
     miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
+#else
+    miIndexedPtr indexed = 0;
+#endif
     miIndexedPtr aindexed;
 
     if (!pict->alphaMap) {
@@ -3286,7 +3339,11 @@
 
     store = storeProcForPicture(pict);
     astore = storeProcForPicture(pict->alphaMap);
+#ifdef PIXMAN_INDEXED_FORMATS
     aindexed = (miIndexedPtr) pict->alphaMap->pFormat->index.devPrivate;
+#else
+    aindexed = 0;
+#endif
 
     ax = x;
     ay = y;
@@ -3318,32 +3375,46 @@
     scanStoreProc store;
     scanFetchProc fetchSrc = 0, fetchMask = 0, fetchDest = 0;
 
-    if (data->op == PictOpClear)
+    if (data->op == PIXMAN_OPERATOR_CLEAR)
         fetchSrc = 0;
     else if (!data->src->pDrawable) {
+#ifdef PIXMAN_GRADIENTS
         if (data->src->pSourcePict)
             fetchSrc = fbFetchSourcePict;
+#endif
     } else if (data->src->alphaMap)
         fetchSrc = fbFetchExternalAlpha;
     else if (data->src->repeat == RepeatNormal &&
              data->src->pDrawable->width == 1 && data->src->pDrawable->height == 1)
         fetchSrc = fbFetchSolid;
+#ifdef PIXMAN_CONVOLUTION
     else if (!data->src->transform && data->src->filter != PictFilterConvolution)
         fetchSrc = fbFetch;
+#else
+    else if (!data->src->transform)
+        fetchSrc = fbFetch;
+#endif
     else
         fetchSrc = fbFetchTransformed;
 
-    if (data->mask && data->op != PictOpClear) {
+    if (data->mask && data->op != PIXMAN_OPERATOR_CLEAR) {
         if (!data->mask->pDrawable) {
+#ifdef PIXMAN_GRADIENTS
             if (data->mask->pSourcePict)
                 fetchMask = fbFetchSourcePict;
+#endif
         } else if (data->mask->alphaMap)
             fetchMask = fbFetchExternalAlpha;
         else if (data->mask->repeat == RepeatNormal
                  && data->mask->pDrawable->width == 1 && data->mask->pDrawable->height == 1)
             fetchMask = fbFetchSolid;
+#ifdef PIXMAN_CONVOLUTION
         else if (!data->mask->transform && data->mask->filter != PictFilterConvolution)
             fetchMask = fbFetch;
+#else
+        else if (!data->mask->transform)
+            fetchMask = fbFetch;
+#endif
         else
             fetchMask = fbFetchTransformed;
     } else {
@@ -3357,10 +3428,10 @@
         fetchDest = fbFetch;
         store = fbStore;
     }
-    if (data->op == PictOpClear || data->op == PictOpSrc)
+    if (data->op == PIXMAN_OPERATOR_CLEAR || data->op == PIXMAN_OPERATOR_SRC)
         fetchDest = 0;
 
-    if (fetchSrc && fetchMask && data->mask && data->mask->componentAlpha && PICT_FORMAT_RGB(data->mask->format)) {
+    if (fetchSrc && fetchMask && data->mask && data->mask->componentAlpha && PICT_FORMAT_RGB(data->mask->format_code)) {
         CARD32 *mask_buffer = dest_buffer + data->width;
         CombineFuncC compose = composeFunctions.combineC[data->op];
         if (!compose)
@@ -3424,7 +3495,7 @@
 }
 
 void
-fbCompositeGeneral (CARD8	op,
+pixman_compositeGeneral (pixman_operator_t	op,
 		    PicturePtr	pSrc,
 		    PicturePtr	pMask,
 		    PicturePtr	pDst,
@@ -3437,7 +3508,7 @@
 		    CARD16	width,
 		    CARD16	height)
 {
-    RegionRec	    region;
+    pixman_region16_t *region;
     int		    n;
     BoxPtr	    pbox;
     Bool	    srcRepeat = FALSE;
@@ -3455,10 +3526,13 @@
 	maskRepeat = pMask->repeat == RepeatNormal && !pMask->transform
                      && (pMask->pDrawable->width != 1 || pMask->pDrawable->height != 1);
 
-    if (op == PictOpOver && !pMask && !pSrc->transform && !PICT_FORMAT_A(pSrc->format) && !pSrc->alphaMap)
-        op = PictOpSrc;
+    if (op == PIXMAN_OPERATOR_OVER && !pMask && !pSrc->transform && !PICT_FORMAT_A(pSrc->format_code) && !pSrc->alphaMap)
+        op = PIXMAN_OPERATOR_SRC;
+
+    region = pixman_region_create();
+    pixman_region_union_rect (region, region, xDst, yDst, width, height);
 
-    if (!miComputeCompositeRegion (&region,
+    if (!FbComputeCompositeRegion (region,
 				   pSrc,
 				   pMask,
 				   pDst,
@@ -3479,8 +3553,8 @@
     if (width > SCANLINE_BUFFER_LENGTH)
         scanline_buffer = (CARD32 *) malloc(width * 3 * sizeof(CARD32));
 
-    n = REGION_NUM_RECTS (&region);
-    pbox = REGION_RECTS (&region);
+    n = pixman_region_num_rects (region);
+    pbox = pixman_region_rects (region);
     while (n--)
     {
 	h = pbox->y2 - pbox->y1;
@@ -3534,7 +3608,7 @@
 	}
 	pbox++;
     }
-    REGION_UNINIT (pDst->pDrawable->pScreen, &region);
+    pixman_region_destroy (region);
 
     if (scanline_buffer != _scanline_buffer)
         free(scanline_buffer);


More information about the cairo mailing list