diff options
author | Lars Knoll <lars@trolltech.com> | 2005-06-13 14:40:25 +0000 |
---|---|---|
committer | Lars Knoll <lars@trolltech.com> | 2005-06-13 14:40:25 +0000 |
commit | 49476ca73c86a599a1bc49cba1117d42f59996a8 (patch) | |
tree | a5618b6b33c73b7b40898c70059105f89ee2677b | |
parent | f0ab6d57df66da5de1a8182f8250cc2c8e1450ad (diff) |
add the convolution filter from xserver to xorg
-rw-r--r-- | fb/fbcompose.c | 196 | ||||
-rw-r--r-- | fb/fbpict.c | 74 | ||||
-rw-r--r-- | render/filter.c | 35 | ||||
-rw-r--r-- | render/picturestr.h | 28 |
4 files changed, 208 insertions, 125 deletions
diff --git a/fb/fbcompose.c b/fb/fbcompose.c index 9085c6a86..9c25a0f97 100644 --- a/fb/fbcompose.c +++ b/fb/fbcompose.c @@ -50,7 +50,7 @@ fbFetch_a8r8g8b8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexe { memcpy(buffer, (const CARD32 *)bits + x, width*sizeof(CARD32)); } - + static FASTCALL void fbFetch_x8r8g8b8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) { @@ -60,7 +60,7 @@ fbFetch_x8r8g8b8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexe *buffer++ = *pixel++ | 0xff000000; } } - + static FASTCALL void fbFetch_a8b8g8r8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) { @@ -73,7 +73,7 @@ fbFetch_a8b8g8r8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexe ++pixel; } } - + static FASTCALL void fbFetch_x8b8g8r8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) { @@ -389,7 +389,7 @@ fbFetch_a4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr i int i; for (i = 0; i < width; ++i) { CARD32 p = Fetch4(bits, i + x); - + p |= p << 4; *buffer++ = p << 24; } @@ -402,7 +402,7 @@ fbFetch_r1g2b1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedP for (i = 0; i < width; ++i) { CARD32 p = Fetch4(bits, i + x); CARD32 r,g,b; - + r = ((p & 0x8) * 0xff) << 13; g = ((p & 0x6) * 0x55) << 7; b = ((p & 0x1) * 0xff); @@ -417,7 +417,7 @@ fbFetch_b1g2r1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedP for (i = 0; i < width; ++i) { CARD32 p = Fetch4(bits, i + x); CARD32 r,g,b; - + b = ((p & 0x8) * 0xff) >> 3; g = ((p & 0x6) * 0x55) << 7; r = ((p & 0x1) * 0xff) << 16; @@ -432,7 +432,7 @@ fbFetch_a1r1g1b1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexe for (i = 0; i < width; ++i) { CARD32 p = Fetch4(bits, i + x); CARD32 a,r,g,b; - + a = ((p & 0x8) * 0xff) << 21; r = ((p & 0x4) * 0xff) << 14; g = ((p & 0x2) * 0xff) << 7; @@ -448,7 +448,7 @@ fbFetch_a1b1g1r1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexe for (i = 0; i < width; ++i) { CARD32 p = Fetch4(bits, i + x); CARD32 a,r,g,b; - + a = ((p & 0x8) * 0xff) << 21; r = ((p & 0x4) * 0xff) >> 3; g = ((p & 0x2) * 0xff) << 7; @@ -463,7 +463,7 @@ fbFetch_c4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr i int i; for (i = 0; i < width; ++i) { CARD32 p = Fetch4(bits, i + x); - + *buffer++ = indexed->rgba[p]; } } @@ -513,15 +513,15 @@ static fetchProc fetchProcForPicture (PicturePtr pict) case PICT_x8r8g8b8: return fbFetch_x8r8g8b8; case PICT_a8b8g8r8: return fbFetch_a8b8g8r8; case PICT_x8b8g8r8: return fbFetch_x8b8g8r8; - + /* 24bpp formats */ case PICT_r8g8b8: return fbFetch_r8g8b8; case PICT_b8g8r8: return fbFetch_b8g8r8; - + /* 16bpp formats */ case PICT_r5g6b5: return fbFetch_r5g6b5; case PICT_b5g6r5: return fbFetch_b5g6r5; - + case PICT_a1r5g5b5: return fbFetch_a1r5g5b5; case PICT_x1r5g5b5: return fbFetch_x1r5g5b5; case PICT_a1b5g5r5: return fbFetch_a1b5g5r5; @@ -530,7 +530,7 @@ static fetchProc fetchProcForPicture (PicturePtr pict) case PICT_x4r4g4b4: return fbFetch_x4r4g4b4; case PICT_a4b4g4r4: return fbFetch_a4b4g4r4; case PICT_x4b4g4r4: return fbFetch_x4b4g4r4; - + /* 8bpp formats */ case PICT_a8: return fbFetch_a8; case PICT_r3g3b2: return fbFetch_r3g3b2; @@ -548,7 +548,7 @@ static fetchProc fetchProcForPicture (PicturePtr pict) case PICT_a1b1g1r1: return fbFetch_a1b1g1r1; case PICT_c4: return fbFetch_c4; case PICT_g4: return fbFetch_c4; - + /* 1bpp formats */ case PICT_a1: return fbFetch_a1; case PICT_g1: return fbFetch_g1; @@ -585,18 +585,18 @@ fbFetchPixel_a8b8g8r8 (const FbBits *bits, int offset, miIndexedPtr indexed) (pixel & 0x0000ff00) | ((pixel & 0xff) << 16)); } - + static FASTCALL CARD32 fbFetchPixel_x8b8g8r8 (const FbBits *bits, int offset, miIndexedPtr indexed) { CARD32 pixel = ((CARD32 *)bits)[offset]; - + return ((0xff000000) | ((pixel >> 16) & 0xff) | (pixel & 0x0000ff00) | ((pixel & 0xff) << 16)); } - + static FASTCALL CARD32 fbFetchPixel_r8g8b8 (const FbBits *bits, int offset, miIndexedPtr indexed) { @@ -636,19 +636,19 @@ fbFetchPixel_r5g6b5 (const FbBits *bits, int offset, miIndexedPtr indexed) { CARD32 pixel = ((CARD16 *) bits)[offset]; CARD32 r,g,b; - + r = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) << 8; g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5; b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2; return (0xff000000 | r | g | b); } - + static FASTCALL CARD32 fbFetchPixel_b5g6r5 (const FbBits *bits, int offset, miIndexedPtr indexed) { CARD32 pixel = ((CARD16 *) bits)[offset]; CARD32 r,g,b; - + b = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) >> 8; g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5; r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14; @@ -886,14 +886,14 @@ fbFetchPixel_a1b1g1r1 (const FbBits *bits, int offset, miIndexedPtr indexed) { CARD32 pixel = Fetch4(bits, offset); CARD32 a,r,g,b; - + a = ((pixel & 0x8) * 0xff) << 21; r = ((pixel & 0x4) * 0xff) >> 3; g = ((pixel & 0x2) * 0xff) << 7; b = ((pixel & 0x1) * 0xff) << 16; return a|r|g|b; } - + static FASTCALL CARD32 fbFetchPixel_c4 (const FbBits *bits, int offset, miIndexedPtr indexed) { @@ -945,11 +945,11 @@ static fetchPixelProc fetchPixelProcForPicture (PicturePtr pict) /* 24bpp formats */ case PICT_r8g8b8: return fbFetchPixel_r8g8b8; case PICT_b8g8r8: return fbFetchPixel_b8g8r8; - + /* 16bpp formats */ case PICT_r5g6b5: return fbFetchPixel_r5g6b5; case PICT_b5g6r5: return fbFetchPixel_b5g6r5; - + case PICT_a1r5g5b5: return fbFetchPixel_a1r5g5b5; case PICT_x1r5g5b5: return fbFetchPixel_x1r5g5b5; case PICT_a1b5g5r5: return fbFetchPixel_a1b5g5r5; @@ -984,7 +984,7 @@ static fetchPixelProc fetchPixelProcForPicture (PicturePtr pict) return 0; } } - + /* @@ -1057,7 +1057,7 @@ fbStore_b8g8r8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedP #endif } } - + static FASTCALL void fbStore_r5g6b5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) { @@ -1070,7 +1070,7 @@ fbStore_r5g6b5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedP ((s >> 8) & 0xf800); } } - + static FASTCALL void fbStore_b5g6r5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) { @@ -1083,7 +1083,7 @@ fbStore_b5g6r5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedP ((r >> 3) )); } } - + static FASTCALL void fbStore_a1r5g5b5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) { @@ -1675,7 +1675,7 @@ fbCombineDisjointInPart (CARD8 a, CARD8 b) return 0; /* 1 - 1 */ return ~FbIntDiv(b,a); /* 1 - (1-b) / a */ } - + static FASTCALL void fbCombineDisjointGeneralU (CARD32 *dest, const CARD32 *src, int width, CARD8 combine) { @@ -1725,7 +1725,7 @@ fbCombineDisjointGeneralU (CARD32 *dest, const CARD32 *src, int width, CARD8 com dest[i] = s; } } - + static FASTCALL void fbCombineDisjointOverU (CARD32 *dest, const CARD32 *src, int width) { @@ -1747,19 +1747,19 @@ fbCombineDisjointOverU (CARD32 *dest, const CARD32 *src, int width) } } } - + static FASTCALL void fbCombineDisjointInU (CARD32 *dest, const CARD32 *src, int width) { fbCombineDisjointGeneralU (dest, src, width, CombineAIn); } - + static FASTCALL void fbCombineDisjointInReverseU (CARD32 *dest, const CARD32 *src, int width) { fbCombineDisjointGeneralU (dest, src, width, CombineBIn); } - + static FASTCALL void fbCombineDisjointOutU (CARD32 *dest, const CARD32 *src, int width) { @@ -1771,7 +1771,7 @@ fbCombineDisjointOutReverseU (CARD32 *dest, const CARD32 *src, int width) { fbCombineDisjointGeneralU (dest, src, width, CombineBOut); } - + static FASTCALL void fbCombineDisjointAtopU (CARD32 *dest, const CARD32 *src, int width) { @@ -1783,7 +1783,7 @@ fbCombineDisjointAtopReverseU (CARD32 *dest, const CARD32 *src, int width) { fbCombineDisjointGeneralU (dest, src, width, CombineBAtop); } - + static FASTCALL void fbCombineDisjointXorU (CARD32 *dest, const CARD32 *src, int width) { @@ -1796,7 +1796,7 @@ fbCombineConjointOutPart (CARD8 a, CARD8 b) { /* max (1-b/a,0) */ /* = 1-min(b/a,1) */ - + /* min (1, (1-b) / a) */ if (b >= a) /* b >= a -> b/a >= 1 */ @@ -1878,7 +1878,7 @@ fbCombineConjointOverReverseU (CARD32 *dest, const CARD32 *src, int width) fbCombineConjointGeneralU (dest, src, width, CombineBOver); } - + static FASTCALL void fbCombineConjointInU (CARD32 *dest, const CARD32 *src, int width) { @@ -2644,38 +2644,32 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 PictVector v; PictVector unit; int i; - int trans_x, trans_y; BoxRec box; miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate; - if (!pict->transform) { - fbFetch(pict, x, y, width, buffer); - return; - } + fetch = fetchPixelProcForPicture(pict); fbGetDrawable(pict->pDrawable, bits, stride, bpp, xoff, yoff); x += xoff; y += yoff; - trans_x = x - pict->pDrawable->x; - trans_y = y - pict->pDrawable->y; v.vector[0] = IntToxFixed(x - pict->pDrawable->x); v.vector[1] = IntToxFixed(y - pict->pDrawable->y); v.vector[2] = xFixed1; - + unit.vector[0] = xFixed1; unit.vector[1] = 0; unit.vector[2] = xFixed1; - - if (!PictureTransformPoint (pict->transform, &v)) { - return; - } - if (!PictureTransformPoint (pict->transform, &unit)) { - return; + + if (pict->transform) { + /* when using convolution filters one might get here without a transform */ + if (!PictureTransformPoint (pict->transform, &v)) + return; + if (!PictureTransformPoint (pict->transform, &unit)) + return; } - - if (pict->filter == PictFilterNearest) - { + + if (pict->filter == PictFilterNearest) { if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) { box = pict->pCompositeClip->extents; for (i = 0; i < width; ++i) { @@ -2706,10 +2700,9 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 buffer[i] = fetch(bits + (y - pict->pDrawable->y)*stride, x - pict->pDrawable->x, indexed); else buffer[i] = 0; - } - } - } else if (pict->filter == PictFilterBilinear) - { + } + } + } else if (pict->filter == PictFilterBilinear) { if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) { box = pict->pCompositeClip->extents; for (i = 0; i < width; ++i) { @@ -2725,19 +2718,18 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 x2 = x1 + 1; y1 = xFixedToInt(v.vector[1]); y2 = y1 + 1; - if (pict->repeat) - { + if (pict->repeat) { x1 = mod (x1, pict->pDrawable->width); y1 = mod (y1, pict->pDrawable->height); x2 = mod (x2, pict->pDrawable->width); y2 = mod (y2, pict->pDrawable->height); - } - + } + distx = ((v.vector[0] - (x1 << 16)) >> 8); disty = ((v.vector[1] - (y1 << 16)) >> 8); idistx = 256 - distx; idisty = 256 - disty; - + b = bits + (y1 - pict->pDrawable->y)*stride; x_off = x1 - pict->pDrawable->x; @@ -2802,6 +2794,64 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 buffer[i] = tl; } } + } else if (pict->filter == PictFilterConvolution) { + xFixed *params = pict->filter_params; + INT32 cwidth = xFixedToInt(params[0]); + INT32 cheight = xFixedToInt(params[1]); + v.vector[0] -= params[0] >> 2; + v.vector[1] -= params[1] >> 2; + params += 2; + for (i = 0; i < width; ++i) { + int x1, x2, y1, y2, x, y; + INT32 srtot, sgtot, sbtot, satot, sum; + xFixed *p = params; + + v.vector[0] += unit.vector[0]; + v.vector[1] += unit.vector[1]; + + x1 = xFixedToInt(v.vector[0]); + x2 = x1 + cwidth; + y1 = xFixedToInt(v.vector[1]); + y2 = y1 + cheight; + + srtot = sgtot = sbtot = satot = sum = 0; + + for (y = y1; y < y2; y++) { + int ty = (pict->repeat) ? mod (y, pict->pDrawable->height) : y; + for (x = x1; x < x2; x++) { + if (*params) { + int tx = (pict->repeat) ? mod (x, pict->pDrawable->width) : x; + if (POINT_IN_REGION (0, 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; + } + sum += *p; + } + p++; + } + } + + if (sum) { + satot /= sum; + srtot /= sum; + sgtot /= sum; + sbtot /= sum; + } + 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 )); + } } } @@ -2904,15 +2954,19 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer) fetchSrc = fbFetchExternalAlpha; else if (data->src->repeat && data->src->pDrawable->width == 1 && data->src->pDrawable->height == 1) fetchSrc = fbFetchSolid; + else if (!data->src->transform && data->src->filter != PictFilterConvolution) + fetchSrc = fbFetch; else fetchSrc = fbFetchTransformed; - + if (data->mask && data->op != PictOpClear) { if (data->mask->alphaMap) fetchMask = fbFetchExternalAlpha; else if (data->mask->repeat && data->mask->pDrawable->width == 1 && data->mask->pDrawable->height == 1) fetchMask = fbFetchSolid; - else + else if (!data->mask->transform && data->src->filter != PictFilterConvolution) + fetchMask = fbFetch; + else fetchMask = fbFetchTransformed; } else { fetchMask = 0; @@ -2935,7 +2989,7 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer) return; 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); @@ -2967,7 +3021,7 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer) } 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); @@ -2977,7 +3031,7 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer) fetchMask(data->mask, data->xMask, data->yMask + i, data->width, dest_buffer); fbCombineMaskU(src_buffer, dest_buffer, data->width); } - } + } /* fill dest into second half of scanline */ if (fetchDest) @@ -2988,7 +3042,7 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer) /* write back */ store(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer); - } + } } } @@ -3016,7 +3070,7 @@ fbCompositeGeneral (CARD8 op, CARD32 *scanline_buffer = _scanline_buffer; FbComposeData compose_data; - + if (pMask) maskRepeat = pMask->repeat && (pMask->pDrawable->width != 1 || pMask->pDrawable->height != 1); @@ -3036,7 +3090,7 @@ fbCompositeGeneral (CARD8 op, width, height)) return; - + compose_data.op = op; compose_data.src = pSrc; compose_data.mask = pMask; diff --git a/fb/fbpict.c b/fb/fbpict.c index f2b4fe821..8b284082f 100644 --- a/fb/fbpict.c +++ b/fb/fbpict.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Keith Packard, SuSE, Inc. @@ -113,7 +113,7 @@ fbCompositeSolidMask_nx8x8888 (CARD8 op, CARD16 w; fbComposeGetSolid(pSrc, src, pDst->format); - + dstMask = FbFullMask (pDst->pDrawable->depth); srca = src >> 24; if (src == 0) @@ -121,7 +121,7 @@ fbCompositeSolidMask_nx8x8888 (CARD8 op, fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1); fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1); - + while (height--) { dst = dstLine; @@ -172,15 +172,15 @@ fbCompositeSolidMask_nx8888x8888C (CARD8 op, CARD32 m, n, o, p; fbComposeGetSolid(pSrc, src, pDst->format); - + dstMask = FbFullMask (pDst->pDrawable->depth); srca = src >> 24; if (src == 0) return; - + fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1); fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1); - + while (height--) { dst = dstLine; @@ -245,14 +245,14 @@ fbCompositeSolidMask_nx8x0888 (CARD8 op, CARD16 w; fbComposeGetSolid(pSrc, src, pDst->format); - + srca = src >> 24; if (src == 0) return; - + fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3); fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1); - + while (height--) { dst = dstLine; @@ -307,14 +307,14 @@ fbCompositeSolidMask_nx8x0565 (CARD8 op, CARD16 w; fbComposeGetSolid(pSrc, src, pDst->format); - + srca = src >> 24; if (src == 0) return; - + fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1); fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1); - + while (height--) { dst = dstLine; @@ -372,16 +372,16 @@ fbCompositeSolidMask_nx8888x0565C (CARD8 op, CARD32 m, n, o; fbComposeGetSolid(pSrc, src, pDst->format); - + srca = src >> 24; if (src == 0) return; - + src16 = cvt8888to0565(src); - + fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1); fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1); - + while (height--) { dst = dstLine; @@ -440,10 +440,10 @@ fbCompositeSrc_8888x8888 (CARD8 op, FbStride dstStride, srcStride; CARD8 a; CARD16 w; - + fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1); fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1); - + dstMask = FbFullMask (pDst->pDrawable->depth); while (height--) @@ -487,10 +487,10 @@ fbCompositeSrc_8888x0888 (CARD8 op, CARD8 a; FbStride dstStride, srcStride; CARD16 w; - + fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3); fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1); - + while (height--) { dst = dstLine; @@ -536,7 +536,7 @@ fbCompositeSrc_8888x0565 (CARD8 op, CARD8 a; FbStride dstStride, srcStride; CARD16 w; - + fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1); fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1); @@ -586,7 +586,7 @@ fbCompositeSrc_0565x0565 (CARD8 op, CARD16 *srcLine, *src; FbStride dstStride, srcStride; CARD16 w; - + fbComposeGetStart (pSrc, xSrc, ySrc, CARD16, srcStride, srcLine, 1); fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1); @@ -624,7 +624,7 @@ fbCompositeSrcAdd_8000x8000 (CARD8 op, CARD16 w; CARD8 s, d; CARD16 t; - + fbComposeGetStart (pSrc, xSrc, ySrc, CARD8, srcStride, srcLine, 1); fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 1); @@ -675,7 +675,7 @@ fbCompositeSrcAdd_8888x8888 (CARD8 op, CARD32 s, d; CARD16 t; CARD32 m,n,o,p; - + fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1); fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1); @@ -730,7 +730,7 @@ fbCompositeSrcAdd_1000x1000 (CARD8 op, int dstBpp, srcBpp; int dstXoff, dstYoff; int srcXoff, srcYoff; - + fbGetDrawable(pSrc->pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); fbGetDrawable(pDst->pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); @@ -775,13 +775,13 @@ fbCompositeSolidMask_nx1xn (CARD8 op, int dstXoff, dstYoff; int maskXoff, maskYoff; FbBits src; - + fbComposeGetSolid(pSrc, src, pDst->format); if ((src & 0xff000000) != 0xff000000) { fbCompositeGeneral (op, pSrc, pMask, pDst, - xSrc, ySrc, xMask, yMask, xDst, yDst, + xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); return; } @@ -845,7 +845,7 @@ fbComposite (CARD8 op, Bool dstAlphaMap = pDst->alphaMap != 0; int x_msk, y_msk, x_src, y_src, x_dst, y_dst; int w, h, w_this, h_this; - + xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; xSrc += pSrc->pDrawable->x; @@ -857,9 +857,11 @@ fbComposite (CARD8 op, maskRepeat = pMask->repeat; maskAlphaMap = pMask->alphaMap != 0; } - - if (!pSrc->transform && !(pMask && pMask->transform)) - if (!maskAlphaMap && !srcAlphaMap && !dstAlphaMap) + + if (!pSrc->transform && !(pMask && pMask->transform) + && !maskAlphaMap && !srcAlphaMap && !dstAlphaMap + && (pSrc->filter != PictFilterConvolution) + && (!pMask || pMask->filter != PictFilterConvolution)) switch (op) { case PictOpSrc: #ifdef USE_MMX @@ -873,7 +875,7 @@ fbComposite (CARD8 op, case PictOpOver: if (pMask) { - if (srcRepeat && + if (srcRepeat && pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1) { @@ -1026,7 +1028,7 @@ fbComposite (CARD8 op, } break; } - else + else { /* non-repeating source, repeating mask => translucent window */ if (maskRepeat && @@ -1040,7 +1042,7 @@ fbComposite (CARD8 op, #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrc_8888x8x8888mmx; -#endif +#endif } } } @@ -1048,7 +1050,7 @@ fbComposite (CARD8 op, } else /* no mask */ { - if (srcRepeat && + if (srcRepeat && pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1) { @@ -1274,7 +1276,7 @@ fbComposite (CARD8 op, w_this = pSrc->pDrawable->width - x_src; } (*func) (op, pSrc, pMask, pDst, - x_src, y_src, x_msk, y_msk, x_dst, y_dst, + x_src, y_src, x_msk, y_msk, x_dst, y_dst, w_this, h_this); w -= w_this; x_src += w_this; diff --git a/render/filter.c b/render/filter.c index d1dbded6b..935c91515 100644 --- a/render/filter.c +++ b/render/filter.c @@ -47,8 +47,6 @@ static int nfilterNames; * standard but not required filters don't have constant indices */ -int pictFilterConvolution; - int PictureGetFilterId (char *filter, int len, Bool makeit) { @@ -87,18 +85,21 @@ static Bool PictureSetDefaultIds (void) { /* careful here -- this list must match the #define values */ - + if (PictureGetFilterId (FilterNearest, -1, TRUE) != PictFilterNearest) return FALSE; if (PictureGetFilterId (FilterBilinear, -1, TRUE) != PictFilterBilinear) return FALSE; - + if (PictureGetFilterId (FilterFast, -1, TRUE) != PictFilterFast) return FALSE; if (PictureGetFilterId (FilterGood, -1, TRUE) != PictFilterGood) return FALSE; if (PictureGetFilterId (FilterBest, -1, TRUE) != PictFilterBest) return FALSE; + + if (PictureGetFilterId (FilterConvolution, -1, TRUE) != PictFilterConvolution) + return FALSE; return TRUE; } @@ -174,7 +175,7 @@ PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias) if (ps->filterAliases) aliases = xrealloc (ps->filterAliases, - (ps->nfilterAliases + 1) * + (ps->nfilterAliases + 1) * sizeof (PictFilterAliasRec)); else aliases = xalloc (sizeof (PictFilterAliasRec)); @@ -212,6 +213,26 @@ PictureFindFilter (ScreenPtr pScreen, char *name, int len) return 0; } +static Bool +convolutionFilterValidateParams (PicturePtr pPicture, + int filter, + xFixed *params, + int nparams) +{ + if (nparams < 3) + return FALSE; + + if (xFixedFrac (params[0]) || xFixedFrac (params[1])) + return FALSE; + + nparams -= 2; + if ((xFixedToInt (params[0]) * xFixedToInt (params[1])) > nparams) + return FALSE; + + return TRUE; +} + + Bool PictureSetDefaultFilters (ScreenPtr pScreen) { @@ -229,6 +250,10 @@ PictureSetDefaultFilters (ScreenPtr pScreen) return FALSE; if (!PictureSetFilterAlias (pScreen, FilterBilinear, FilterBest)) return FALSE; + + if (PictureAddFilter (pScreen, FilterConvolution, convolutionFilterValidateParams) < 0) + return FALSE; + return TRUE; } diff --git a/render/picturestr.h b/render/picturestr.h index 30630ce06..690e08f4d 100644 --- a/render/picturestr.h +++ b/render/picturestr.h @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Keith Packard, SuSE, Inc. @@ -69,7 +69,7 @@ typedef struct _Picture { int refcnt; CARD32 id; PicturePtr pNext; /* chain on same drawable */ - + unsigned int repeat : 1; unsigned int graphicsExposures : 1; unsigned int subWindowMode : 1; @@ -92,9 +92,9 @@ typedef struct _Picture { unsigned long serialNumber; RegionPtr pCompositeClip; - + DevUnion *devPrivates; - + PictTransform *transform; int filter; @@ -117,6 +117,8 @@ typedef struct { #define PictFilterGood 3 #define PictFilterBest 4 +#define PictFilterConvolution 5 + typedef struct { char *alias; int alias_id; @@ -130,7 +132,7 @@ typedef int (*ChangePictureClipProcPtr) (PicturePtr pPicture, pointer value, int n); typedef void (*DestroyPictureClipProcPtr)(PicturePtr pPicture); - + typedef int (*ChangePictureTransformProcPtr) (PicturePtr pPicture, PictTransform *transform); @@ -246,12 +248,12 @@ typedef struct _PictureScreen { PictFormatPtr formats; PictFormatPtr fallback; int nformats; - + CreatePictureProcPtr CreatePicture; DestroyPictureProcPtr DestroyPicture; ChangePictureClipProcPtr ChangePictureClip; DestroyPictureClipProcPtr DestroyPictureClip; - + ChangePictureProcPtr ChangePicture; ValidatePictureProcPtr ValidatePicture; @@ -269,7 +271,7 @@ typedef struct _PictureScreen { UpdateIndexedProcPtr UpdateIndexed; int subpixel; - + PictFilterPtr filters; int nfilters; PictFilterAliasPtr filterAliases; @@ -278,7 +280,7 @@ typedef struct _PictureScreen { ChangePictureTransformProcPtr ChangePictureTransform; ChangePictureFilterProcPtr ChangePictureFilter; DestroyPictureFilterProcPtr DestroyPictureFilter; - + TrapezoidsProcPtr Trapezoids; TrianglesProcPtr Triangles; TriStripProcPtr TriStrip; @@ -355,7 +357,7 @@ PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual); PictFormatPtr PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 format); - + Bool PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats); @@ -375,7 +377,7 @@ PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias); Bool PictureSetDefaultFilters (ScreenPtr pScreen); - + void PictureResetFilters (ScreenPtr pScreen); @@ -390,7 +392,7 @@ PictureFinishInit (void); void SetPictureToDefaults (PicturePtr pPicture); - + PicturePtr AllocatePicture (ScreenPtr pScreen); @@ -534,7 +536,7 @@ int AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor); void -AddTraps (PicturePtr pPicture, +AddTraps (PicturePtr pPicture, INT16 xOff, INT16 yOff, int ntraps, |