summaryrefslogtreecommitdiff
path: root/fb/fbpict.c
diff options
context:
space:
mode:
authorSoren Sandmann Pedersen <sandmann@redhat.com>2007-05-17 21:31:08 -0400
committerSoren Sandmann Pedersen <sandmann@redhat.com>2007-05-18 14:06:21 -0400
commitc5ef84c325440af5fbdf9f44c3781d99a0392df9 (patch)
treebef05e387103cff9ab4bec58b091e5fdf3ecafec /fb/fbpict.c
parent076d070e186afeb416976ae74fbfd50c86db10c5 (diff)
Make the general compositing code create a pixman image and call
pixman_image_composite(). Leave the general code commented out for now.
Diffstat (limited to 'fb/fbpict.c')
-rw-r--r--fb/fbpict.c234
1 files changed, 232 insertions, 2 deletions
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 (
+ &center, 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 (&region, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height))
return;
-
+
n = REGION_NUM_RECTS (&region);
pbox = REGION_RECTS (&region);
while (n--)