--- fborig 2007-04-05 15:16:29.837354000 +0800 +++ fbcompose.c 2007-04-05 16:35:27.323976000 +0800 @@ -2958,6 +2958,7 @@ SourcePictPtr pGradient = pict->pSourcePict; GradientWalker walker; CARD32 *end = buffer + width; + pixman_transform_t *transform = pict->transform; _gradient_walker_init (&walker, pGradient, pict->repeat); @@ -2975,12 +2976,12 @@ v.vector[0] = IntToxFixed(x) + xFixed1/2; v.vector[1] = IntToxFixed(y) + xFixed1/2; v.vector[2] = xFixed1; - if (pict->transform) { - if (!PictureTransformPoint3d (pict->transform, &v)) + if (transform) { + if (!PictureTransformPoint3d (transform, &v)) return; - unit.vector[0] = pict->transform->matrix[0][0]; - unit.vector[1] = pict->transform->matrix[1][0]; - unit.vector[2] = pict->transform->matrix[2][0]; + unit.vector[0] = transform->matrix[0][0]; + unit.vector[1] = transform->matrix[1][0]; + unit.vector[2] = transform->matrix[2][0]; } else { unit.vector[0] = xFixed1; unit.vector[1] = 0; @@ -3208,55 +3209,60 @@ double ry = y + 0.5; double rz = 1.; - if (pict->transform) { + if (transform) { PictVector v; /* reference point is the center of the pixel */ v.vector[0] = IntToxFixed(x) + xFixed1/2; v.vector[1] = IntToxFixed(y) + xFixed1/2; v.vector[2] = xFixed1; - if (!PictureTransformPoint3d (pict->transform, &v)) + if (!PictureTransformPoint3d (transform, &v)) return; - cx = pict->transform->matrix[0][0]/65536.; - cy = pict->transform->matrix[1][0]/65536.; - cz = pict->transform->matrix[2][0]/65536.; + cx = transform->matrix[0][0]/65536.; + cy = transform->matrix[1][0]/65536.; + cz = transform->matrix[2][0]/65536.; rx = v.vector[0]/65536.; ry = v.vector[1]/65536.; rz = v.vector[2]/65536.; - projective = pict->transform->matrix[2][0] != 0 || v.vector[2] != xFixed1; + projective = transform->matrix[2][0] != 0 || v.vector[2] != xFixed1; } if (pGradient->type == SourcePictTypeRadial) { pixman_radial_gradient_image_t *radial; radial = &pGradient->radial; if (!projective) { + double c1x = xFixedToDouble (radial->c1.x); + double c1y = xFixedToDouble (radial->c1.y); + double r1 = xFixedToDouble (radial->c1.radius); + double A = radial->A; + double cdx = radial->cdx; + double cdy = radial->cdy; + double dr = radial->dr; + while (buffer < end) { if (!mask || *mask++ & maskBits) { double pdx, pdy; double B, C; double det; - double c1x = xFixedToDouble (radial->c1.x); - double c1y = xFixedToDouble (radial->c1.y); - double r1 = xFixedToDouble (radial->c1.radius); xFixed_48_16 t; pdx = rx - c1x; pdy = ry - c1y; - B = -2 * ( pdx * radial->cdx - + pdy * radial->cdy - + r1 * radial->dr); + B = -2 * ( pdx * cdx + + pdy * cdy + + r1 * dr); C = (pdx * pdx + pdy * pdy - r1 * r1); - det = (B * B) - (4 * radial->A * C); + det = (B * B) - (4 * A * C); if (det < 0.0) det = 0.0; - if (radial->A < 0) - t = (xFixed_48_16) ((- B - sqrt(det)) / (2.0 * radial->A) * 65536); + if (A < 0) + t = (xFixed_48_16) ((- B - sqrt(det)) / (2.0 * A) * 65536); else - t = (xFixed_48_16) ((- B + sqrt(det)) / (2.0 * radial->A) * 65536); + t = (xFixed_48_16) ((- B + sqrt(det)) / (2.0 * A) * 65536); *buffer = _gradient_walker_pixel (&walker, t); } @@ -3273,10 +3279,13 @@ assert (0); } } else /* SourcePictTypeConical */ { + pixman_fixed16_16_t center_x = pGradient->conical.center.x; + pixman_fixed16_16_t center_y = pGradient->conical.center.y; double a = pGradient->conical.angle/(180.*65536); + if (!projective) { - rx -= pGradient->conical.center.x/65536.; - ry -= pGradient->conical.center.y/65536.; + rx -= center_x/65536.; + ry -= center_y/65536.; while (buffer < end) { double angle; @@ -3309,8 +3318,8 @@ } else { x = y = 0.; } - x -= pGradient->conical.center.x/65536.; - y -= pGradient->conical.center.y/65536.; + x -= center.x/65536.; + y -= center.y/65536.; angle = atan2(y, x) + a; t = (xFixed_48_16) (angle * (65536. / (2*M_PI))); @@ -3330,6 +3339,11 @@ { FbBits *bits; FbStride stride; + FbPixels *pixels; + pixman_transform_t *transform; + pixman_region16_t *source_clip; + pixman_filter_t filter; + unsigned int pix_width, pix_height, pix_x, pix_y, repeat; int bpp; int xoff, yoff; fetchPixelProc fetch; @@ -3344,9 +3358,19 @@ #endif Bool projective = FALSE; + pixels = pict->pDrawable; + pix_width = pixels->width; + pix_height = pixels->height; + pix_x = pixels->x; + pix_y = pixels->y; + source_clip = pict->pSourceClip; + repeat = pict->repeat; + transform = pict->transform; + filter = pict->filter; + fetch = fetchPixelProcForPicture(pict); - fbGetDrawable(pict->pDrawable, bits, stride, bpp, xoff, yoff); + fbGetDrawable(pixels, bits, stride, bpp, xoff, yoff); x += xoff; y += yoff; @@ -3356,12 +3380,12 @@ v.vector[2] = xFixed1; /* when using convolution filters one might get here without a transform */ - if (pict->transform) { - if (!PictureTransformPoint3d (pict->transform, &v)) + if (transform) { + if (!PictureTransformPoint3d (transform, &v)) return; - unit.vector[0] = pict->transform->matrix[0][0]; - unit.vector[1] = pict->transform->matrix[1][0]; - unit.vector[2] = pict->transform->matrix[2][0]; + unit.vector[0] = transform->matrix[0][0]; + unit.vector[1] = transform->matrix[1][0]; + unit.vector[2] = transform->matrix[2][0]; } else { unit.vector[0] = xFixed1; unit.vector[1] = 0; @@ -3369,11 +3393,11 @@ } projective = (unit.vector[2] != 0); - if (pict->filter == PIXMAN_FILTER_NEAREST || pict->filter == PIXMAN_FILTER_FAST) + if (filter == PIXMAN_FILTER_NEAREST || filter == PIXMAN_FILTER_FAST) { - if (pict->repeat == RepeatNormal) { - if (PIXREGION_NUM_RECTS(pict->pSourceClip) == 1) { - box = pict->pSourceClip->extents; + if (repeat == RepeatNormal) { + if (PIXREGION_NUM_RECTS(source_clip) == 1) { + box = source_clip->extents; for (i = 0; i < width; ++i) { if (!mask || mask[i] & maskBits) { @@ -3381,13 +3405,13 @@ 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); + y = MOD(DIV(v.vector[1],v.vector[2]), pix_height); + x = MOD(DIV(v.vector[0],v.vector[2]), pix_width); } else { - y = MOD(v.vector[1]>>16, pict->pDrawable->height); - x = MOD(v.vector[0]>>16, pict->pDrawable->width); + y = MOD(v.vector[1]>>16, pix_height); + x = MOD(v.vector[0]>>16, pix_width); } - buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed); + buffer[i] = fetch(bits + (y + pix_y)*stride, x + pix_x, indexed); } } v.vector[0] += unit.vector[0]; @@ -3402,14 +3426,14 @@ 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); + y = MOD(DIV(v.vector[1],v.vector[2]), pix_height); + x = MOD(DIV(v.vector[0],v.vector[2]), pix_width); } else { - y = MOD(v.vector[1]>>16, pict->pDrawable->height); - x = MOD(v.vector[0]>>16, pict->pDrawable->width); + y = MOD(v.vector[1]>>16, pix_height); + x = MOD(v.vector[0]>>16, pix_width); } - if (pixman_region_contains_point (pict->pSourceClip, x, y, &box)) - buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed); + if (pixman_region_contains_point (source_clip, x, y, &box)) + buffer[i] = fetch(bits + (y + pix_y)*stride, x + pix_x, indexed); else buffer[i] = 0; } @@ -3420,8 +3444,8 @@ } } } else { - if (PIXREGION_NUM_RECTS(pict->pSourceClip) == 1) { - box = pict->pSourceClip->extents; + if (PIXREGION_NUM_RECTS(source_clip) == 1) { + box = source_clip->extents; for (i = 0; i < width; ++i) { if (!mask || mask[i] & maskBits) { @@ -3436,7 +3460,7 @@ 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); + 0 : fetch(bits + (y + pix_y)*stride, x + pix_x, indexed); } } v.vector[0] += unit.vector[0]; @@ -3455,8 +3479,8 @@ y = v.vector[1]>>16; x = v.vector[0]>>16; } - if (pixman_region_contains_point (pict->pSourceClip, x, y, &box)) - buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed); + if (pixman_region_contains_point (source_clip, x, y, &box)) + buffer[i] = fetch(bits + (y + pix_y)*stride, x + pix_x, indexed); else buffer[i] = 0; } @@ -3466,16 +3490,16 @@ } } } - } else if (pict->filter == PIXMAN_FILTER_BILINEAR || pict->filter == PIXMAN_FILTER_GOOD || pict->filter == PIXMAN_FILTER_BEST) { + } else if (filter == PIXMAN_FILTER_BILINEAR || filter == PIXMAN_FILTER_GOOD || filter == PIXMAN_FILTER_BEST) { /* adjust vector for maximum contribution at 0.5, 0.5 of each texel. */ v.vector[0] -= v.vector[2]/2; v.vector[1] -= v.vector[2]/2; unit.vector[0] -= unit.vector[2]/2; unit.vector[1] -= unit.vector[2]/2; - if (pict->repeat == RepeatNormal) { - if (PIXREGION_NUM_RECTS(pict->pSourceClip) == 1) { - box = pict->pSourceClip->extents; + if (repeat == RepeatNormal) { + if (PIXREGION_NUM_RECTS(source_clip) == 1) { + box = source_clip->extents; for (i = 0; i < width; ++i) { if (!mask || mask[i] & maskBits) { @@ -3507,18 +3531,17 @@ 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); + x1 = MOD (x1, pix_width); + x2 = MOD (x2, pix_width); + y1 = MOD (y1, pix_height); + y2 = MOD (y2, pix_height); + + b = bits + (y1 + pix_y)*stride; + tl = fetch(b, x1 + pix_x, indexed); + tr = fetch(b, x2 + pix_x, indexed); + b = bits + (y2 + pix_y)*stride; + bl = fetch(b, x1 + pix_x, indexed); + br = fetch(b, x2 + pix_x, indexed); ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx; fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx; @@ -3571,22 +3594,22 @@ 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->pSourceClip, x1, y1, &box) - ? fetch(b, x1 + pict->pDrawable->x, indexed) : 0; - tr = pixman_region_contains_point(pict->pSourceClip, x2, y1, &box) - ? fetch(b, x2 + pict->pDrawable->x, indexed) : 0; - b = bits + (y2 + pict->pDrawable->y)*stride; - bl = pixman_region_contains_point(pict->pSourceClip, x1, y2, &box) - ? fetch(b, x1 + pict->pDrawable->x, indexed) : 0; - br = pixman_region_contains_point(pict->pSourceClip, x2, y2, &box) - ? fetch(b, x2 + pict->pDrawable->x, indexed) : 0; + x1 = MOD (x1, pix_width); + x2 = MOD (x2, pix_width); + y1 = MOD (y1, pix_height); + y2 = MOD (y2, pix_height); + + b = bits + (y1 + pix_y)*stride; + + tl = pixman_region_contains_point(source_clip, x1, y1, &box) + ? fetch(b, x1 + pix_x, indexed) : 0; + tr = pixman_region_contains_point(source_clip, x2, y1, &box) + ? fetch(b, x2 + pix_x, indexed) : 0; + b = bits + (y2 + pix_y)*stride; + bl = pixman_region_contains_point(source_clip, x1, y2, &box) + ? fetch(b, x1 + pix_x, indexed) : 0; + br = pixman_region_contains_point(source_clip, x2, y2, &box) + ? fetch(b, x2 + pix_x, indexed) : 0; ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx; fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx; @@ -3609,8 +3632,8 @@ } } } else { - if (PIXREGION_NUM_RECTS(pict->pSourceClip) == 1) { - box = pict->pSourceClip->extents; + if (PIXREGION_NUM_RECTS(source_clip) == 1) { + box = source_clip->extents; for (i = 0; i < width; ++i) { if (!mask || mask[i] & maskBits) { @@ -3643,8 +3666,8 @@ idistx = 256 - distx; idisty = 256 - disty; - b = bits + (y1 + pict->pDrawable->y)*stride; - x_off = x1 + pict->pDrawable->x; + b = bits + (y1 + pix_y)*stride; + x_off = x1 + pix_x; x1_out = (x1 < box.x1) | (x1 >= box.x2); x2_out = (x2 < box.x1) | (x2 >= box.x2); @@ -3708,17 +3731,17 @@ idistx = 256 - distx; idisty = 256 - disty; - b = bits + (y1 + pict->pDrawable->y)*stride; - x_off = x1 + pict->pDrawable->x; + b = bits + (y1 + pix_y)*stride; + x_off = x1 + pix_x; - tl = pixman_region_contains_point(pict->pSourceClip, x1, y1, &box) + tl = pixman_region_contains_point(source_clip, x1, y1, &box) ? fetch(b, x_off, indexed) : 0; - tr = pixman_region_contains_point(pict->pSourceClip, x2, y1, &box) + tr = pixman_region_contains_point(source_clip, x2, y1, &box) ? fetch(b, x_off + 1, indexed) : 0; b += stride; - bl = pixman_region_contains_point(pict->pSourceClip, x1, y2, &box) + bl = pixman_region_contains_point(source_clip, x1, y2, &box) ? fetch(b, x_off, indexed) : 0; - br = pixman_region_contains_point(pict->pSourceClip, x2, y2, &box) + br = pixman_region_contains_point(source_clip, x2, y2, &box) ? fetch(b, x_off + 1, indexed) : 0; ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx; @@ -3743,7 +3766,7 @@ } } #ifdef PIXMAN_CONVOLUTION - } else if (pict->filter == PictFilterConvolution) { + } else if (filter == PictFilterConvolution) { xFixed *params = pict->filter_params; INT32 cwidth = xFixedToInt(params[0]); INT32 cheight = xFixedToInt(params[1]); @@ -3776,13 +3799,13 @@ srtot = sgtot = sbtot = satot = 0; for (y = y1; y < y2; y++) { - int ty = (pict->repeat == RepeatNormal) ? MOD (y, pict->pDrawable->height) : y; + int ty = (repeat == RepeatNormal) ? MOD (y, pix_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->pSourceClip, tx, ty, &box)) { - FbBits *b = bits + (ty + pict->pDrawable->y)*stride; - CARD32 c = fetch(b, tx + pict->pDrawable->x, indexed); + int tx = (repeat == RepeatNormal) ? MOD (x, pix_width) : x; + if (pixman_region_contains_point (source_clip, tx, ty, &box)) { + FbBits *b = bits + (ty + pix_y)*stride; + CARD32 c = fetch(b, tx + pix_x, indexed); srtot += Red(c) * *p; sgtot += Green(c) * *p; @@ -4202,17 +4225,27 @@ Bool srcRepeat = FALSE; Bool maskRepeat = FALSE; int w, h; + unsigned int mask_width; + unsigned int mask_height; + unsigned int src_width; + unsigned int src_height; + FbComposeData compose_data; CARD32 _scanline_buffer[SCANLINE_BUFFER_LENGTH*3]; CARD32 *scanline_buffer = _scanline_buffer; - FbComposeData compose_data; - if (pSrc->pDrawable) - srcRepeat = pSrc->repeat == RepeatNormal && !pSrc->transform - && (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1); - - if (pMask && pMask->pDrawable) - maskRepeat = pMask->repeat == RepeatNormal && !pMask->transform - && (pMask->pDrawable->width != 1 || pMask->pDrawable->height != 1); + if (pSrc->pDrawable) { + src_width = pSrc->pDrawable->width; + src_height = pSrc->pDrawable->height; + srcRepeat = pSrc->repeat == RepeatNormal && !pSrc->transform + && (src_width != 1 || src_height != 1); + } + + if (pMask && pMask->pDrawable) { + mask_width = pMask->pDrawable->width; + mask_height = pMask->pDrawable->height; + maskRepeat = pMask->repeat == RepeatNormal && !pMask->transform + && (mask_width != 1 || mask_height != 1); + } if (op == PIXMAN_OPERATOR_OVER && !pMask && !pSrc->transform && !PICT_FORMAT_A(pSrc->format_code) && !pSrc->alphaMap) op = PIXMAN_OPERATOR_SRC; @@ -4245,43 +4278,48 @@ pbox = pixman_region_rects (region); while (n--) { - h = pbox->y2 - pbox->y1; - compose_data.ySrc = pbox->y1 - yDst + ySrc; - compose_data.yMask = pbox->y1 - yDst + yMask; - compose_data.yDest = pbox->y1; + short x1 = pbox->x1; + short x2 = pbox->x2; + short y1 = pbox->y1; + short y2 = pbox->y2; + + h = y2 - y1; + compose_data.ySrc = y1 - yDst + ySrc; + compose_data.yMask = y1 - yDst + yMask; + compose_data.yDest = y1; while (h) { compose_data.height = h; - w = pbox->x2 - pbox->x1; - compose_data.xSrc = pbox->x1 - xDst + xSrc; - compose_data.xMask = pbox->x1 - xDst + xMask; - compose_data.xDest = pbox->x1; + w = x2 - x1; + compose_data.xSrc = x1 - xDst + xSrc; + compose_data.xMask = x1 - xDst + xMask; + compose_data.xDest = x1; if (maskRepeat) { - compose_data.yMask = mod (compose_data.yMask, pMask->pDrawable->height); - if (compose_data.height > pMask->pDrawable->height - compose_data.yMask) - compose_data.height = pMask->pDrawable->height - compose_data.yMask; + compose_data.yMask = mod (compose_data.yMask, mask_height); + if (compose_data.height > mask_height - compose_data.yMask) + compose_data.height = mask_height - compose_data.yMask; } if (srcRepeat) { - compose_data.ySrc = mod (compose_data.ySrc, pSrc->pDrawable->height); - if (compose_data.height > pSrc->pDrawable->height - compose_data.ySrc) - compose_data.height = pSrc->pDrawable->height - compose_data.ySrc; + compose_data.ySrc = mod (compose_data.ySrc, src_height); + if (compose_data.height > src_height - compose_data.ySrc) + compose_data.height = src_height - compose_data.ySrc; } while (w) { compose_data.width = w; if (maskRepeat) { - compose_data.xMask = mod (compose_data.xMask, pMask->pDrawable->width); - if (compose_data.width > pMask->pDrawable->width - compose_data.xMask) - compose_data.width = pMask->pDrawable->width - compose_data.xMask; + compose_data.xMask = mod (compose_data.xMask, mask_width); + if (compose_data.width > mask_width - compose_data.xMask) + compose_data.width = mask_width - compose_data.xMask; } if (srcRepeat) { - compose_data.xSrc = mod (compose_data.xSrc, pSrc->pDrawable->width); - if (compose_data.width > pSrc->pDrawable->width - compose_data.xSrc) - compose_data.width = pSrc->pDrawable->width - compose_data.xSrc; + compose_data.xSrc = mod (compose_data.xSrc, src_width); + if (compose_data.width > src_width - compose_data.xSrc) + compose_data.width = src_width - compose_data.xSrc; } fbCompositeRect(&compose_data, scanline_buffer); w -= compose_data.width;