diff options
Diffstat (limited to 'render')
-rw-r--r-- | render/filter.c | 48 | ||||
-rw-r--r-- | render/glyph.c | 60 | ||||
-rw-r--r-- | render/glyphstr.h | 21 | ||||
-rw-r--r-- | render/mipict.c | 161 | ||||
-rw-r--r-- | render/mipict.h | 3 | ||||
-rw-r--r-- | render/mirect.c | 11 | ||||
-rw-r--r-- | render/mitrap.c | 70 | ||||
-rw-r--r-- | render/mitri.c | 274 | ||||
-rw-r--r-- | render/picture.c | 228 | ||||
-rw-r--r-- | render/picture.h | 8 | ||||
-rw-r--r-- | render/picturestr.h | 64 | ||||
-rw-r--r-- | render/render.c | 85 | ||||
-rw-r--r-- | render/renderedge.c | 197 | ||||
-rw-r--r-- | render/renderedge.h | 120 |
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_ */ |