diff options
author | Soren Sandmann Pedersen <sandmann@redhat.com> | 2007-05-17 21:31:08 -0400 |
---|---|---|
committer | Soren Sandmann Pedersen <sandmann@redhat.com> | 2007-05-18 14:06:21 -0400 |
commit | c5ef84c325440af5fbdf9f44c3781d99a0392df9 (patch) | |
tree | bef05e387103cff9ab4bec58b091e5fdf3ecafec | |
parent | 076d070e186afeb416976ae74fbfd50c86db10c5 (diff) |
Make the general compositing code create a pixman image and call
pixman_image_composite(). Leave the general code commented out for now.
-rw-r--r-- | fb/fbcompose.c | 3 | ||||
-rw-r--r-- | fb/fbpict.c | 234 |
2 files changed, 234 insertions, 3 deletions
diff --git a/fb/fbcompose.c b/fb/fbcompose.c index 465f7d343..0e64de08e 100644 --- a/fb/fbcompose.c +++ b/fb/fbcompose.c @@ -1553,7 +1553,6 @@ fbCombineSrcU (CARD32 *dest, const CARD32 *src, int width) MEMCPY_WRAPPED(dest, src, width*sizeof(CARD32)); } - static FASTCALL void fbCombineOverU (CARD32 *dest, const CARD32 *src, int width) { @@ -4028,6 +4027,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 * , CARD32 *, CARD32); +#if 0 void fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer) { @@ -4294,6 +4294,7 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer) if (!store) fbFinishAccess (data->dest->pDrawable); } +#endif void fbCompositeGeneral (CARD8 op, diff --git a/fb/fbpict.c b/fb/fbpict.c index 1146e99ca..4034a16a0 100644 --- a/fb/fbpict.c +++ b/fb/fbpict.c @@ -1,6 +1,7 @@ /* * * Copyright © 2000 SuSE, Inc. + * Copyright © 2007 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -29,6 +30,7 @@ #include <string.h> #include "fb.h" +#include <pixman/pixman.h> #ifdef RENDER @@ -950,7 +952,199 @@ fbCompositeSolidSrc_nxn (CARD8 op, */ #define SCANLINE_BUFFER_LENGTH 2048 - + +static pixman_image_t * +image_from_pict (PicturePtr pict) +{ + pixman_image_t *result = NULL; + + if (!pict) + return NULL; + + if (pict->pSourcePict) + { + SourcePictPtr sp = pict->pSourcePict; + + if (sp->type == SourcePictTypeSolidFill) + { + PictSolidFill *solid = &pict->pSourcePict->solidFill; + pixman_color_t color; + CARD32 a, r, g, b; + + a = (solid->color & 0xff000000) >> 24; + r = (solid->color & 0x00ff0000) >> 16; + g = (solid->color & 0x0000ff00) >> 8; + b = (solid->color & 0x000000ff) >> 0; + + color.alpha = (a << 8) | a; + color.red = (r << 8) | r; + color.green = (g << 8) | g; + color.blue = (b << 8) | b; + + result = pixman_image_create_solid_fill (&color); + } + else + { + PictGradient *gradient = &pict->pSourcePict->gradient; + + if (sp->type == SourcePictTypeLinear) + { + PictLinearGradient *linear = &pict->pSourcePict->linear; + pixman_point_fixed_t p1; + pixman_point_fixed_t p2; + + p1.x = linear->p1.x; + p1.y = linear->p1.y; + p2.x = linear->p2.x; + p2.y = linear->p2.y; + + result = pixman_image_create_linear_gradient ( + &p1, &p2, (pixman_gradient_stop_t *)gradient->stops, gradient->nstops); + } + else if (sp->type == SourcePictTypeRadial) + { + PictRadialGradient *radial = &pict->pSourcePict->radial; + + pixman_point_fixed_t c1; + pixman_point_fixed_t c2; + + c1.x = radial->c1.x; + c1.y = radial->c1.y; + c2.x = radial->c2.x; + c2.y = radial->c2.y; + + result = pixman_image_create_radial_gradient ( + &c1, &c2, radial->c1.radius, + radial->c2.radius, + (pixman_gradient_stop_t *)gradient->stops, gradient->nstops); + } + else if (sp->type == SourcePictTypeConical) + { + PictConicalGradient *conical = &pict->pSourcePict->conical; + pixman_point_fixed_t center; + + center.x = conical->center.x; + center.y = conical->center.y; + + result = pixman_image_create_conical_gradient ( + ¢er, conical->angle, (pixman_gradient_stop_t *)gradient->stops, + gradient->nstops); + } + else + { + /* Shouldn't happen */ + result = NULL; + } + } + } + else if (pict->pDrawable) + { + FbBits *bits; + FbStride stride; + int bpp, xoff, yoff; + + fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff); + + bits += yoff * stride + xoff; + + result = pixman_image_create_bits ( + pict->format, + pict->pDrawable->width, pict->pDrawable->height, + (uint32_t *)bits, stride * sizeof (FbStride)); + + +#ifdef FB_ACCESS_WRAPPER +#if FB_SHIFT==5 + + pixman_image_set_accessors ( + result, + (pixman_read_memory_func_t)wfbReadMemory, + (pixman_write_memory_func_t)wfbWriteMemory); +#else + +#error The pixman library only works with sizeof (FbBits) == 5 + +#endif +#endif + + /* pCompositeClip is undefined for source pictures, so + * only set the clip region for pictures with drawables + */ + pixman_image_set_clip_region ( + result, pict->pCompositeClip); + + fbFinishAccess (pict->pDrawable); + } + + if (result) + { + pixman_repeat_t repeat; + pixman_filter_t filter; + + if (pict->transform) + { + pixman_image_set_transform ( + result, (pixman_transform_t *)pict->transform); + } + + switch (pict->repeatType) + { + default: + case RepeatNone: + repeat = PIXMAN_REPEAT_NONE; + break; + + case RepeatPad: + repeat = PIXMAN_REPEAT_PAD; + break; + + case RepeatNormal: + repeat = PIXMAN_REPEAT_NORMAL; + break; + + case RepeatReflect: + repeat = PIXMAN_REPEAT_REFLECT; + break; + } + + pixman_image_set_repeat (result, repeat); + + if (pict->alphaMap) + { + pixman_image_t *alpha_map = image_from_pict (pict->alphaMap); + + pixman_image_set_alpha_map ( + result, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y); + + pixman_image_unref (alpha_map); + } + + pixman_image_set_component_alpha (result, pict->componentAlpha); + + switch (pict->filter) + { + default: + case PictFilterNearest: + case PictFilterFast: + filter = PIXMAN_FILTER_NEAREST; + break; + + case PictFilterBilinear: + case PictFilterGood: + filter = PIXMAN_FILTER_BILINEAR; + break; + + case PictFilterConvolution: + filter = PIXMAN_FILTER_CONVOLUTION; + break; + } + + pixman_image_set_filter (result, filter, (pixman_fixed_t *)pict->filter_params, pict->filter_nparams); + } + + return result; +} + static void fbCompositeRectWrapper (CARD8 op, PicturePtr pSrc, @@ -965,6 +1159,41 @@ fbCompositeRectWrapper (CARD8 op, CARD16 width, CARD16 height) { + pixman_image_t *src = image_from_pict (pSrc); + pixman_image_t *dest = image_from_pict (pDst); + pixman_image_t *mask = image_from_pict (pMask); + + if (!src || !dest || (pMask && !mask)) + goto out; + + pixman_image_composite_rect (op, src, mask, dest, + xSrc, ySrc, xMask, yMask, xDst, yDst, + width, height); + +out: + if (src) + pixman_image_unref (src); + if (mask) + pixman_image_unref (mask); + if (dest) + pixman_image_unref (dest); +} + +#if 0 +static void +oldfbCompositeRectWrapper (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ CARD32 _scanline_buffer[SCANLINE_BUFFER_LENGTH * 3]; CARD32 *scanline_buffer = _scanline_buffer; FbComposeData data; @@ -990,6 +1219,7 @@ fbCompositeRectWrapper (CARD8 op, if (scanline_buffer != _scanline_buffer) free(scanline_buffer); } +#endif void fbWalkCompositeRegion (CARD8 op, @@ -1030,7 +1260,7 @@ fbWalkCompositeRegion (CARD8 op, if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) return; - + n = REGION_NUM_RECTS (®ion); pbox = REGION_RECTS (®ion); while (n--) |