summaryrefslogtreecommitdiff
path: root/pixman/src
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2006-01-04 16:39:23 +0000
committerCarl Worth <cworth@cworth.org>2006-01-04 16:39:23 +0000
commit19441311e471b661b6b2a6854f030aafa7715d5d (patch)
treeaa0f65afd06692b3fef827d9d2fa72cd3647430d /pixman/src
parent305a83721f5c6423fc1e7fbb0cf1d67c0f92ecb7 (diff)
2005-10-10 David Reveman <davidr@novell.com>
Some major performance improvements to the general composite code used for gradients and transformed images. Like fetching of mask scanline before source scanline so that only the necessary pixels from source needs to be computed in case of gradients or transformed images as source. This patch also include some gradient specific fixes and performance improvement.
Diffstat (limited to 'pixman/src')
-rw-r--r--pixman/src/fbcompose.c1187
-rw-r--r--pixman/src/icimage.c17
-rw-r--r--pixman/src/icimage.h9
3 files changed, 755 insertions, 458 deletions
diff --git a/pixman/src/fbcompose.c b/pixman/src/fbcompose.c
index fa151cb9d..2289cee09 100644
--- a/pixman/src/fbcompose.c
+++ b/pixman/src/fbcompose.c
@@ -66,6 +66,65 @@ PictureTransformPoint3d (pixman_transform_t *transform,
return TRUE;
}
+static unsigned int
+SourcePictureClassify (PicturePtr pict,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ if (pict->pSourcePict->type == SourcePictTypeSolidFill)
+ {
+ pict->pSourcePict->solidFill.class = SourcePictClassHorizontal;
+ }
+ else if (pict->pSourcePict->type == SourcePictTypeLinear)
+ {
+ PictVector v;
+ xFixed_32_32 l;
+ xFixed_48_16 dx, dy, a, b, off;
+ xFixed_48_16 factors[4];
+ int i;
+
+ dx = pict->pSourcePict->linear.p2.x - pict->pSourcePict->linear.p1.x;
+ dy = pict->pSourcePict->linear.p2.y - pict->pSourcePict->linear.p1.y;
+ l = dx * dx + dy * dy;
+ if (l)
+ {
+ a = (dx << 32) / l;
+ b = (dy << 32) / l;
+ }
+ else
+ {
+ a = b = 0;
+ }
+
+ off = (-a * pict->pSourcePict->linear.p1.x
+ -b * pict->pSourcePict->linear.p1.y) >> 16;
+
+ for (i = 0; i < 3; i++)
+ {
+ v.vector[0] = IntToxFixed ((i % 2) * (width - 1) + x);
+ v.vector[1] = IntToxFixed ((i / 2) * (height - 1) + y);
+ v.vector[2] = xFixed1;
+
+ if (pict->transform)
+ {
+ if (!PictureTransformPoint3d (pict->transform, &v))
+ return SourcePictClassUnknown;
+ }
+
+ factors[i] = ((a * v.vector[0] + b * v.vector[1]) >> 16) + off;
+ }
+
+ if (factors[2] == factors[0])
+ pict->pSourcePict->linear.class = SourcePictClassHorizontal;
+ else if (factors[1] == factors[0])
+ pict->pSourcePict->linear.class = SourcePictClassVertical;
+ }
+
+ return pict->pSourcePict->solidFill.class;
+}
+
#define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
#define SCANLINE_BUFFER_LENGTH 2048
@@ -2627,7 +2686,7 @@ FbComposeFunctions composeFunctions = {
};
-static void fbFetchSolid(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+static void fbFetchSolid(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
{
FbBits *bits;
FbStride stride;
@@ -2652,7 +2711,7 @@ static void fbFetchSolid(PicturePtr pict, int x, int y, int width, CARD32 *buffe
*buffer++ = color;
}
-static void fbFetch(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+static void fbFetch(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
{
FbBits *bits;
FbStride stride;
@@ -2745,7 +2804,7 @@ static CARD32 gradientPixel(const SourcePictPtr pGradient, xFixed_48_16 pos, uns
}
}
-static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
{
SourcePictPtr pGradient = pict->pSourcePict;
CARD32 *end = buffer + width;
@@ -2793,27 +2852,74 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
t = ((a*v.vector[0] + b*v.vector[1]) >> 16) + off;
inc = (a * unit.vector[0] + b * unit.vector[1]) >> 16;
}
- while (buffer < end) {
- *buffer++ = gradientPixel(pGradient, t, pict->repeat);
- t += inc;
- }
- } else {
- /* projective transformation */
- while (buffer < end) {
- xFixed_48_16 t;
- if (v.vector[2] == 0) {
- t = 0;
- } else {
- xFixed_48_16 x, y;
- x = ((xFixed_48_16)v.vector[0] << 16) / v.vector[2];
- y = ((xFixed_48_16)v.vector[1] << 16) / v.vector[2];
- t = ((a*x + b*y) >> 16) + off;
- }
- *buffer++ = gradientPixel(pGradient, t, pict->repeat);
- v.vector[0] += unit.vector[0];
- v.vector[1] += unit.vector[1];
- v.vector[2] += unit.vector[2];
- }
+
+ if (pGradient->linear.class == SourcePictClassVertical)
+ {
+ register CARD32 color;
+
+ color = gradientPixel (pGradient, t, pict->repeat);
+ while (buffer < end)
+ *buffer++ = color;
+ }
+ else
+ {
+ while (buffer < end) {
+ if (!mask || *mask++ & maskBits)
+ {
+ *buffer = gradientPixel (pGradient, t, pict->repeat);
+ }
+ ++buffer;
+ t += inc;
+ }
+ }
+ }
+ else /* projective transformation */
+ {
+ xFixed_48_16 t;
+
+ if (pGradient->linear.class == SourcePictClassVertical)
+ {
+ register CARD32 color;
+
+ if (v.vector[2] == 0)
+ {
+ t = 0;
+ }
+ else
+ {
+ xFixed_48_16 x, y;
+
+ x = ((xFixed_48_16) v.vector[0] << 16) / v.vector[2];
+ y = ((xFixed_48_16) v.vector[1] << 16) / v.vector[2];
+ t = ((a * x + b * y) >> 16) + off;
+ }
+
+ color = gradientPixel (pGradient, t, pict->repeat);
+ while (buffer < end)
+ *buffer++ = color;
+ }
+ else
+ {
+ while (buffer < end)
+ {
+ if (!mask || *mask++ & maskBits)
+ {
+ if (v.vector[2] == 0) {
+ t = 0;
+ } else {
+ xFixed_48_16 x, y;
+ x = ((xFixed_48_16)v.vector[0] << 16) / v.vector[2];
+ y = ((xFixed_48_16)v.vector[1] << 16) / v.vector[2];
+ t = ((a*x + b*y) >> 16) + off;
+ }
+ *buffer = gradientPixel(pGradient, t, pict->repeat);
+ }
+ ++buffer;
+ v.vector[0] += unit.vector[0];
+ v.vector[1] += unit.vector[1];
+ v.vector[2] += unit.vector[2];
+ }
+ }
}
} else {
/* radial or conical */
@@ -2848,14 +2954,19 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
ry -= pGradient->radial.fy;
while (buffer < end) {
- double b = 2*(rx*pGradient->radial.dx + ry*pGradient->radial.dy);
- double c = -(rx*rx + ry*ry);
- double det = (b * b) - (4 * pGradient->radial.a * c);
- double s = (-b + sqrt(det))/(2. * pGradient->radial.a);
+ double b, c, det, s;
+
+ if (!mask || *mask++ & maskBits)
+ {
+ b = 2*(rx*pGradient->radial.dx + ry*pGradient->radial.dy);
+ c = -(rx*rx + ry*ry);
+ det = (b * b) - (4 * pGradient->radial.a * c);
+ s = (-b + sqrt(det))/(2. * pGradient->radial.a);
*buffer = gradientPixel(pGradient,
(xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
pict->repeat);
- ++buffer;
+ }
+ ++buffer;
rx += cx;
ry += cy;
}
@@ -2863,22 +2974,26 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
while (buffer < end) {
double x, y;
double b, c, det, s;
- if (rz != 0) {
- x = rx/rz;
- y = ry/rz;
- } else {
- x = y = 0.;
- }
- x -= pGradient->radial.fx;
- y -= pGradient->radial.fy;
- b = 2*(x*pGradient->radial.dx + y*pGradient->radial.dy);
- c = -(x*x + y*y);
- det = (b * b) - (4 * pGradient->radial.a * c);
- s = (-b + sqrt(det))/(2. * pGradient->radial.a);
- *buffer = gradientPixel(pGradient,
- (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
- pict->repeat);
- ++buffer;
+
+ if (!mask || *mask++ & maskBits)
+ {
+ if (rz != 0) {
+ x = rx/rz;
+ y = ry/rz;
+ } else {
+ x = y = 0.;
+ }
+ x -= pGradient->radial.fx;
+ y -= pGradient->radial.fy;
+ b = 2*(x*pGradient->radial.dx + y*pGradient->radial.dy);
+ c = -(x*x + y*y);
+ det = (b * b) - (4 * pGradient->radial.a * c);
+ s = (-b + sqrt(det))/(2. * pGradient->radial.a);
+ *buffer = gradientPixel(pGradient,
+ (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
+ pict->repeat);
+ }
+ ++buffer;
rx += cx;
ry += cy;
rz += cz;
@@ -2891,9 +3006,15 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
ry -= pGradient->conical.center.y/65536.;
while (buffer < end) {
- double angle = atan2(ry, rx) + a;
- *buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
- pict->repeat);
+ double angle;
+
+ if (!mask || *mask++ & maskBits)
+ {
+ angle = atan2(ry, rx) + a;
+
+ *buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
+ pict->repeat);
+ }
++buffer;
rx += cx;
ry += cy;
@@ -2902,17 +3023,22 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
while (buffer < end) {
double x, y;
- if (rz != 0) {
- x = rx/rz;
- y = ry/rz;
- } else {
- x = y = 0.;
- }
- x -= pGradient->conical.center.x/65536.;
- y -= pGradient->conical.center.y/65536.;
- double angle = atan2(y, x) + a;
- *buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
- pict->repeat);
+ double angle;
+
+ if (!mask || *mask++ & maskBits)
+ {
+ if (rz != 0) {
+ x = rx/rz;
+ y = ry/rz;
+ } else {
+ x = y = 0.;
+ }
+ x -= pGradient->conical.center.x/65536.;
+ y -= pGradient->conical.center.y/65536.;
+ angle = atan2(y, x) + a;
+ *buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
+ pict->repeat);
+ }
++buffer;
rx += cx;
ry += cy;
@@ -2923,8 +3049,7 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
}
}
-
-static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
{
FbBits *bits;
FbStride stride;
@@ -2972,38 +3097,44 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
if (PIXREGION_NUM_RECTS(pict->pCompositeClip) == 1) {
box = pict->pCompositeClip->extents;
for (i = 0; i < width; ++i) {
- if (!v.vector[2]) {
- buffer[i] = 0;
- } else {
- if (projective) {
- y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
- x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width);
- } else {
- y = MOD(v.vector[1]>>16, pict->pDrawable->height);
- x = MOD(v.vector[0]>>16, pict->pDrawable->width);
- }
- buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
- }
+ if (!mask || mask[i] & maskBits)
+ {
+ if (!v.vector[2]) {
+ buffer[i] = 0;
+ } else {
+ if (projective) {
+ y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
+ x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width);
+ } else {
+ y = MOD(v.vector[1]>>16, pict->pDrawable->height);
+ x = MOD(v.vector[0]>>16, pict->pDrawable->width);
+ }
+ buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
+ }
+ }
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
}
} else {
for (i = 0; i < width; ++i) {
- if (!v.vector[2]) {
- buffer[i] = 0;
- } else {
- if (projective) {
- y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
- x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width);
- } else {
- y = MOD(v.vector[1]>>16, pict->pDrawable->height);
- x = MOD(v.vector[0]>>16, pict->pDrawable->width);
- }
- 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;
+ if (!mask || mask[i] & maskBits)
+ {
+ if (!v.vector[2]) {
+ buffer[i] = 0;
+ } else {
+ if (projective) {
+ y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
+ x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width);
+ } else {
+ y = MOD(v.vector[1]>>16, pict->pDrawable->height);
+ x = MOD(v.vector[0]>>16, pict->pDrawable->width);
+ }
+ 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;
+ }
}
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
@@ -3014,19 +3145,22 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
if (PIXREGION_NUM_RECTS(pict->pCompositeClip) == 1) {
box = pict->pCompositeClip->extents;
for (i = 0; i < width; ++i) {
- if (!v.vector[2]) {
- buffer[i] = 0;
- } else {
- if (projective) {
- y = DIV(v.vector[1],v.vector[2]);
- x = DIV(v.vector[0],v.vector[2]);
- } else {
- y = v.vector[1]>>16;
- x = v.vector[0]>>16;
- }
- buffer[i] = ((x < box.x1) | (x >= box.x2) | (y < box.y1) | (y >= box.y2)) ?
- 0 : fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
- }
+ if (!mask || mask[i] & maskBits)
+ {
+ if (!v.vector[2]) {
+ buffer[i] = 0;
+ } else {
+ if (projective) {
+ y = DIV(v.vector[1],v.vector[2]);
+ x = DIV(v.vector[0],v.vector[2]);
+ } else {
+ y = v.vector[1]>>16;
+ x = v.vector[0]>>16;
+ }
+ buffer[i] = ((x < box.x1) | (x >= box.x2) | (y < box.y1) | (y >= box.y2)) ?
+ 0 : fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
+ }
+ }
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
@@ -3059,126 +3193,132 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
if (PIXREGION_NUM_RECTS(pict->pCompositeClip) == 1) {
box = pict->pCompositeClip->extents;
for (i = 0; i < width; ++i) {
- if (!v.vector[2]) {
- buffer[i] = 0;
- } else {
- int x1, x2, y1, y2, distx, idistx, disty, idisty;
- FbBits *b;
- CARD32 tl, tr, bl, br, r;
- CARD32 ft, fb;
-
- if (projective) {
- xFixed_48_16 div;
- div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
- x1 = div >> 16;
- distx = ((xFixed)div >> 8) & 0xff;
- div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
- y1 = div >> 16;
- disty = ((xFixed)div >> 8) & 0xff;
- } else {
- x1 = v.vector[0] >> 16;
- distx = (v.vector[0] >> 8) & 0xff;
- y1 = v.vector[1] >> 16;
- disty = (v.vector[1] >> 8) & 0xff;
- }
- x2 = x1 + 1;
- y2 = y1 + 1;
-
- idistx = 256 - distx;
- idisty = 256 - disty;
-
- x1 = MOD (x1, pict->pDrawable->width);
- x2 = MOD (x2, pict->pDrawable->width);
- y1 = MOD (y1, pict->pDrawable->height);
- y2 = MOD (y2, pict->pDrawable->height);
-
- b = bits + (y1 + pict->pDrawable->y)*stride;
-
- tl = fetch(b, x1 + pict->pDrawable->x, indexed);
- tr = fetch(b, x2 + pict->pDrawable->x, indexed);
- b = bits + (y2 + pict->pDrawable->y)*stride;
- bl = fetch(b, x1 + pict->pDrawable->x, indexed);
- br = fetch(b, x2 + pict->pDrawable->x, indexed);
-
- ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
- fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
- r = (((ft * idisty + fb * disty) >> 16) & 0xff);
- ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
- fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
- r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
- ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
- fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
- r |= (((ft * idisty + fb * disty)) & 0xff0000);
- ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
- fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
- r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
- buffer[i] = r;
- }
+ if (!mask || mask[i] & maskBits)
+ {
+ if (!v.vector[2]) {
+ buffer[i] = 0;
+ } else {
+ int x1, x2, y1, y2, distx, idistx, disty, idisty;
+ FbBits *b;
+ CARD32 tl, tr, bl, br, r;
+ CARD32 ft, fb;
+
+ if (projective) {
+ xFixed_48_16 div;
+ div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
+ x1 = div >> 16;
+ distx = ((xFixed)div >> 8) & 0xff;
+ div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
+ y1 = div >> 16;
+ disty = ((xFixed)div >> 8) & 0xff;
+ } else {
+ x1 = v.vector[0] >> 16;
+ distx = (v.vector[0] >> 8) & 0xff;
+ y1 = v.vector[1] >> 16;
+ disty = (v.vector[1] >> 8) & 0xff;
+ }
+ x2 = x1 + 1;
+ y2 = y1 + 1;
+
+ idistx = 256 - distx;
+ idisty = 256 - disty;
+
+ x1 = MOD (x1, pict->pDrawable->width);
+ x2 = MOD (x2, pict->pDrawable->width);
+ y1 = MOD (y1, pict->pDrawable->height);
+ y2 = MOD (y2, pict->pDrawable->height);
+
+ b = bits + (y1 + pict->pDrawable->y)*stride;
+
+ tl = fetch(b, x1 + pict->pDrawable->x, indexed);
+ tr = fetch(b, x2 + pict->pDrawable->x, indexed);
+ b = bits + (y2 + pict->pDrawable->y)*stride;
+ bl = fetch(b, x1 + pict->pDrawable->x, indexed);
+ br = fetch(b, x2 + pict->pDrawable->x, indexed);
+
+ ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
+ fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
+ r = (((ft * idisty + fb * disty) >> 16) & 0xff);
+ ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
+ fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
+ r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
+ ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
+ fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
+ r |= (((ft * idisty + fb * disty)) & 0xff0000);
+ ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
+ fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
+ r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
+ buffer[i] = r;
+ }
+ }
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
}
} else {
for (i = 0; i < width; ++i) {
- if (!v.vector[2]) {
- buffer[i] = 0;
- } else {
- int x1, x2, y1, y2, distx, idistx, disty, idisty;
- FbBits *b;
- CARD32 tl, tr, bl, br, r;
- CARD32 ft, fb;
-
- if (projective) {
- xFixed_48_16 div;
- div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
- x1 = div >> 16;
- distx = ((xFixed)div >> 8) & 0xff;
- div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
- y1 = div >> 16;
- disty = ((xFixed)div >> 8) & 0xff;
- } else {
- x1 = v.vector[0] >> 16;
- distx = (v.vector[0] >> 8) & 0xff;
- y1 = v.vector[1] >> 16;
- disty = (v.vector[1] >> 8) & 0xff;
- }
- x2 = x1 + 1;
- y2 = y1 + 1;
-
- idistx = 256 - distx;
- idisty = 256 - disty;
-
- x1 = MOD (x1, pict->pDrawable->width);
- x2 = MOD (x2, pict->pDrawable->width);
- y1 = MOD (y1, pict->pDrawable->height);
- y2 = MOD (y2, pict->pDrawable->height);
-
- b = bits + (y1 + pict->pDrawable->y)*stride;
-
- tl = pixman_region_contains_point(pict->pCompositeClip, x1, y1, &box)
- ? fetch(b, x1 + pict->pDrawable->x, indexed) : 0;
- 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 = pixman_region_contains_point(pict->pCompositeClip, x1, y2, &box)
- ? fetch(b, x1 + pict->pDrawable->x, indexed) : 0;
- br = pixman_region_contains_point(pict->pCompositeClip, x2, y2, &box)
- ? fetch(b, x2 + pict->pDrawable->x, indexed) : 0;
-
- ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
- fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
- r = (((ft * idisty + fb * disty) >> 16) & 0xff);
- ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
- fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
- r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
- ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
- fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
- r |= (((ft * idisty + fb * disty)) & 0xff0000);
- ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
- fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
- r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
- buffer[i] = r;
- }
+ if (!mask || mask[i] & maskBits)
+ {
+ if (!v.vector[2]) {
+ buffer[i] = 0;
+ } else {
+ int x1, x2, y1, y2, distx, idistx, disty, idisty;
+ FbBits *b;
+ CARD32 tl, tr, bl, br, r;
+ CARD32 ft, fb;
+
+ if (projective) {
+ xFixed_48_16 div;
+ div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
+ x1 = div >> 16;
+ distx = ((xFixed)div >> 8) & 0xff;
+ div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
+ y1 = div >> 16;
+ disty = ((xFixed)div >> 8) & 0xff;
+ } else {
+ x1 = v.vector[0] >> 16;
+ distx = (v.vector[0] >> 8) & 0xff;
+ y1 = v.vector[1] >> 16;
+ disty = (v.vector[1] >> 8) & 0xff;
+ }
+ x2 = x1 + 1;
+ y2 = y1 + 1;
+
+ idistx = 256 - distx;
+ idisty = 256 - disty;
+
+ x1 = MOD (x1, pict->pDrawable->width);
+ x2 = MOD (x2, pict->pDrawable->width);
+ y1 = MOD (y1, pict->pDrawable->height);
+ y2 = MOD (y2, pict->pDrawable->height);
+
+ b = bits + (y1 + pict->pDrawable->y)*stride;
+
+ tl = pixman_region_contains_point(pict->pCompositeClip, x1, y1, &box)
+ ? fetch(b, x1 + pict->pDrawable->x, indexed) : 0;
+ 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 = pixman_region_contains_point(pict->pCompositeClip, x1, y2, &box)
+ ? fetch(b, x1 + pict->pDrawable->x, indexed) : 0;
+ br = pixman_region_contains_point(pict->pCompositeClip, x2, y2, &box)
+ ? fetch(b, x2 + pict->pDrawable->x, indexed) : 0;
+
+ ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
+ fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
+ r = (((ft * idisty + fb * disty) >> 16) & 0xff);
+ ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
+ fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
+ r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
+ ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
+ fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
+ r |= (((ft * idisty + fb * disty)) & 0xff0000);
+ ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
+ fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
+ r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
+ buffer[i] = r;
+ }
+ }
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
@@ -3188,124 +3328,130 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
if (PIXREGION_NUM_RECTS(pict->pCompositeClip) == 1) {
box = pict->pCompositeClip->extents;
for (i = 0; i < width; ++i) {
- if (!v.vector[2]) {
- buffer[i] = 0;
- } else {
- int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
- FbBits *b;
- CARD32 tl, tr, bl, br, r;
- Bool x1_out, x2_out, y1_out, y2_out;
- CARD32 ft, fb;
-
- if (projective) {
- xFixed_48_16 div;
- div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
- x1 = div >> 16;
- distx = ((xFixed)div >> 8) & 0xff;
- div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
- y1 = div >> 16;
- disty = ((xFixed)div >> 8) & 0xff;
- } else {
- x1 = v.vector[0] >> 16;
- distx = (v.vector[0] >> 8) & 0xff;
- y1 = v.vector[1] >> 16;
- disty = (v.vector[1] >> 8) & 0xff;
- }
- x2 = x1 + 1;
- y2 = y1 + 1;
-
- idistx = 256 - distx;
- idisty = 256 - disty;
-
- b = bits + (y1 + pict->pDrawable->y)*stride;
- x_off = x1 + pict->pDrawable->x;
-
- x1_out = (x1 < box.x1) | (x1 >= box.x2);
- x2_out = (x2 < box.x1) | (x2 >= box.x2);
- y1_out = (y1 < box.y1) | (y1 >= box.y2);
- y2_out = (y2 < box.y1) | (y2 >= box.y2);
-
- tl = x1_out|y1_out ? 0 : fetch(b, x_off, indexed);
- tr = x2_out|y1_out ? 0 : fetch(b, x_off + 1, indexed);
- b += stride;
- bl = x1_out|y2_out ? 0 : fetch(b, x_off, indexed);
- br = x2_out|y2_out ? 0 : fetch(b, x_off + 1, indexed);
-
- ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
- fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
- r = (((ft * idisty + fb * disty) >> 16) & 0xff);
- ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
- fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
- r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
- ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
- fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
- r |= (((ft * idisty + fb * disty)) & 0xff0000);
- ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
- fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
- r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
- buffer[i] = r;
- }
+ if (!mask || mask[i] & maskBits)
+ {
+ if (!v.vector[2]) {
+ buffer[i] = 0;
+ } else {
+ int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
+ FbBits *b;
+ CARD32 tl, tr, bl, br, r;
+ Bool x1_out, x2_out, y1_out, y2_out;
+ CARD32 ft, fb;
+
+ if (projective) {
+ xFixed_48_16 div;
+ div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
+ x1 = div >> 16;
+ distx = ((xFixed)div >> 8) & 0xff;
+ div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
+ y1 = div >> 16;
+ disty = ((xFixed)div >> 8) & 0xff;
+ } else {
+ x1 = v.vector[0] >> 16;
+ distx = (v.vector[0] >> 8) & 0xff;
+ y1 = v.vector[1] >> 16;
+ disty = (v.vector[1] >> 8) & 0xff;
+ }
+ x2 = x1 + 1;
+ y2 = y1 + 1;
+
+ idistx = 256 - distx;
+ idisty = 256 - disty;
+
+ b = bits + (y1 + pict->pDrawable->y)*stride;
+ x_off = x1 + pict->pDrawable->x;
+
+ x1_out = (x1 < box.x1) | (x1 >= box.x2);
+ x2_out = (x2 < box.x1) | (x2 >= box.x2);
+ y1_out = (y1 < box.y1) | (y1 >= box.y2);
+ y2_out = (y2 < box.y1) | (y2 >= box.y2);
+
+ tl = x1_out|y1_out ? 0 : fetch(b, x_off, indexed);
+ tr = x2_out|y1_out ? 0 : fetch(b, x_off + 1, indexed);
+ b += stride;
+ bl = x1_out|y2_out ? 0 : fetch(b, x_off, indexed);
+ br = x2_out|y2_out ? 0 : fetch(b, x_off + 1, indexed);
+
+ ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
+ fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
+ r = (((ft * idisty + fb * disty) >> 16) & 0xff);
+ ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
+ fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
+ r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
+ ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
+ fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
+ r |= (((ft * idisty + fb * disty)) & 0xff0000);
+ ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
+ fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
+ r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
+ buffer[i] = r;
+ }
+ }
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
}
} else {
for (i = 0; i < width; ++i) {
- if (!v.vector[2]) {
- buffer[i] = 0;
- } else {
- int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
- FbBits *b;
- CARD32 tl, tr, bl, br, r;
- CARD32 ft, fb;
-
- if (projective) {
- xFixed_48_16 div;
- div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
- x1 = div >> 16;
- distx = ((xFixed)div >> 8) & 0xff;
- div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
- y1 = div >> 16;
- disty = ((xFixed)div >> 8) & 0xff;
- } else {
- x1 = v.vector[0] >> 16;
- distx = (v.vector[0] >> 8) & 0xff;
- y1 = v.vector[1] >> 16;
- disty = (v.vector[1] >> 8) & 0xff;
- }
- x2 = x1 + 1;
- y2 = y1 + 1;
-
- idistx = 256 - distx;
- idisty = 256 - disty;
-
- b = bits + (y1 + pict->pDrawable->y)*stride;
- x_off = x1 + pict->pDrawable->x;
-
- tl = pixman_region_contains_point(pict->pCompositeClip, x1, y1, &box)
- ? fetch(b, x_off, indexed) : 0;
- tr = pixman_region_contains_point(pict->pCompositeClip, x2, y1, &box)
- ? fetch(b, x_off + 1, indexed) : 0;
- b += stride;
- bl = pixman_region_contains_point(pict->pCompositeClip, x1, y2, &box)
- ? fetch(b, x_off, indexed) : 0;
- br = pixman_region_contains_point(pict->pCompositeClip, x2, y2, &box)
- ? fetch(b, x_off + 1, indexed) : 0;
-
- ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
- fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
- r = (((ft * idisty + fb * disty) >> 16) & 0xff);
- ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
- fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
- r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
- ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
- fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
- r |= (((ft * idisty + fb * disty)) & 0xff0000);
- ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
- fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
- r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
- buffer[i] = r;
- }
+ if (!mask || mask[i] & maskBits)
+ {
+ if (!v.vector[2]) {
+ buffer[i] = 0;
+ } else {
+ int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
+ FbBits *b;
+ CARD32 tl, tr, bl, br, r;
+ CARD32 ft, fb;
+
+ if (projective) {
+ xFixed_48_16 div;
+ div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
+ x1 = div >> 16;
+ distx = ((xFixed)div >> 8) & 0xff;
+ div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
+ y1 = div >> 16;
+ disty = ((xFixed)div >> 8) & 0xff;
+ } else {
+ x1 = v.vector[0] >> 16;
+ distx = (v.vector[0] >> 8) & 0xff;
+ y1 = v.vector[1] >> 16;
+ disty = (v.vector[1] >> 8) & 0xff;
+ }
+ x2 = x1 + 1;
+ y2 = y1 + 1;
+
+ idistx = 256 - distx;
+ idisty = 256 - disty;
+
+ b = bits + (y1 + pict->pDrawable->y)*stride;
+ x_off = x1 + pict->pDrawable->x;
+
+ tl = pixman_region_contains_point(pict->pCompositeClip, x1, y1, &box)
+ ? fetch(b, x_off, indexed) : 0;
+ tr = pixman_region_contains_point(pict->pCompositeClip, x2, y1, &box)
+ ? fetch(b, x_off + 1, indexed) : 0;
+ b += stride;
+ bl = pixman_region_contains_point(pict->pCompositeClip, x1, y2, &box)
+ ? fetch(b, x_off, indexed) : 0;
+ br = pixman_region_contains_point(pict->pCompositeClip, x2, y2, &box)
+ ? fetch(b, x_off + 1, indexed) : 0;
+
+ ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
+ fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
+ r = (((ft * idisty + fb * disty) >> 16) & 0xff);
+ ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
+ fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
+ r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
+ ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
+ fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
+ r |= (((ft * idisty + fb * disty)) & 0xff0000);
+ ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
+ fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
+ r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
+ buffer[i] = r;
+ }
+ }
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
@@ -3321,57 +3467,60 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
int yoff = params[1] >> 1;
params += 2;
for (i = 0; i < width; ++i) {
- if (!v.vector[2]) {
- buffer[i] = 0;
- } else {
- int x1, x2, y1, y2, x, y;
- INT32 srtot, sgtot, sbtot, satot;
- xFixed *p = params;
-
- if (projective) {
- xFixed_48_16 tmp;
- tmp = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2] - xoff;
- x1 = xFixedToInt(tmp);
- tmp = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2] - yoff;
- y1 = xFixedToInt(tmp);
- } else {
- x1 = xFixedToInt(v.vector[0] - xoff);
- y1 = xFixedToInt(v.vector[1] - yoff);
- }
- x2 = x1 + cwidth;
- y2 = y1 + cheight;
-
- srtot = sgtot = sbtot = satot = 0;
-
- for (y = y1; y < y2; y++) {
- int ty = (pict->repeat == RepeatNormal) ? MOD (y, pict->pDrawable->height) : y;
- for (x = x1; x < x2; x++) {
- if (*p) {
- int tx = (pict->repeat == RepeatNormal) ? MOD (x, pict->pDrawable->width) : x;
- 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);
-
- srtot += Red(c) * *p;
- sgtot += Green(c) * *p;
- sbtot += Blue(c) * *p;
- satot += Alpha(c) * *p;
- }
- }
- p++;
- }
- }
-
- if (satot < 0) satot = 0; else if (satot > 0xff) satot = 0xff;
- if (srtot < 0) srtot = 0; else if (srtot > 0xff) srtot = 0xff;
- if (sgtot < 0) sgtot = 0; else if (sgtot > 0xff) sgtot = 0xff;
- if (sbtot < 0) sbtot = 0; else if (sbtot > 0xff) sbtot = 0xff;
-
- buffer[i] = ((satot << 24) |
- (srtot << 16) |
- (sgtot << 8) |
- (sbtot ));
- }
+ if (!mask || mask[i] & maskBits)
+ {
+ if (!v.vector[2]) {
+ buffer[i] = 0;
+ } else {
+ int x1, x2, y1, y2, x, y;
+ INT32 srtot, sgtot, sbtot, satot;
+ xFixed *p = params;
+
+ if (projective) {
+ xFixed_48_16 tmp;
+ tmp = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2] - xoff;
+ x1 = xFixedToInt(tmp);
+ tmp = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2] - yoff;
+ y1 = xFixedToInt(tmp);
+ } else {
+ x1 = xFixedToInt(v.vector[0] - xoff);
+ y1 = xFixedToInt(v.vector[1] - yoff);
+ }
+ x2 = x1 + cwidth;
+ y2 = y1 + cheight;
+
+ srtot = sgtot = sbtot = satot = 0;
+
+ for (y = y1; y < y2; y++) {
+ int ty = (pict->repeat == RepeatNormal) ? MOD (y, pict->pDrawable->height) : y;
+ for (x = x1; x < x2; x++) {
+ if (*p) {
+ int tx = (pict->repeat == RepeatNormal) ? MOD (x, pict->pDrawable->width) : x;
+ 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);
+
+ srtot += Red(c) * *p;
+ sgtot += Green(c) * *p;
+ sbtot += Blue(c) * *p;
+ satot += Alpha(c) * *p;
+ }
+ }
+ p++;
+ }
+ }
+
+ if (satot < 0) satot = 0; else if (satot > 0xff) satot = 0xff;
+ if (srtot < 0) srtot = 0; else if (srtot > 0xff) srtot = 0xff;
+ if (sgtot < 0) sgtot = 0; else if (sgtot > 0xff) sgtot = 0xff;
+ if (sbtot < 0) sbtot = 0; else if (sbtot > 0xff) sbtot = 0xff;
+
+ buffer[i] = ((satot << 24) |
+ (srtot << 16) |
+ (sgtot << 8) |
+ (sbtot ));
+ }
+ }
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
@@ -3381,28 +3530,33 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
}
-static void fbFetchExternalAlpha(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+static void fbFetchExternalAlpha(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
{
int i;
CARD32 _alpha_buffer[SCANLINE_BUFFER_LENGTH];
CARD32 *alpha_buffer = _alpha_buffer;
if (!pict->alphaMap) {
- fbFetchTransformed(pict, x, y, width, buffer);
+ fbFetchTransformed(pict, x, y, width, buffer, mask, maskBits);
return;
}
if (width > SCANLINE_BUFFER_LENGTH)
alpha_buffer = (CARD32 *) malloc(width*sizeof(CARD32));
- fbFetchTransformed(pict, x, y, width, buffer);
- fbFetchTransformed(pict->alphaMap, x - pict->alphaOrigin.x, y - pict->alphaOrigin.y, width, alpha_buffer);
+ fbFetchTransformed(pict, x, y, width, buffer, mask, maskBits);
+ fbFetchTransformed(pict->alphaMap, x - pict->alphaOrigin.x,
+ y - pict->alphaOrigin.y, width, alpha_buffer,
+ mask, maskBits);
for (i = 0; i < width; ++i) {
- int a = alpha_buffer[i]>>24;
- buffer[i] = (a << 24)
- | (div_255(Red(buffer[i]) * a) << 16)
- | (div_255(Green(buffer[i]) * a) << 8)
- | (div_255(Blue(buffer[i]) * a));
+ if (!mask || mask[i] & maskBits)
+ {
+ int a = alpha_buffer[i]>>24;
+ buffer[i] = (a << 24)
+ | (div_255(Red(buffer[i]) * a) << 16)
+ | (div_255(Green(buffer[i]) * a) << 8)
+ | (div_255(Blue(buffer[i]) * a));
+ }
}
if (alpha_buffer != _alpha_buffer)
@@ -3478,7 +3632,7 @@ static void fbStoreExternalAlpha(PicturePtr pict, int x, int y, int width, CARD3
}
typedef void (*scanStoreProc)(PicturePtr , int , int , int , CARD32 *);
-typedef void (*scanFetchProc)(PicturePtr , int , int , int , CARD32 *);
+typedef void (*scanFetchProc)(PicturePtr , int , int , int , CARD32 * , CARD32 *, CARD32);
static void
fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
@@ -3488,17 +3642,29 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
int i;
scanStoreProc store;
scanFetchProc fetchSrc = NULL, fetchMask = NULL, fetchDest = NULL;
+ unsigned int srcClass = SourcePictClassUnknown;
+ unsigned int maskClass = SourcePictClassUnknown;
+ FbBits *bits;
+ FbStride stride;
+ int xoff, yoff;
if (data->op == PIXMAN_OPERATOR_CLEAR)
fetchSrc = NULL;
else if (!data->src->pDrawable) {
if (data->src->pSourcePict)
+ {
fetchSrc = fbFetchSourcePict;
+ srcClass = SourcePictureClassify (data->src,
+ data->xSrc, data->ySrc,
+ data->width, data->height);
+ }
} else if (data->src->alphaMap)
fetchSrc = fbFetchExternalAlpha;
else if (data->src->repeat == RepeatNormal &&
- data->src->pDrawable->width == 1 && data->src->pDrawable->height == 1)
+ data->src->pDrawable->width == 1 && data->src->pDrawable->height == 1) {
fetchSrc = fbFetchSolid;
+ srcClass = SourcePictClassHorizontal;
+ }
#ifdef PIXMAN_CONVOLUTION
else if (!data->src->transform && data->src->filter != PictFilterConvolution)
fetchSrc = fbFetch;
@@ -3512,12 +3678,19 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
if (data->mask && data->op != PIXMAN_OPERATOR_CLEAR) {
if (!data->mask->pDrawable) {
if (data->mask->pSourcePict)
+ {
fetchMask = fbFetchSourcePict;
+ maskClass = SourcePictureClassify (data->mask,
+ data->xMask, data->yMask,
+ data->width, data->height);
+ }
} else if (data->mask->alphaMap)
fetchMask = fbFetchExternalAlpha;
else if (data->mask->repeat == RepeatNormal
- && data->mask->pDrawable->width == 1 && data->mask->pDrawable->height == 1)
+ && data->mask->pDrawable->width == 1 && data->mask->pDrawable->height == 1) {
fetchMask = fbFetchSolid;
+ maskClass = SourcePictClassHorizontal;
+ }
#ifdef PIXMAN_CONVOLUTION
else if (!data->mask->transform && data->mask->filter != PictFilterConvolution)
fetchMask = fbFetch;
@@ -3531,76 +3704,198 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
fetchMask = NULL;
}
- if (data->dest->alphaMap) {
- fetchDest = fbFetchExternalAlpha;
- store = fbStoreExternalAlpha;
- } else {
- fetchDest = fbFetch;
- store = fbStore;
+ if (data->dest->alphaMap)
+ {
+ fetchDest = fbFetchExternalAlpha;
+ store = fbStoreExternalAlpha;
+
+ if (data->op == PIXMAN_OPERATOR_CLEAR ||
+ data->op == PIXMAN_OPERATOR_SRC)
+ fetchDest = NULL;
+ }
+ else
+ {
+ fetchDest = fbFetch;
+ store = fbStore;
+
+ switch (data->op) {
+ case PIXMAN_OPERATOR_CLEAR:
+ case PIXMAN_OPERATOR_SRC:
+ fetchDest = NULL;
+ /* fall-through */
+ case PIXMAN_OPERATOR_ADD:
+ case PIXMAN_OPERATOR_OVER:
+ switch (data->dest->format_code) {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ store = NULL;
+ break;
+ }
+ break;
+ }
}
- if (data->op == PIXMAN_OPERATOR_CLEAR || data->op == PIXMAN_OPERATOR_SRC)
- fetchDest = NULL;
- 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)
- return;
+ if (!store)
+ {
+ int bpp;
- for (i = 0; i < data->height; ++i)
- {
- /* fill first half of scanline with source */
- fetchSrc(data->src, data->xSrc, data->ySrc + i, data->width, src_buffer);
- fetchMask(data->mask, data->xMask, data->yMask + i, data->width, mask_buffer);
+ fbGetDrawable (data->dest->pDrawable, bits, stride, bpp, xoff, yoff);
+ }
+
+ 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)
+ return;
- /* fill dest into second half of scanline */
- if (fetchDest)
- fetchDest(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer);
+ for (i = 0; i < data->height; ++i) {
+ /* fill first half of scanline with source */
+ if (fetchSrc)
+ {
+ if (fetchMask)
+ {
+ /* fetch mask before source so that fetching of
+ source can be optimized */
+ fetchMask (data->mask, data->xMask, data->yMask + i,
+ data->width, mask_buffer, 0, 0);
- /* blend */
- compose(dest_buffer, src_buffer, mask_buffer, data->width);
+ if (maskClass == SourcePictClassHorizontal)
+ fetchMask = NULL;
+ }
- /* write back */
- store(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer);
- }
- } else {
+ if (srcClass == SourcePictClassHorizontal)
+ {
+ fetchSrc (data->src, data->xSrc, data->ySrc + i,
+ data->width, src_buffer, 0, 0);
+ fetchSrc = NULL;
+ }
+ else
+ {
+ fetchSrc (data->src, data->xSrc, data->ySrc + i,
+ data->width, src_buffer, mask_buffer,
+ 0xffffffff);
+ }
+ }
+ else if (fetchMask)
+ {
+ fetchMask (data->mask, data->xMask, data->yMask + i,
+ data->width, mask_buffer, 0, 0);
+ }
- CombineFuncU compose = composeFunctions.combineU[data->op];
- if (!compose)
- return;
+ if (store)
+ {
+ /* fill dest into second half of scanline */
+ if (fetchDest)
+ fetchDest (data->dest, data->xDest, data->yDest + i,
+ data->width, dest_buffer, 0, 0);
- if (fetchSrc == fbFetchSolid && (!fetchMask || fetchMask == fbFetchSolid)) {
- fetchSrc(data->src, data->xSrc, data->ySrc, data->width, src_buffer);
- if (fetchMask) {
- fetchMask(data->mask, data->xMask, data->yMask, data->width, dest_buffer);
- composeFunctions.combineMaskU(src_buffer, dest_buffer, data->width);
- }
- fetchSrc = NULL;
- fetchMask = NULL;
- }
+ /* blend */
+ compose (dest_buffer, src_buffer, mask_buffer, data->width);
- for (i = 0; i < data->height; ++i) {
- /* fill first half of scanline with source */
- if (fetchSrc) {
- fetchSrc(data->src, data->xSrc, data->ySrc + i, data->width, src_buffer);
+ /* write back */
+ store (data->dest, data->xDest, data->yDest + i, data->width,
+ dest_buffer);
+ }
+ else
+ {
+ /* blend */
+ compose (bits + (data->yDest + i+ yoff) * stride +
+ data->xDest + xoff,
+ src_buffer, mask_buffer, data->width);
+ }
+ }
+ }
+ else
+ {
+ CARD32 *src_mask_buffer, *mask_buffer = 0;
+ CombineFuncU compose = composeFunctions.combineU[data->op];
+ if (!compose)
+ return;
- /* add in mask */
- if (fetchMask) {
- fetchMask(data->mask, data->xMask, data->yMask + i, data->width, dest_buffer);
- composeFunctions.combineMaskU(src_buffer, dest_buffer, data->width);
- }
- }
+ if (fetchMask)
+ mask_buffer = dest_buffer + data->width;
- /* fill dest into second half of scanline */
- if (fetchDest)
- fetchDest(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer);
+ for (i = 0; i < data->height; ++i) {
+ /* fill first half of scanline with source */
+ if (fetchSrc)
+ {
+ if (fetchMask)
+ {
+ /* fetch mask before source so that fetching of
+ source can be optimized */
+ fetchMask (data->mask, data->xMask, data->yMask + i,
+ data->width, mask_buffer, 0, 0);
- /* blend */
- compose(dest_buffer, src_buffer, data->width);
+ if (maskClass == SourcePictClassHorizontal)
+ fetchMask = NULL;
+ }
- /* write back */
- store(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer);
- }
+ if (srcClass == SourcePictClassHorizontal)
+ {
+ fetchSrc (data->src, data->xSrc, data->ySrc + i,
+ data->width, src_buffer, 0, 0);
+
+ if (mask_buffer)
+ {
+ fbCombineInU (mask_buffer, src_buffer, data->width);
+ src_mask_buffer = mask_buffer;
+ }
+ else
+ src_mask_buffer = src_buffer;
+
+ fetchSrc = NULL;
+ }
+ else
+ {
+ fetchSrc (data->src, data->xSrc, data->ySrc + i,
+ data->width, src_buffer, mask_buffer,
+ 0xff000000);
+
+ if (mask_buffer)
+ composeFunctions.combineMaskU (src_buffer,
+ mask_buffer,
+ data->width);
+
+ src_mask_buffer = src_buffer;
+ }
+ }
+ else if (fetchMask)
+ {
+ fetchMask (data->mask, data->xMask, data->yMask + i,
+ data->width, mask_buffer, 0, 0);
+
+ fbCombineInU (mask_buffer, src_buffer, data->width);
+
+ src_mask_buffer = mask_buffer;
+ }
+
+ if (store)
+ {
+ /* fill dest into second half of scanline */
+ if (fetchDest)
+ fetchDest (data->dest, data->xDest, data->yDest + i,
+ data->width, dest_buffer, 0, 0);
+
+ /* blend */
+ compose (dest_buffer, src_mask_buffer, data->width);
+
+ /* write back */
+ store (data->dest, data->xDest, data->yDest + i, data->width,
+ dest_buffer);
+ }
+ else
+ {
+ /* blend */
+ compose (bits + (data->yDest + i+ yoff) * stride +
+ data->xDest + xoff,
+ src_mask_buffer, data->width);
+ }
+ }
}
}
diff --git a/pixman/src/icimage.c b/pixman/src/icimage.c
index b50bcff75..06a502013 100644
--- a/pixman/src/icimage.c
+++ b/pixman/src/icimage.c
@@ -240,6 +240,7 @@ _pixman_init_gradient (pixman_gradient_image_t *gradient,
dpos = stops[i].x;
}
+ gradient->class = SourcePictClassUnknown;
gradient->stopRange = 0xffff;
gradient->colorTable = NULL;
gradient->colorTableSize = 0;
@@ -253,8 +254,9 @@ _pixman_create_source_image (void)
pixman_image_t *image;
image = (pixman_image_t *) malloc (sizeof (pixman_image_t));
- image->pDrawable = 0;
- image->pixels = 0;
+ image->pDrawable = 0;
+ image->pixels = 0;
+ image->format_code = PICT_a8r8g8b8;
pixman_image_init (image);
@@ -276,9 +278,6 @@ pixman_image_create_linear_gradient (const pixman_linear_gradient_t *gradient,
if (!image)
return 0;
- if (gradient->p1.x == gradient->p2.x && gradient->p1.y == gradient->p2.y)
- return 0;
-
linear = malloc (sizeof (pixman_linear_gradient_image_t) +
sizeof (pixman_gradient_stop_t) * n_stops);
if (!linear)
@@ -314,7 +313,7 @@ pixman_image_create_radial_gradient (const pixman_radial_gradient_t *gradient,
{
pixman_radial_gradient_image_t *radial;
pixman_image_t *image;
- double dx, dy, x;
+ double x;
if (n_stops < 2)
return 0;
@@ -323,12 +322,6 @@ pixman_image_create_radial_gradient (const pixman_radial_gradient_t *gradient,
if (!image)
return 0;
- dx = (double) (gradient->inner.x - gradient->outer.x);
- dy = (double) (gradient->inner.y - gradient->outer.y);
- if (sqrt (dx * dx + dy * dy) + (double) (gradient->inner.radius) >
- (double) (gradient->outer.radius))
- return 0;
-
radial = malloc (sizeof (pixman_radial_gradient_image_t) +
sizeof (pixman_gradient_stop_t) * n_stops);
if (!radial)
diff --git a/pixman/src/icimage.h b/pixman/src/icimage.h
index 8ca73bff4..cf65c7bed 100644
--- a/pixman/src/icimage.h
+++ b/pixman/src/icimage.h
@@ -61,13 +61,19 @@ typedef struct pixman_format {
#define SourcePictTypeRadial 2
#define SourcePictTypeConical 3
+#define SourcePictClassUnknown 0
+#define SourcePictClassHorizontal 1
+#define SourcePictClassVertical 2
+
typedef struct _pixman_solid_fill_image {
unsigned int type;
+ unsigned int class;
uint32_t color;
} pixman_solid_fill_image_t;
typedef struct _pixman_gradient_image {
unsigned int type;
+ unsigned int class;
pixman_gradient_stop_t *stops;
int nstops;
int stopRange;
@@ -77,6 +83,7 @@ typedef struct _pixman_gradient_image {
typedef struct _pixman_linear_gradient_image {
unsigned int type;
+ unsigned int class;
pixman_gradient_stop_t *stops;
int nstops;
int stopRange;
@@ -88,6 +95,7 @@ typedef struct _pixman_linear_gradient_image {
typedef struct _pixman_radial_gradient_image {
unsigned int type;
+ unsigned int class;
pixman_gradient_stop_t *stops;
int nstops;
int stopRange;
@@ -104,6 +112,7 @@ typedef struct _pixman_radial_gradient_image {
typedef struct _pixman_conical_gradient_image {
unsigned int type;
+ unsigned int class;
pixman_gradient_stop_t *stops;
int nstops;
int stopRange;