[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 (®ion,
+ 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 (®ion);
- pbox = REGION_RECTS (®ion);
+ 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, ®ion);
+ pixman_region_destroy (region);
if (scanline_buffer != _scanline_buffer)
free(scanline_buffer);
More information about the cairo
mailing list