summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pixman/ChangeLog22
-rw-r--r--pixman/src/fbcompose.c1187
-rw-r--r--pixman/src/icimage.c17
-rw-r--r--pixman/src/icimage.h9
4 files changed, 776 insertions, 459 deletions
diff --git a/pixman/ChangeLog b/pixman/ChangeLog
index 37395ecae..1b2520a61 100644
--- a/pixman/ChangeLog
+++ b/pixman/ChangeLog
@@ -1,6 +1,26 @@
2006-01-04 Carl Worth <cworth@cworth.org>
- Originally: 2005-10-10 David Reveman <davidr@novell.com>
+ * Originally: 2005-10-10 David Reveman <davidr@novell.com>
+
+ * src/fbcompose.c: (SourcePictureClassify), (fbFetchSolid),
+ (fbFetch), (fbFetchSourcePict), (fbFetchTransformed),
+ (fbFetchExternalAlpha), (fbCompositeRect):
+ * src/icimage.c: (_pixman_init_gradient),
+ (_pixman_create_source_image),
+ (pixman_image_create_linear_gradient),
+ (pixman_image_create_radial_gradient):
+ * src/icimage.h:
+
+ 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.
+
+2006-01-04 Carl Worth <cworth@cworth.org>
+
+ * Originally: 2005-10-10 David Reveman <davidr@novell.com>
* src/pixman.h: Add entries for gradient support.
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;