summaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
Diffstat (limited to 'render')
-rw-r--r--render/filter.c48
-rw-r--r--render/glyph.c60
-rw-r--r--render/glyphstr.h21
-rw-r--r--render/mipict.c161
-rw-r--r--render/mipict.h3
-rw-r--r--render/mirect.c11
-rw-r--r--render/mitrap.c70
-rw-r--r--render/mitri.c274
-rw-r--r--render/picture.c228
-rw-r--r--render/picture.h8
-rw-r--r--render/picturestr.h64
-rw-r--r--render/render.c85
-rw-r--r--render/renderedge.c197
-rw-r--r--render/renderedge.h120
14 files changed, 1018 insertions, 332 deletions
diff --git a/render/filter.c b/render/filter.c
index 4435197e2..cb9297e9c 100644
--- a/render/filter.c
+++ b/render/filter.c
@@ -1,7 +1,7 @@
/*
- * $XFree86$
+ * $Id$
*
- * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ * Copyright © 2002 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -22,6 +22,9 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include "misc.h"
#include "scrnintstr.h"
#include "os.h"
@@ -40,6 +43,12 @@
static char **filterNames;
static int nfilterNames;
+/*
+ * standard but not required filters don't have constant indices
+ */
+
+int pictFilterConvolution;
+
int
PictureGetFilterId (char *filter, int len, Bool makeit)
{
@@ -50,15 +59,14 @@ PictureGetFilterId (char *filter, int len, Bool makeit)
if (len < 0)
len = strlen (filter);
for (i = 0; i < nfilterNames; i++)
- if (len == strlen (filterNames[i]) &&
- !strncmp (filterNames[i], filter, len))
+ if (!CompareISOLatin1Lowered ((unsigned char *) filterNames[i], -1, (unsigned char *) filter, len))
return i;
if (!makeit)
return -1;
- name = xalloc (strlen (filter) + 1);
+ name = xalloc (len + 1);
if (!name)
return -1;
- strncpy (name, filter, len);
+ memcpy (name, filter, len);
name[len] = '\0';
if (filterNames)
names = xrealloc (filterNames, (nfilterNames + 1) * sizeof (char *));
@@ -116,7 +124,9 @@ PictureFreeFilterIds (void)
}
int
-PictureAddFilter (ScreenPtr pScreen, char *filter, xFixed *params, int nparams)
+PictureAddFilter (ScreenPtr pScreen,
+ char *filter,
+ PictFilterValidateParamsProcPtr ValidateParams)
{
PictureScreenPtr ps = GetPictureScreen(pScreen);
int id = PictureGetFilterId (filter, -1, TRUE);
@@ -140,9 +150,8 @@ PictureAddFilter (ScreenPtr pScreen, char *filter, xFixed *params, int nparams)
ps->filters = filters;
i = ps->nfilters++;
ps->filters[i].name = PictureGetFilterName (id);
- ps->filters[i].params = params;
- ps->filters[i].nparams = nparams;
ps->filters[i].id = id;
+ ps->filters[i].ValidateParams = ValidateParams;
return id;
}
@@ -209,9 +218,9 @@ PictureSetDefaultFilters (ScreenPtr pScreen)
if (!filterNames)
if (!PictureSetDefaultIds ())
return FALSE;
- if (PictureAddFilter (pScreen, FilterNearest, 0, 0) < 0)
+ if (PictureAddFilter (pScreen, FilterNearest, 0) < 0)
return FALSE;
- if (PictureAddFilter (pScreen, FilterBilinear, 0, 0) < 0)
+ if (PictureAddFilter (pScreen, FilterBilinear, 0) < 0)
return FALSE;
if (!PictureSetFilterAlias (pScreen, FilterNearest, FilterFast))
@@ -243,21 +252,26 @@ SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int
if (!pFilter)
return BadName;
- if (nparams > pFilter->nparams)
+ if (pFilter->ValidateParams)
+ {
+ if (!(*pFilter->ValidateParams) (pPicture, pFilter->id, params, nparams))
+ return BadMatch;
+ }
+ else if (nparams)
return BadMatch;
- if (pFilter->nparams != pPicture->filter_nparams)
+
+ if (nparams != pPicture->filter_nparams)
{
- new_params = xalloc (pFilter->nparams * sizeof (xFixed));
+ new_params = xalloc (nparams * sizeof (xFixed));
if (!new_params)
return BadAlloc;
xfree (pPicture->filter_params);
pPicture->filter_params = new_params;
- pPicture->filter_nparams = pFilter->nparams;
+ pPicture->filter_nparams = nparams;
}
for (i = 0; i < nparams; i++)
pPicture->filter_params[i] = params[i];
- for (; i < pFilter->nparams; i++)
- pPicture->filter_params[i] = pFilter->params[i];
pPicture->filter = pFilter->id;
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
return Success;
}
diff --git a/render/glyph.c b/render/glyph.c
index 5dd700581..e4c2f689e 100644
--- a/render/glyph.c
+++ b/render/glyph.c
@@ -89,6 +89,50 @@ FindGlyphHashSet (CARD32 filled)
return 0;
}
+static int _GlyphSetPrivateAllocateIndex = 0;
+
+int
+AllocateGlyphSetPrivateIndex (void)
+{
+ return _GlyphSetPrivateAllocateIndex++;
+}
+
+void
+ResetGlyphSetPrivateIndex (void)
+{
+ _GlyphSetPrivateAllocateIndex = 0;
+}
+
+Bool
+_GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr)
+{
+ pointer *new;
+
+ if (n > glyphSet->maxPrivate) {
+ if (glyphSet->devPrivates &&
+ glyphSet->devPrivates != (pointer)(&glyphSet[1])) {
+ new = (pointer *) xrealloc (glyphSet->devPrivates,
+ (n + 1) * sizeof (pointer));
+ if (!new)
+ return FALSE;
+ } else {
+ new = (pointer *) xalloc ((n + 1) * sizeof (pointer));
+ if (!new)
+ return FALSE;
+ if (glyphSet->devPrivates)
+ memcpy (new,
+ glyphSet->devPrivates,
+ (glyphSet->maxPrivate + 1) * sizeof (pointer));
+ }
+ glyphSet->devPrivates = new;
+ /* Zero out new, uninitialize privates */
+ while (++glyphSet->maxPrivate < n)
+ glyphSet->devPrivates[glyphSet->maxPrivate] = (pointer)0;
+ }
+ glyphSet->devPrivates[n] = ptr;
+ return TRUE;
+}
+
Bool
GlyphInit (ScreenPtr pScreen)
{
@@ -363,15 +407,24 @@ GlyphSetPtr
AllocateGlyphSet (int fdepth, PictFormatPtr format)
{
GlyphSetPtr glyphSet;
+ int size;
if (!globalGlyphs[fdepth].hashSet)
{
if (!AllocateGlyphHash (&globalGlyphs[fdepth], &glyphHashSets[0]))
return FALSE;
}
- glyphSet = xalloc (sizeof (GlyphSetRec));
+
+ size = (sizeof (GlyphSetRec) +
+ (sizeof (pointer) * _GlyphSetPrivateAllocateIndex));
+ glyphSet = xalloc (size);
if (!glyphSet)
return FALSE;
+ bzero((char *)glyphSet, size);
+ glyphSet->maxPrivate = _GlyphSetPrivateAllocateIndex - 1;
+ if (_GlyphSetPrivateAllocateIndex)
+ glyphSet->devPrivates = (pointer)(&glyphSet[1]);
+
if (!AllocateGlyphHash (&glyphSet->hash, &glyphHashSets[0]))
{
xfree (glyphSet);
@@ -410,6 +463,11 @@ FreeGlyphSet (pointer value,
else
ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], 0, TRUE);
xfree (table);
+
+ if (glyphSet->devPrivates &&
+ glyphSet->devPrivates != (pointer)(&glyphSet[1]))
+ xfree(glyphSet->devPrivates);
+
xfree (glyphSet);
}
return Success;
diff --git a/render/glyphstr.h b/render/glyphstr.h
index 68d6f2085..0f496d704 100644
--- a/render/glyphstr.h
+++ b/render/glyphstr.h
@@ -68,8 +68,20 @@ typedef struct _GlyphSet {
PictFormatPtr format;
int fdepth;
GlyphHashRec hash;
+ int maxPrivate;
+ pointer *devPrivates;
} GlyphSetRec, *GlyphSetPtr;
+#define GlyphSetGetPrivate(pGlyphSet,n) \
+ ((n) > (pGlyphSet)->maxPrivate ? \
+ (pointer) 0 : \
+ (pGlyphSet)->devPrivates[n])
+
+#define GlyphSetSetPrivate(pGlyphSet,n,ptr) \
+ ((n) > (pGlyphSet)->maxPrivate ? \
+ _GlyphSetSetNewPrivate(pGlyphSet, n, ptr) : \
+ ((((pGlyphSet)->devPrivates[n] = (ptr)) != 0) || TRUE))
+
typedef struct _GlyphList {
INT16 xOff;
INT16 yOff;
@@ -82,6 +94,15 @@ extern GlyphHashRec globalGlyphs[GlyphFormatNum];
GlyphHashSetPtr
FindGlyphHashSet (CARD32 filled);
+int
+AllocateGlyphSetPrivateIndex (void);
+
+void
+ResetGlyphSetPrivateIndex (void);
+
+Bool
+_GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr);
+
Bool
GlyphInit (ScreenPtr pScreen);
diff --git a/render/mipict.c b/render/mipict.c
index ed97acc7b..8e51ebeab 100644
--- a/render/mipict.c
+++ b/render/mipict.c
@@ -249,8 +249,7 @@ miValidatePicture (PicturePtr pPicture,
#define BOUND(v) (INT16) ((v) < MINSHORT ? MINSHORT : (v) > MAXSHORT ? MAXSHORT : (v))
static __inline Bool
-miClipPictureReg (ScreenPtr pScreen,
- RegionPtr pRegion,
+miClipPictureReg (RegionPtr pRegion,
RegionPtr pClip,
int dx,
int dy)
@@ -276,19 +275,22 @@ miClipPictureReg (ScreenPtr pScreen,
REGION_EMPTY(pScreen, pRegion);
}
}
+ else if (!REGION_NOTEMPTY (pScreen, pClip))
+ return FALSE;
else
{
- REGION_TRANSLATE(pScreen, pRegion, dx, dy);
+ if (dx || dy)
+ REGION_TRANSLATE(pScreen, pRegion, -dx, -dy);
if (!REGION_INTERSECT (pScreen, pRegion, pRegion, pClip))
return FALSE;
- REGION_TRANSLATE(pScreen, pRegion, -dx, -dy);
+ if (dx || dy)
+ REGION_TRANSLATE(pScreen, pRegion, dx, dy);
}
- return TRUE;
+ return REGION_NOTEMPTY(pScreen, pRegion);
}
static __inline Bool
-miClipPictureSrc (ScreenPtr pScreen,
- RegionPtr pRegion,
+miClipPictureSrc (RegionPtr pRegion,
PicturePtr pPicture,
int dx,
int dy)
@@ -314,11 +316,70 @@ miClipPictureSrc (ScreenPtr pScreen,
}
else
{
- return miClipPictureReg (pScreen, pRegion, pPicture->pCompositeClip,
- dx, dy);
+ return miClipPictureReg (pRegion,
+ pPicture->pCompositeClip,
+ dx,
+ dy);
+ }
+}
+
+static void
+miCompositeSourceValidate (PicturePtr pPicture,
+ INT16 x,
+ INT16 y,
+ CARD16 width,
+ CARD16 height)
+{
+ DrawablePtr pDrawable = pPicture->pDrawable;
+ ScreenPtr pScreen = pDrawable->pScreen;
+
+ if (pScreen->SourceValidate)
+ {
+ x -= pPicture->pDrawable->x;
+ y -= pPicture->pDrawable->y;
+ if (pPicture->transform)
+ {
+ xPoint points[4];
+ int i;
+ int xmin, ymin, xmax, ymax;
+
+#define VectorSet(i,_x,_y) { points[i].x = _x; points[i].y = _y; }
+ VectorSet (0, x, y);
+ VectorSet (1, x + width, y);
+ VectorSet (2, x, y + height);
+ VectorSet (3, x + width, y + height);
+ xmin = ymin = 32767;
+ xmax = ymax = -32737;
+ for (i = 0; i < 4; i++)
+ {
+ PictVector t;
+ t.vector[0] = IntToxFixed (points[i].x);
+ t.vector[1] = IntToxFixed (points[i].y);
+ t.vector[2] = xFixed1;
+ if (PictureTransformPoint (pPicture->transform, &t))
+ {
+ int tx = xFixedToInt (t.vector[0]);
+ int ty = xFixedToInt (t.vector[1]);
+ if (tx < xmin) xmin = tx;
+ if (tx > xmax) xmax = tx;
+ if (ty < ymin) ymin = ty;
+ if (ty > ymax) ymax = ty;
+ }
+ }
+ x = xmin;
+ y = ymin;
+ width = xmax - xmin;
+ height = ymax - ymin;
+ }
+ (*pScreen->SourceValidate) (pDrawable, x, y, width, height);
}
}
+/*
+ * returns FALSE if the final region is empty. Indistinguishable from
+ * an allocation failure, but rendering ignores those anyways.
+ */
+
Bool
miComputeCompositeRegion (RegionPtr pRegion,
PicturePtr pSrc,
@@ -333,7 +394,6 @@ miComputeCompositeRegion (RegionPtr pRegion,
CARD16 width,
CARD16 height)
{
- ScreenPtr pScreen = pSrc->pDrawable->pScreen;
int v;
pRegion->extents.x1 = xDst;
@@ -347,18 +407,34 @@ miComputeCompositeRegion (RegionPtr pRegion,
if (pRegion->extents.x1 >= pRegion->extents.x2 ||
pRegion->extents.y1 >= pRegion->extents.y2)
{
- REGION_EMPTY (pScreen, pRegion);
- return TRUE;
+ REGION_EMPTY (pDst->pDrawable->pScreen, pRegion);
+ return FALSE;
+ }
+ /* clip against dst */
+ if (!miClipPictureReg (pRegion, pDst->pCompositeClip, 0, 0))
+ {
+ REGION_UNINIT (pScreen, pRegion);
+ return FALSE;
+ }
+ if (pDst->alphaMap)
+ {
+ if (!miClipPictureReg (pRegion, pDst->alphaMap->pCompositeClip,
+ -pDst->alphaOrigin.x,
+ -pDst->alphaOrigin.y))
+ {
+ REGION_UNINIT (pScreen, pRegion);
+ return FALSE;
+ }
}
/* clip against src */
- if (!miClipPictureSrc (pScreen, pRegion, pSrc, xDst - xSrc, yDst - ySrc))
+ if (!miClipPictureSrc (pRegion, pSrc, xDst - xSrc, yDst - ySrc))
{
REGION_UNINIT (pScreen, pRegion);
return FALSE;
}
if (pSrc->alphaMap)
{
- if (!miClipPictureSrc (pScreen, pRegion, pSrc->alphaMap,
+ if (!miClipPictureSrc (pRegion, pSrc->alphaMap,
xDst - (xSrc + pSrc->alphaOrigin.x),
yDst - (ySrc + pSrc->alphaOrigin.y)))
{
@@ -369,15 +445,14 @@ miComputeCompositeRegion (RegionPtr pRegion,
/* clip against mask */
if (pMask)
{
- if (!miClipPictureSrc (pScreen, pRegion, pMask,
- xDst - xMask, yDst - yMask))
+ if (!miClipPictureSrc (pRegion, pMask, xDst - xMask, yDst - yMask))
{
REGION_UNINIT (pScreen, pRegion);
return FALSE;
}
if (pMask->alphaMap)
{
- if (!miClipPictureSrc (pScreen, pRegion, pMask->alphaMap,
+ if (!miClipPictureSrc (pRegion, pMask->alphaMap,
xDst - (xMask + pMask->alphaOrigin.x),
yDst - (yMask + pMask->alphaOrigin.y)))
{
@@ -386,22 +461,9 @@ miComputeCompositeRegion (RegionPtr pRegion,
}
}
}
- if (!miClipPictureReg (pScreen, pRegion, pDst->pCompositeClip, 0, 0))
- {
- REGION_UNINIT (pScreen, pRegion);
- return FALSE;
- }
- if (pDst->alphaMap)
- {
- if (!miClipPictureReg (pScreen,
- pRegion, pDst->alphaMap->pCompositeClip,
- -pDst->alphaOrigin.x,
- -pDst->alphaOrigin.y))
- {
- REGION_UNINIT (pScreen, pRegion);
- return FALSE;
- }
- }
+ miCompositeSourceValidate (pSrc, xSrc, ySrc, width, height);
+ if (pMask)
+ miCompositeSourceValidate (pMask, xMask, yMask, width, height);
return TRUE;
}
@@ -456,6 +518,35 @@ miFillColor (CARD32 pixel, int bits)
return (CARD16) pixel;
}
+Bool
+miIsSolidAlpha (PicturePtr pSrc)
+{
+ ScreenPtr pScreen = pSrc->pDrawable->pScreen;
+ char line[1];
+
+ /* Alpha-only */
+ if (PICT_FORMAT_TYPE (pSrc->format) != PICT_TYPE_A)
+ return FALSE;
+ /* repeat */
+ if (!pSrc->repeat)
+ return FALSE;
+ /* 1x1 */
+ if (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1)
+ return FALSE;
+ line[0] = 1;
+ (*pScreen->GetImage) (pSrc->pDrawable, 0, 0, 1, 1, ZPixmap, ~0L, line);
+ switch (pSrc->pDrawable->bitsPerPixel) {
+ case 1:
+ return (CARD8) line[0] == 1 || (CARD8) line[0] == 0x80;
+ case 4:
+ return (CARD8) line[0] == 0xf || (CARD8) line[0] == 0xf0;
+ case 8:
+ return (CARD8) line[0] == 0xff;
+ default:
+ return FALSE;
+ }
+}
+
void
miRenderPixelToColor (PictFormatPtr format,
CARD32 pixel,
@@ -516,5 +607,9 @@ miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
ps->TriStrip = miTriStrip;
ps->TriFan = miTriFan;
+ ps->RasterizeTrapezoid = 0; /* requires DDX support */
+ ps->AddTraps = 0; /* requires DDX support */
+ ps->AddTriangles = 0; /* requires DDX support */
+
return TRUE;
}
diff --git a/render/mipict.h b/render/mipict.h
index 4af4c56be..f990e7939 100644
--- a/render/mipict.h
+++ b/render/mipict.h
@@ -124,6 +124,9 @@ miRenderPixelToColor (PictFormatPtr pPict,
CARD32 pixel,
xRenderColor *color);
+Bool
+miIsSolidAlpha (PicturePtr pSrc);
+
void
miCompositeRects (CARD8 op,
PicturePtr pDst,
diff --git a/render/mirect.c b/render/mirect.c
index 63e9c7cc4..bb50e8583 100644
--- a/render/mirect.c
+++ b/render/mirect.c
@@ -42,7 +42,7 @@ miColorRects (PicturePtr pDst,
ScreenPtr pScreen = pDst->pDrawable->pScreen;
CARD32 pixel;
GCPtr pGC;
- CARD32 tmpval[4];
+ CARD32 tmpval[5];
RegionPtr pClip;
unsigned long mask;
@@ -53,12 +53,13 @@ miColorRects (PicturePtr pDst,
return;
tmpval[0] = GXcopy;
tmpval[1] = pixel;
- mask = GCFunction | GCForeground;
+ tmpval[2] = pDst->subWindowMode;
+ mask = GCFunction | GCForeground | GCSubwindowMode;
if (pClipPict->clientClipType == CT_REGION)
{
- tmpval[2] = pDst->clipOrigin.x - xoff;
- tmpval[3] = pDst->clipOrigin.y - yoff;
- mask |= CPClipXOrigin|CPClipYOrigin;
+ tmpval[3] = pDst->clipOrigin.x - xoff;
+ tmpval[4] = pDst->clipOrigin.y - yoff;
+ mask |= GCClipXOrigin|GCClipYOrigin;
pClip = REGION_CREATE (pScreen, NULL, 1);
REGION_COPY (pScreen, pClip,
diff --git a/render/mitrap.c b/render/mitrap.c
index 05db36ec8..77cdcf03f 100644
--- a/render/mitrap.c
+++ b/render/mitrap.c
@@ -136,16 +136,25 @@ miTrapezoids (CARD8 op,
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
PictureScreenPtr ps = GetPictureScreen(pScreen);
- PicturePtr pPicture = 0;
- BoxRec bounds;
- INT16 xDst, yDst;
- INT16 xRel, yRel;
-
- xDst = traps[0].left.p1.x >> 16;
- yDst = traps[0].left.p1.y >> 16;
-
- if (maskFormat)
+
+ /*
+ * Check for solid alpha add
+ */
+ if (op == PictOpAdd && miIsSolidAlpha (pSrc))
+ {
+ for (; ntrap; ntrap--, traps++)
+ (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
+ }
+ else if (maskFormat)
{
+ PicturePtr pPicture;
+ BoxRec bounds;
+ INT16 xDst, yDst;
+ INT16 xRel, yRel;
+
+ xDst = traps[0].left.p1.x >> 16;
+ yDst = traps[0].left.p1.y >> 16;
+
miTrapezoidBounds (ntrap, traps, &bounds);
if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
return;
@@ -154,37 +163,9 @@ miTrapezoids (CARD8 op,
bounds.y2 - bounds.y1);
if (!pPicture)
return;
- }
- for (; ntrap; ntrap--, traps++)
- {
- if (!xTrapezoidValid(traps))
- continue;
- if (!maskFormat)
- {
- miTrapezoidBounds (1, traps, &bounds);
- if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
- continue;
- pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
- bounds.x2 - bounds.x1,
- bounds.y2 - bounds.y1);
- if (!pPicture)
- continue;
- }
- (*ps->RasterizeTrapezoid) (pPicture, traps,
- -bounds.x1, -bounds.y1);
- if (!maskFormat)
- {
- xRel = bounds.x1 + xSrc - xDst;
- yRel = bounds.y1 + ySrc - yDst;
- CompositePicture (op, pSrc, pPicture, pDst,
- xRel, yRel, 0, 0, bounds.x1, bounds.y1,
- bounds.x2 - bounds.x1,
- bounds.y2 - bounds.y1);
- FreePicture (pPicture, 0);
- }
- }
- if (maskFormat)
- {
+ for (; ntrap; ntrap--, traps++)
+ (*ps->RasterizeTrapezoid) (pPicture, traps,
+ -bounds.x1, -bounds.y1);
xRel = bounds.x1 + xSrc - xDst;
yRel = bounds.y1 + ySrc - yDst;
CompositePicture (op, pSrc, pPicture, pDst,
@@ -193,4 +174,13 @@ miTrapezoids (CARD8 op,
bounds.y2 - bounds.y1);
FreePicture (pPicture, 0);
}
+ else
+ {
+ if (pDst->polyEdge == PolyEdgeSharp)
+ maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+ else
+ maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+ for (; ntrap; ntrap--, traps++)
+ miTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps);
+ }
}
diff --git a/render/mitri.c b/render/mitri.c
index b0526256d..5d5df1c61 100644
--- a/render/mitri.c
+++ b/render/mitri.c
@@ -65,82 +65,6 @@ miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds)
}
void
-miRasterizeTriangle (PicturePtr pPicture,
- xTriangle *tri,
- int x_off,
- int y_off)
-{
- ScreenPtr pScreen = pPicture->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- xPointFixed *top, *left, *right, *t;
- xTrapezoid trap[2];
-
- top = &tri->p1;
- left = &tri->p2;
- right = &tri->p3;
- if (left->y < top->y) {
- t = left; left = top; top = t;
- }
- if (right->y < top->y) {
- t = right; right = top; top = t;
- }
- if (right->x < left->x) {
- t = right; right = left; left = t;
- }
-
- /*
- * Two cases:
- *
- * + +
- * / \ / \
- * / \ / \
- * / + + \
- * / -- -- \
- * / -- -- \
- * / --- --- \
- * +-- --+
- */
-
- trap[0].top = top->y;
-
- trap[0].left.p1.x = top->x;
- trap[0].left.p1.y = trap[0].top;
- trap[0].left.p2.x = left->x;
- trap[0].left.p2.y = left->y;
-
- trap[0].right.p1 = trap[0].left.p1;
- trap[0].right.p2.x = right->x;
- trap[0].right.p2.y = right->y;
-
- if (right->y < left->y)
- {
- trap[0].bottom = trap[0].right.p2.y;
-
- trap[1].top = trap[0].bottom;
- trap[1].bottom = trap[0].left.p2.y;
-
- trap[1].left = trap[0].left;
- trap[1].right.p1 = trap[0].right.p2;
- trap[1].right.p2 = trap[0].left.p2;
- }
- else
- {
- trap[0].bottom = trap[0].left.p2.y;
-
- trap[1].top = trap[0].bottom;
- trap[1].bottom = trap[0].right.p2.y;
-
- trap[1].right = trap[0].right;
- trap[1].left.p1 = trap[0].left.p2;
- trap[1].left.p2 = trap[0].right.p2;
- }
- if (trap[0].top != trap[0].bottom)
- (*ps->RasterizeTrapezoid) (pPicture, &trap[0], x_off, y_off);
- if (trap[1].top != trap[1].bottom)
- (*ps->RasterizeTrapezoid) (pPicture, &trap[1], x_off, y_off);
-}
-
-void
miTriangles (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
@@ -151,16 +75,25 @@ miTriangles (CARD8 op,
xTriangle *tris)
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
- BoxRec bounds;
- PicturePtr pPicture = 0;
- INT16 xDst, yDst;
- INT16 xRel, yRel;
-
- xDst = tris[0].p1.x >> 16;
- yDst = tris[0].p1.y >> 16;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
- if (maskFormat)
+ /*
+ * Check for solid alpha add
+ */
+ if (op == PictOpAdd && miIsSolidAlpha (pSrc))
{
+ (*ps->AddTriangles) (pDst, 0, 0, ntri, tris);
+ }
+ else if (maskFormat)
+ {
+ BoxRec bounds;
+ PicturePtr pPicture;
+ INT16 xDst, yDst;
+ INT16 xRel, yRel;
+
+ xDst = tris[0].p1.x >> 16;
+ yDst = tris[0].p1.y >> 16;
+
miTriangleBounds (ntri, tris, &bounds);
if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1)
return;
@@ -169,34 +102,8 @@ miTriangles (CARD8 op,
bounds.y2 - bounds.y1);
if (!pPicture)
return;
- }
- for (; ntri; ntri--, tris++)
- {
- if (!maskFormat)
- {
- miTriangleBounds (1, tris, &bounds);
- if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1)
- continue;
- pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
- bounds.x2 - bounds.x1,
- bounds.y2 - bounds.y1);
- if (!pPicture)
- break;
- }
- miRasterizeTriangle (pPicture, tris, -bounds.x1, -bounds.y1);
- if (!maskFormat)
- {
- xRel = bounds.x1 + xSrc - xDst;
- yRel = bounds.y1 + ySrc - yDst;
- CompositePicture (op, pSrc, pPicture, pDst,
- xRel, yRel, 0, 0, bounds.x1, bounds.y1,
- bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
- FreePicture (pPicture, 0);
- }
- /* XXX adjust xSrc and ySrc */
- }
- if (maskFormat)
- {
+ (*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris);
+
xRel = bounds.x1 + xSrc - xDst;
yRel = bounds.y1 + ySrc - yDst;
CompositePicture (op, pSrc, pPicture, pDst,
@@ -204,6 +111,16 @@ miTriangles (CARD8 op,
bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
FreePicture (pPicture, 0);
}
+ else
+ {
+ if (pDst->polyEdge == PolyEdgeSharp)
+ maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+ else
+ maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+
+ for (; ntri; ntri--, tris++)
+ miTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris);
+ }
}
void
@@ -217,64 +134,24 @@ miTriStrip (CARD8 op,
xPointFixed *points)
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
- xTriangle tri;
- BoxRec bounds;
- PicturePtr pPicture = 0;
- INT16 xDst, yDst;
- INT16 xRel, yRel;
-
- xDst = points[0].x >> 16;
- yDst = points[0].y >> 16;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ xTriangle *tris, *tri;
+ int ntri;
if (npoint < 3)
return;
- if (maskFormat)
- {
- miPointFixedBounds (npoint, points, &bounds);
- if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1)
- return;
- pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
- bounds.x2 - bounds.x1,
- bounds.y2 - bounds.y1);
- if (!pPicture)
- return;
- }
- for (; npoint >= 3; npoint--, points++)
- {
- tri.p1 = points[0];
- tri.p2 = points[1];
- tri.p3 = points[2];
- if (!maskFormat)
- {
- miTriangleBounds (1, &tri, &bounds);
- if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1)
- continue;
- pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
- bounds.x2 - bounds.x1,
- bounds.y2 - bounds.y1);
- if (!pPicture)
- continue;
- }
- miRasterizeTriangle (pPicture, &tri, -bounds.x1, -bounds.y1);
- if (!maskFormat)
- {
- xRel = bounds.x1 + xSrc - xDst;
- yRel = bounds.y1 + ySrc - yDst;
- CompositePicture (op, pSrc, pPicture, pDst,
- xRel, yRel, 0, 0, bounds.x1, bounds.y1,
- bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
- FreePicture (pPicture, 0);
- }
- }
- if (maskFormat)
+ ntri = npoint - 2;
+ tris = ALLOCATE_LOCAL (ntri & sizeof (xTriangle));
+ if (!tris)
+ return;
+ for (tri = tris; npoint >= 3; npoint--, points++, tri++)
{
- xRel = bounds.x1 + xSrc - xDst;
- yRel = bounds.y1 + ySrc - yDst;
- CompositePicture (op, pSrc, pPicture, pDst,
- xRel, yRel, 0, 0, bounds.x1, bounds.y1,
- bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
- FreePicture (pPicture, 0);
+ tri->p1 = points[0];
+ tri->p2 = points[1];
+ tri->p3 = points[2];
}
+ (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
+ DEALLOCATE_LOCAL (tris);
}
void
@@ -288,65 +165,24 @@ miTriFan (CARD8 op,
xPointFixed *points)
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
- xTriangle tri;
- BoxRec bounds;
- PicturePtr pPicture = 0;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ xTriangle *tris, *tri;
xPointFixed *first;
- INT16 xDst, yDst;
- INT16 xRel, yRel;
-
- xDst = points[0].x >> 16;
- yDst = points[0].y >> 16;
+ int ntri;
if (npoint < 3)
return;
- if (maskFormat)
- {
- miPointFixedBounds (npoint, points, &bounds);
- if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1)
- return;
- pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
- bounds.x2 - bounds.x1,
- bounds.y2 - bounds.y1);
- if (!pPicture)
- return;
- }
+ ntri = npoint - 2;
+ tris = ALLOCATE_LOCAL (ntri & sizeof (xTriangle));
+ if (!tris)
+ return;
first = points++;
- npoint--;
- for (; npoint >= 2; npoint--, points++)
+ for (tri = tris; npoint >= 3; npoint--, points++, tri++)
{
- tri.p1 = *first;
- tri.p2 = points[0];
- tri.p3 = points[1];
- if (!maskFormat)
- {
- miTriangleBounds (1, &tri, &bounds);
- if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1)
- continue;
- pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
- bounds.x2 - bounds.x1,
- bounds.y2 - bounds.y1);
- if (!pPicture)
- continue;
- }
- miRasterizeTriangle (pPicture, &tri, -bounds.x1, -bounds.y1);
- if (!maskFormat)
- {
- xRel = bounds.x1 + xSrc - xDst;
- yRel = bounds.y1 + ySrc - yDst;
- CompositePicture (op, pSrc, pPicture, pDst,
- xRel, yRel, 0, 0, bounds.x1, bounds.y1,
- bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
- FreePicture (pPicture, 0);
- }
- }
- if (maskFormat)
- {
- xRel = bounds.x1 + xSrc - xDst;
- yRel = bounds.y1 + ySrc - yDst;
- CompositePicture (op, pSrc, pPicture, pDst,
- xRel, yRel, 0, 0, bounds.x1, bounds.y1,
- bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
- FreePicture (pPicture, 0);
+ tri->p1 = *first;
+ tri->p2 = points[0];
+ tri->p3 = points[1];
}
+ (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
+ DEALLOCATE_LOCAL (tris);
}
diff --git a/render/picture.c b/render/picture.c
index ad746b277..b0c44e694 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -23,6 +23,9 @@
* Author: Keith Packard, SuSE, Inc.
*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include "misc.h"
#include "scrnintstr.h"
#include "os.h"
@@ -46,6 +49,57 @@ RESTYPE PictFormatType;
RESTYPE GlyphSetType;
int PictureCmapPolicy = PictureCmapPolicyDefault;
+/* Picture Private machinery */
+
+static int picturePrivateCount;
+
+void
+ResetPicturePrivateIndex (void)
+{
+ picturePrivateCount = 0;
+}
+
+int
+AllocatePicturePrivateIndex (void)
+{
+ return picturePrivateCount++;
+}
+
+Bool
+AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ unsigned int oldamount;
+
+ /* Round up sizes for proper alignment */
+ amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+ if (index2 >= ps->PicturePrivateLen)
+ {
+ unsigned int *nsizes;
+
+ nsizes = (unsigned int *)xrealloc(ps->PicturePrivateSizes,
+ (index2 + 1) * sizeof(unsigned int));
+ if (!nsizes)
+ return FALSE;
+ while (ps->PicturePrivateLen <= index2)
+ {
+ nsizes[ps->PicturePrivateLen++] = 0;
+ ps->totalPictureSize += sizeof(DevUnion);
+ }
+ ps->PicturePrivateSizes = nsizes;
+ }
+ oldamount = ps->PicturePrivateSizes[index2];
+ if (amount > oldamount)
+ {
+ ps->PicturePrivateSizes[index2] = amount;
+ ps->totalPictureSize += (amount - oldamount);
+ }
+
+ return TRUE;
+}
+
+
Bool
PictureDestroyWindow (WindowPtr pWindow)
{
@@ -82,6 +136,8 @@ PictureCloseScreen (int index, ScreenPtr pScreen)
if (ps->formats[n].type == PictTypeIndexed)
(*ps->CloseIndexed) (pScreen, &ps->formats[n]);
SetPictureScreen(pScreen, 0);
+ if (ps->PicturePrivateSizes)
+ xfree (ps->PicturePrivateSizes);
xfree (ps->formats);
xfree (ps);
return ret;
@@ -367,7 +423,7 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
case PICT_TYPE_COLOR:
case PICT_TYPE_GRAY:
pFormats[f].type = PictTypeIndexed;
- pFormats[f].index.pVisual = &pScreen->visuals[PICT_FORMAT_VIS(format)];
+ pFormats[f].index.vid = pScreen->visuals[PICT_FORMAT_VIS(format)].vid;
break;
}
}
@@ -375,6 +431,21 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
return pFormats;
}
+static VisualPtr
+PictureFindVisual (ScreenPtr pScreen, VisualID visual)
+{
+ int i;
+ VisualPtr pVisual;
+ for (i = 0, pVisual = pScreen->visuals;
+ i < pScreen->numVisuals;
+ i++, pVisual++)
+ {
+ if (pVisual->vid == visual)
+ return pVisual;
+ }
+ return 0;
+}
+
Bool
PictureInitIndexedFormats (ScreenPtr pScreen)
{
@@ -390,13 +461,16 @@ PictureInitIndexedFormats (ScreenPtr pScreen)
{
if (format->type == PictTypeIndexed && !format->index.pColormap)
{
- if (format->index.pVisual->vid == pScreen->rootVisual)
+ if (format->index.vid == pScreen->rootVisual)
format->index.pColormap = (ColormapPtr) LookupIDByType(pScreen->defColormap,
RT_COLORMAP);
else
{
+ VisualPtr pVisual;
+
+ pVisual = PictureFindVisual (pScreen, format->index.vid);
if (CreateColormap (FakeClientID (0), pScreen,
- format->index.pVisual,
+ pVisual,
&format->index.pColormap, AllocNone,
0) != Success)
{
@@ -480,7 +554,7 @@ PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual)
{
if (type == PictTypeIndexed)
{
- if (format->index.pVisual == pVisual)
+ if (format->index.vid == pVisual->vid)
return format;
}
else
@@ -585,7 +659,8 @@ PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
}
if (formats[n].type == PictTypeIndexed)
{
- if ((formats[n].index.pVisual->class | DynamicClass) == PseudoColor)
+ VisualPtr pVisual = PictureFindVisual (pScreen, formats[n].index.vid);
+ if ((pVisual->class | DynamicClass) == PseudoColor)
type = PICT_TYPE_COLOR;
else
type = PICT_TYPE_GRAY;
@@ -1027,6 +1102,51 @@ SetPictureClipRects (PicturePtr pPicture,
}
int
+SetPictureClipRegion (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ RegionPtr pRegion)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ RegionPtr clientClip;
+ int result;
+ int type;
+
+ if (pRegion)
+ {
+ type = CT_REGION;
+ clientClip = REGION_CREATE (pScreen,
+ REGION_EXTENTS(pScreen, pRegion),
+ REGION_NUM_RECTS(pRegion));
+ if (!clientClip)
+ return BadAlloc;
+ if (!REGION_COPY (pSCreen, clientClip, pRegion))
+ {
+ REGION_DESTROY (pScreen, clientClip);
+ return BadAlloc;
+ }
+ }
+ else
+ {
+ type = CT_NONE;
+ clientClip = 0;
+ }
+
+ result =(*ps->ChangePictureClip) (pPicture, type,
+ (pointer) clientClip, 0);
+ if (result == Success)
+ {
+ pPicture->clipOrigin.x = xOrigin;
+ pPicture->clipOrigin.y = yOrigin;
+ pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ }
+ return result;
+}
+
+
+int
SetPictureTransform (PicturePtr pPicture,
PictTransform *transform)
{
@@ -1057,9 +1177,94 @@ SetPictureTransform (PicturePtr pPicture,
pPicture->transform = 0;
}
}
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+
return Success;
}
+void
+CopyPicture (PicturePtr pSrc,
+ Mask mask,
+ PicturePtr pDst)
+{
+ PictureScreenPtr ps = GetPictureScreen(pSrc->pDrawable->pScreen);
+ Mask origMask = mask;
+
+ pDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pDst->stateChanges |= mask;
+
+ while (mask) {
+ Mask bit = lowbit(mask);
+
+ switch (bit)
+ {
+ case CPRepeat:
+ pDst->repeat = pSrc->repeat;
+ break;
+ case CPAlphaMap:
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable->type == DRAWABLE_PIXMAP)
+ pSrc->alphaMap->refcnt++;
+ if (pDst->alphaMap)
+ FreePicture ((pointer) pDst->alphaMap, (XID) 0);
+ pDst->alphaMap = pSrc->alphaMap;
+ break;
+ case CPAlphaXOrigin:
+ pDst->alphaOrigin.x = pSrc->alphaOrigin.x;
+ break;
+ case CPAlphaYOrigin:
+ pDst->alphaOrigin.y = pSrc->alphaOrigin.y;
+ break;
+ case CPClipXOrigin:
+ pDst->clipOrigin.x = pSrc->clipOrigin.x;
+ break;
+ case CPClipYOrigin:
+ pDst->clipOrigin.y = pSrc->clipOrigin.y;
+ break;
+ case CPClipMask:
+ switch (pSrc->clientClipType) {
+ case CT_NONE:
+ (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+ break;
+ case CT_REGION:
+ if (!pSrc->clientClip) {
+ (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+ } else {
+ RegionPtr clientClip;
+ RegionPtr srcClientClip = (RegionPtr)pSrc->clientClip;
+
+ clientClip = REGION_CREATE(pSrc->pDrawable->pScreen,
+ REGION_EXTENTS(pSrc->pDrawable->pScreen, srcClientClip),
+ REGION_NUM_RECTS(srcClientClip));
+ (*ps->ChangePictureClip)(pDst, CT_REGION, clientClip, 0);
+ }
+ break;
+ default:
+ /* XXX: CT_PIXMAP unimplemented */
+ break;
+ }
+ break;
+ case CPGraphicsExposure:
+ pDst->graphicsExposures = pSrc->graphicsExposures;
+ break;
+ case CPPolyEdge:
+ pDst->polyEdge = pSrc->polyEdge;
+ break;
+ case CPPolyMode:
+ pDst->polyMode = pSrc->polyMode;
+ break;
+ case CPDither:
+ pDst->dither = pSrc->dither;
+ break;
+ case CPComponentAlpha:
+ pDst->componentAlpha = pSrc->componentAlpha;
+ break;
+ }
+ mask &= ~bit;
+ }
+
+ (*ps->ChangePicture)(pDst, origMask);
+}
+
static void
ValidateOnePicture (PicturePtr pPicture)
{
@@ -1263,7 +1468,18 @@ CompositeTriFan (CARD8 op,
(*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
}
-typedef xFixed_32_32 xFixed_48_16;
+void
+AddTraps (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntrap,
+ xTrap *traps)
+{
+ PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+ ValidatePicture (pPicture);
+ (*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps);
+}
#define MAX_FIXED_48_16 ((xFixed_48_16) 0x7fffffff)
#define MIN_FIXED_48_16 (-((xFixed_48_16) 1 << 31))
diff --git a/render/picture.h b/render/picture.h
index b4e3bd27c..4ed6e6ae0 100644
--- a/render/picture.h
+++ b/render/picture.h
@@ -160,6 +160,9 @@ extern int PictureCmapPolicy;
int PictureParseCmapPolicy (const char *name);
+extern int RenderErrBase;
+extern int RenderClientPrivateIndex;
+
/* Fixed point updates from Carl Worth, USC, Information Sciences Institute */
#ifdef WIN32
@@ -183,6 +186,11 @@ typedef long long int xFixed_32_32;
# endif
#endif
+typedef xFixed_32_32 xFixed_48_16;
+
+#define MAX_FIXED_48_16 ((xFixed_48_16) 0x7fffffff)
+#define MIN_FIXED_48_16 (-((xFixed_48_16) 1 << 31))
+
typedef CARD32 xFixed_1_31;
typedef CARD32 xFixed_1_16;
typedef INT32 xFixed_16_16;
diff --git a/render/picturestr.h b/render/picturestr.h
index ca766ce94..cdeb207a6 100644
--- a/render/picturestr.h
+++ b/render/picturestr.h
@@ -1,6 +1,5 @@
-/* $XdotOrg: xc/programs/Xserver/render/picturestr.h,v 1.1.4.2.2.2 2004/03/04 17:48:45 eich Exp $ */
/*
- * $XFree86: xc/programs/Xserver/render/picturestr.h,v 1.21 2002/11/06 22:45:36 keithp Exp $
+ * $Id$
*
* Copyright © 2000 SuSE, Inc.
*
@@ -39,7 +38,7 @@ typedef struct _DirectFormat {
} DirectFormatRec;
typedef struct _IndexFormat {
- VisualPtr pVisual;
+ VisualID vid;
ColormapPtr pColormap;
int nvalues;
xIndexValue *pValues;
@@ -103,11 +102,12 @@ typedef struct _Picture {
int filter_nparams;
} PictureRec;
+typedef Bool (*PictFilterValidateParamsProcPtr) (PicturePtr pPicture, int id,
+ xFixed *params, int nparams);
typedef struct {
- char *name;
- xFixed *params;
- int nparams;
- int id;
+ char *name;
+ int id;
+ PictFilterValidateParamsProcPtr ValidateParams;
} PictFilterRec, *PictFilterPtr;
#define PictFilterNearest 0
@@ -226,6 +226,18 @@ typedef void (*UpdateIndexedProcPtr) (ScreenPtr pScreen,
int ndef,
xColorItem *pdef);
+typedef void (*AddTrapsProcPtr) (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntrap,
+ xTrap *traps);
+
+typedef void (*AddTrianglesProcPtr) (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntri,
+ xTriangle *tris);
+
typedef struct _PictureScreen {
int totalPictureSize;
unsigned int *PicturePrivateSizes;
@@ -273,6 +285,11 @@ typedef struct _PictureScreen {
TriFanProcPtr TriFan;
RasterizeTrapezoidProcPtr RasterizeTrapezoid;
+
+ AddTrianglesProcPtr AddTriangles;
+
+ AddTrapsProcPtr AddTraps;
+
} PictureScreenRec, *PictureScreenPtr;
extern int PictureScreenPrivateIndex;
@@ -303,6 +320,15 @@ extern RESTYPE GlyphSetType;
} \
} \
+void
+ResetPicturePrivateIndex (void);
+
+int
+AllocatePicturePrivateIndex (void);
+
+Bool
+AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount);
+
Bool
PictureDestroyWindow (WindowPtr pWindow);
@@ -340,7 +366,9 @@ char *
PictureGetFilterName (int id);
int
-PictureAddFilter (ScreenPtr pScreen, char *filter, xFixed *params, int nparams);
+PictureAddFilter (ScreenPtr pScreen,
+ char *filter,
+ PictFilterValidateParamsProcPtr ValidateParams);
Bool
PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias);
@@ -396,9 +424,20 @@ SetPictureClipRects (PicturePtr pPicture,
xRectangle *rects);
int
+SetPictureClipRegion (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ RegionPtr pRegion);
+
+int
SetPictureTransform (PicturePtr pPicture,
PictTransform *transform);
-
+
+void
+CopyPicture (PicturePtr pSrc,
+ Mask mask,
+ PicturePtr pDst);
+
void
ValidatePicture(PicturePtr pPicture);
@@ -494,6 +533,13 @@ AnimCurInit (ScreenPtr pScreen);
int
AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor);
+void
+AddTraps (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntraps,
+ xTrap *traps);
+
#ifdef PANORAMIX
void PanoramiXRenderInit (void);
void PanoramiXRenderReset (void);
diff --git a/render/render.c b/render/render.c
index 542599adf..5a852ba68 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1,4 +1,4 @@
-/* $XdotOrg: xc/programs/Xserver/render/render.c,v 1.1.4.3.2.2 2004/03/04 17:48:45 eich Exp $ */
+/* $XdotOrg: xc/programs/Xserver/render/render.c,v 1.5 2004/08/06 23:42:10 keithp Exp $ */
/*
* $XFree86: xc/programs/Xserver/render/render.c,v 1.27tsi Exp $
*
@@ -78,6 +78,7 @@ static int ProcRenderSetPictureTransform (ClientPtr pClient);
static int ProcRenderQueryFilters (ClientPtr pClient);
static int ProcRenderSetPictureFilter (ClientPtr pClient);
static int ProcRenderCreateAnimCursor (ClientPtr pClient);
+static int ProcRenderAddTraps (ClientPtr pClient);
static int ProcRenderDispatch (ClientPtr pClient);
@@ -111,6 +112,7 @@ static int SProcRenderSetPictureTransform (ClientPtr pClient);
static int SProcRenderQueryFilters (ClientPtr pClient);
static int SProcRenderSetPictureFilter (ClientPtr pClient);
static int SProcRenderCreateAnimCursor (ClientPtr pClient);
+static int SProcRenderAddTraps (ClientPtr pClient);
static int SProcRenderDispatch (ClientPtr pClient);
@@ -147,6 +149,7 @@ int (*ProcRenderVector[RenderNumberRequests])(ClientPtr) = {
ProcRenderQueryFilters,
ProcRenderSetPictureFilter,
ProcRenderCreateAnimCursor,
+ ProcRenderAddTraps,
};
int (*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
@@ -182,6 +185,7 @@ int (*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
SProcRenderQueryFilters,
SProcRenderSetPictureFilter,
SProcRenderCreateAnimCursor,
+ SProcRenderAddTraps,
};
static void
@@ -243,6 +247,8 @@ RenderExtensionInit (void)
static void
RenderResetProc (ExtensionEntry *extEntry)
{
+ ResetPicturePrivateIndex();
+ ResetGlyphSetPrivateIndex();
}
static int
@@ -1508,7 +1514,7 @@ ProcRenderCreateCursor (ClientPtr client)
}
pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0,
client, &error);
- if (!pPicture);
+ if (!pPicture)
{
xfree (argbbits);
xfree (srcbits);
@@ -1811,6 +1817,27 @@ ProcRenderCreateAnimCursor (ClientPtr client)
}
static int
+ProcRenderAddTraps (ClientPtr client)
+{
+ int ntraps;
+ PicturePtr pPicture;
+ REQUEST(xRenderAddTrapsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
+ if (ntraps % sizeof (xTrap))
+ return BadLength;
+ ntraps /= sizeof (xTrap);
+ if (ntraps)
+ AddTraps (pPicture,
+ stuff->xOff, stuff->yOff,
+ ntraps, (xTrap *) &stuff[1]);
+ return client->noClientException;
+}
+
+static int
ProcRenderDispatch (ClientPtr client)
{
REQUEST(xReq);
@@ -2276,6 +2303,21 @@ SProcRenderCreateAnimCursor (ClientPtr client)
}
static int
+SProcRenderAddTraps (ClientPtr client)
+{
+ register int n;
+ REQUEST (xRenderAddTrapsReq);
+ REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ swaps(&stuff->xOff, n);
+ swaps(&stuff->yOff, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
SProcRenderDispatch (ClientPtr client)
{
REQUEST(xReq);
@@ -2920,6 +2962,44 @@ PanoramiXRenderColorTriangles(ClientPtr client)
#endif
+static int
+PanoramiXRenderAddTraps (ClientPtr client)
+{
+ PanoramiXRes *picture;
+ int result = Success, j;
+ REQUEST(xRenderAddTrapsReq);
+ char *extra;
+ int extra_len;
+ INT16 x_off, y_off;
+
+ REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
+ VERIFY_XIN_PICTURE (picture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len)))
+ {
+ memcpy (extra, stuff + 1, extra_len);
+ x_off = stuff->xOff;
+ y_off = stuff->yOff;
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ stuff->picture = picture->info[j].id;
+
+ if (picture->u.pict.root)
+ {
+ stuff->xOff = x_off + panoramiXdataPtr[j].x;
+ stuff->yOff = y_off + panoramiXdataPtr[j].y;
+ }
+ result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
+ if(result != Success) break;
+ }
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
void
PanoramiXRenderInit (void)
{
@@ -2947,6 +3027,7 @@ PanoramiXRenderInit (void)
ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
+ ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
}
void
diff --git a/render/renderedge.c b/render/renderedge.c
new file mode 100644
index 000000000..b84eec14d
--- /dev/null
+++ b/render/renderedge.c
@@ -0,0 +1,197 @@
+/*
+ * $Id$
+ *
+ * Copyright © 2004 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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 CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "renderedge.h"
+
+/*
+ * Compute the smallest value no less than y which is on a
+ * grid row
+ */
+
+xFixed
+RenderSampleCeilY (xFixed y, int n)
+{
+ xFixed f = xFixedFrac(y);
+ xFixed i = xFixedFloor(y);
+
+ f = ((f + Y_FRAC_FIRST(n)) / STEP_Y_SMALL(n)) * STEP_Y_SMALL(n) + Y_FRAC_FIRST(n);
+ if (f > Y_FRAC_LAST(n))
+ {
+ f = Y_FRAC_FIRST(n);
+ i += xFixed1;
+ }
+ return (i | f);
+}
+
+#define _div(a,b) ((a) >= 0 ? (a) / (b) : -((-(a) + (b) - 1) / (b)))
+
+/*
+ * Compute the largest value no greater than y which is on a
+ * grid row
+ */
+xFixed
+RenderSampleFloorY (xFixed y, int n)
+{
+ xFixed f = xFixedFrac(y);
+ xFixed i = xFixedFloor (y);
+
+ f = _div(f - Y_FRAC_FIRST(n), STEP_Y_SMALL(n)) * STEP_Y_SMALL(n) + Y_FRAC_FIRST(n);
+ if (f < Y_FRAC_FIRST(n))
+ {
+ f = Y_FRAC_LAST(n);
+ i -= xFixed1;
+ }
+ return (i | f);
+}
+
+/*
+ * Step an edge by any amount (including negative values)
+ */
+void
+RenderEdgeStep (RenderEdge *e, int n)
+{
+ xFixed_48_16 ne;
+
+ e->x += n * e->stepx;
+
+ ne = e->e + n * (xFixed_48_16) e->dx;
+
+ if (n >= 0)
+ {
+ if (ne > 0)
+ {
+ int nx = (ne + e->dy - 1) / e->dy;
+ e->e = ne - nx * (xFixed_48_16) e->dy;
+ e->x += nx * e->signdx;
+ }
+ }
+ else
+ {
+ if (ne <= -e->dy)
+ {
+ int nx = (-ne) / e->dy;
+ e->e = ne + nx * (xFixed_48_16) e->dy;
+ e->x -= nx * e->signdx;
+ }
+ }
+}
+
+/*
+ * A private routine to initialize the multi-step
+ * elements of an edge structure
+ */
+static void
+_RenderEdgeMultiInit (RenderEdge *e, int n, xFixed *stepx_p, xFixed *dx_p)
+{
+ xFixed stepx;
+ xFixed_48_16 ne;
+
+ ne = n * (xFixed_48_16) e->dx;
+ stepx = n * e->stepx;
+ if (ne > 0)
+ {
+ int nx = ne / e->dy;
+ ne -= nx * e->dy;
+ stepx += nx * e->signdx;
+ }
+ *dx_p = ne;
+ *stepx_p = stepx;
+}
+
+/*
+ * Initialize one edge structure given the line endpoints and a
+ * starting y value
+ */
+void
+RenderEdgeInit (RenderEdge *e,
+ int n,
+ xFixed y_start,
+ xFixed x_top,
+ xFixed y_top,
+ xFixed x_bot,
+ xFixed y_bot)
+{
+ xFixed dx, dy;
+
+ e->x = x_top;
+ e->e = 0;
+ dx = x_bot - x_top;
+ dy = y_bot - y_top;
+ e->dy = dy;
+ if (dy)
+ {
+ if (dx >= 0)
+ {
+ e->signdx = 1;
+ e->stepx = dx / dy;
+ e->dx = dx % dy;
+ e->e = -dy;
+ }
+ else
+ {
+ e->signdx = -1;
+ e->stepx = -(-dx / dy);
+ e->dx = -dx % dy;
+ e->e = 0;
+ }
+
+ _RenderEdgeMultiInit (e, STEP_Y_SMALL(n), &e->stepx_small, &e->dx_small);
+ _RenderEdgeMultiInit (e, STEP_Y_BIG(n), &e->stepx_big, &e->dx_big);
+ }
+ RenderEdgeStep (e, y_start - y_top);
+}
+
+/*
+ * Initialize one edge structure given a line, starting y value
+ * and a pixel offset for the line
+ */
+void
+RenderLineFixedEdgeInit (RenderEdge *e,
+ int n,
+ xFixed y,
+ xLineFixed *line,
+ int x_off,
+ int y_off)
+{
+ xFixed x_off_fixed = IntToxFixed(x_off);
+ xFixed y_off_fixed = IntToxFixed(y_off);
+ xPointFixed *top, *bot;
+
+ if (line->p1.y <= line->p2.y)
+ {
+ top = &line->p1;
+ bot = &line->p2;
+ }
+ else
+ {
+ top = &line->p2;
+ bot = &line->p1;
+ }
+ RenderEdgeInit (e, n, y,
+ top->x + x_off_fixed,
+ top->y + y_off_fixed,
+ bot->x + x_off_fixed,
+ bot->y + y_off_fixed);
+}
+
diff --git a/render/renderedge.h b/render/renderedge.h
new file mode 100644
index 000000000..d621d9dcf
--- /dev/null
+++ b/render/renderedge.h
@@ -0,0 +1,120 @@
+/*
+ * $Id$
+ *
+ * Copyright © 2004 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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 CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _RENDEREDGE_H_
+#define _RENDEREDGE_H_
+
+#include "picturestr.h"
+
+#define MAX_ALPHA(n) ((1 << (n)) - 1)
+#define N_Y_FRAC(n) ((n) == 1 ? 1 : (1 << ((n)/2)) - 1)
+#define N_X_FRAC(n) ((1 << ((n)/2)) + 1)
+
+#define STEP_Y_SMALL(n) (xFixed1 / N_Y_FRAC(n))
+#define STEP_Y_BIG(n) (xFixed1 - (N_Y_FRAC(n) - 1) * STEP_Y_SMALL(n))
+
+#define Y_FRAC_FIRST(n) (STEP_Y_SMALL(n) / 2)
+#define Y_FRAC_LAST(n) (Y_FRAC_FIRST(n) + (N_Y_FRAC(n) - 1) * STEP_Y_SMALL(n))
+
+#define STEP_X_SMALL(n) (xFixed1 / N_X_FRAC(n))
+#define STEP_X_BIG(n) (xFixed1 - (N_X_FRAC(n) - 1) * STEP_X_SMALL(n))
+
+#define X_FRAC_FIRST(n) (STEP_X_SMALL(n) / 2)
+#define X_FRAC_LAST(n) (X_FRAC_FIRST(n) + (N_X_FRAC(n) - 1) * STEP_X_SMALL(n))
+
+#define RenderSamplesX(x,n) ((n) == 1 ? 0 : (xFixedFrac (x) + X_FRAC_FIRST(n)) / STEP_X_SMALL(n))
+
+/*
+ * An edge structure. This represents a single polygon edge
+ * and can be quickly stepped across small or large gaps in the
+ * sample grid
+ */
+
+typedef struct {
+ xFixed x;
+ xFixed e;
+ xFixed stepx;
+ xFixed signdx;
+ xFixed dy;
+ xFixed dx;
+
+ xFixed stepx_small;
+ xFixed stepx_big;
+ xFixed dx_small;
+ xFixed dx_big;
+} RenderEdge;
+
+/*
+ * Step across a small sample grid gap
+ */
+#define RenderEdgeStepSmall(edge) { \
+ edge->x += edge->stepx_small; \
+ edge->e += edge->dx_small; \
+ if (edge->e > 0) \
+ { \
+ edge->e -= edge->dy; \
+ edge->x += edge->signdx; \
+ } \
+}
+
+/*
+ * Step across a large sample grid gap
+ */
+#define RenderEdgeStepBig(edge) { \
+ edge->x += edge->stepx_big; \
+ edge->e += edge->dx_big; \
+ if (edge->e > 0) \
+ { \
+ edge->e -= edge->dy; \
+ edge->x += edge->signdx; \
+ } \
+}
+
+xFixed
+RenderSampleCeilY (xFixed y, int bpp);
+
+xFixed
+RenderSampleFloorY (xFixed y, int bpp);
+
+void
+RenderEdgeStep (RenderEdge *e, int n);
+
+void
+RenderEdgeInit (RenderEdge *e,
+ int bpp,
+ xFixed y_start,
+ xFixed x_top,
+ xFixed y_top,
+ xFixed x_bot,
+ xFixed y_bot);
+
+void
+RenderLineFixedEdgeInit (RenderEdge *e,
+ int bpp,
+ xFixed y,
+ xLineFixed *line,
+ int x_off,
+ int y_off);
+
+#endif /* _RENDEREDGE_H_ */